2013-09-24 David Bartley <[email protected]>
PR c++/58408
* gcc/cp/class.c: Don't require class to be constructed if it
has a trivial default constructor.
* gcc/testsuite/g++.dg/tls/init-1.C: New testcase.
---
gcc/cp/class.c | 14 +++++++++-----
gcc/testsuite/g++.dg/tls/init-1.C | 11 +++++++++++
2 files changed, 20 insertions(+), 5 deletions(-)
diff --git a/gcc/cp/class.c b/gcc/cp/class.c
index 9e0229f..7523fac 100644
--- a/gcc/cp/class.c
+++ b/gcc/cp/class.c
@@ -5383,6 +5383,7 @@ check_bases_and_members (tree t)
tree access_decls;
bool saved_complex_asn_ref;
bool saved_nontrivial_dtor;
+ bool trivial_default_ctor;
tree fn;
/* By default, we use const reference arguments and generate default
@@ -5426,12 +5427,15 @@ check_bases_and_members (tree t)
TYPE_HAS_COMPLEX_COPY_CTOR (t) |= TYPE_CONTAINS_VPTR_P (t);
TYPE_HAS_COMPLEX_MOVE_CTOR (t) |= TYPE_CONTAINS_VPTR_P (t);
/* We need to call a constructor for this class if it has a
- user-provided constructor, or if the default constructor is going
- to initialize the vptr. (This is not an if-and-only-if;
- TYPE_NEEDS_CONSTRUCTING is set elsewhere if bases or members
- themselves need constructing.) */
+ user-provided constructor and no trivial default constructor
+ or if the default constructor is going to initialize the vptr.
+ (This is not an if-and-only-if; TYPE_NEEDS_CONSTRUCTING is set
+ elsewhere if bases or members themselves need constructing.) */
+ trivial_default_ctor =
+ TYPE_HAS_DEFAULT_CONSTRUCTOR (t) && !TYPE_HAS_COMPLEX_DFLT (t);
TYPE_NEEDS_CONSTRUCTING (t)
- |= (type_has_user_provided_constructor (t) || TYPE_CONTAINS_VPTR_P (t));
+ |= ((type_has_user_provided_constructor (t) && !trivial_default_ctor)
+ || TYPE_CONTAINS_VPTR_P (t));
/* [dcl.init.aggr]
An aggregate is an array or a class with no user-provided
diff --git a/gcc/testsuite/g++.dg/tls/init-1.C
b/gcc/testsuite/g++.dg/tls/init-1.C
index 9786712..c24d874 100644
--- a/gcc/testsuite/g++.dg/tls/init-1.C
+++ b/gcc/testsuite/g++.dg/tls/init-1.C
@@ -1,5 +1,6 @@
/* Valid initializations. */
/* { dg-require-effective-target tls } */
+/* { dg-options "-std=c++11" } */
__thread int i = 42;
@@ -12,3 +13,13 @@ int *q = &i;
/* Valid because "const int k" is an integral constant expression in C++. */
__thread const int k = 42;
__thread const int l = k;
+
+/* Defined copy constructor with explicitly-default constructor.*/
+class Test {
+ public:
+ Test() = default;
+ Test(int) {
+ }
+ int t;
+};
+__thread Test t;
--
1.8.4