init.c (perform_member_init): Instantiate NSDMI here.
authorJason Merrill <jason@redhat.com>
Sun, 25 Sep 2011 02:26:08 +0000 (22:26 -0400)
committerJason Merrill <jason@gcc.gnu.org>
Sun, 25 Sep 2011 02:26:08 +0000 (22:26 -0400)
* init.c (perform_member_init): Instantiate NSDMI here.
* pt.c (tsubst_decl) [FIELD_DECL]: Not here.

From-SVN: r179157

gcc/cp/ChangeLog
gcc/cp/init.c
gcc/cp/pt.c
gcc/testsuite/ChangeLog
gcc/testsuite/g++.dg/cpp0x/nsdmi-defer3.C [new file with mode: 0644]

index f1496b6..fc5436a 100644 (file)
@@ -1,5 +1,8 @@
 2011-09-24  Jason Merrill  <jason@redhat.com>
 
+       * init.c (perform_member_init): Instantiate NSDMI here.
+       * pt.c (tsubst_decl) [FIELD_DECL]: Not here.
+
        Handle deferred parsing of NSDMIs.
        * parser.h (cp_unparsed_functions_entry): Add nsdmis field.
        * parser.c (unparsed_nsdmis, cp_parser_save_nsdmi): New.
index f5904d5..f246286 100644 (file)
@@ -496,7 +496,17 @@ perform_member_init (tree member, tree init)
   /* Use the non-static data member initializer if there was no
      mem-initializer for this field.  */
   if (init == NULL_TREE)
-    init = break_out_target_exprs (DECL_INITIAL (member));
+    {
+      if (CLASSTYPE_TEMPLATE_INSTANTIATION (DECL_CONTEXT (member)))
+       /* Do deferred instantiation of the NSDMI.  */
+       init = (tsubst_copy_and_build
+               (DECL_INITIAL (member),
+                CLASSTYPE_TI_ARGS (DECL_CONTEXT (member)),
+                tf_warning_or_error, member, /*function_p=*/false,
+                /*integral_constant_expression_p=*/false));
+      else
+       init = break_out_target_exprs (DECL_INITIAL (member));
+    }
 
   /* Effective C++ rule 12 requires that all data members be
      initialized.  */
index af5ca5c..ebadebf 100644 (file)
@@ -10264,11 +10264,14 @@ tsubst_decl (tree t, tree args, tsubst_flags_t complain)
        TREE_TYPE (r) = type;
        cp_apply_type_quals_to_decl (cp_type_quals (type), r);
 
-       /* DECL_INITIAL gives the number of bits in a bit-field.  */
-       DECL_INITIAL (r)
-         = tsubst_expr (DECL_INITIAL (t), args,
-                        complain, in_decl,
-                        /*integral_constant_expression_p=*/true);
+       if (DECL_C_BIT_FIELD (r))
+         /* For bit-fields, DECL_INITIAL gives the number of bits.  For
+            non-bit-fields DECL_INITIAL is a non-static data member
+            initializer, which gets deferred instantiation.  */
+         DECL_INITIAL (r)
+           = tsubst_expr (DECL_INITIAL (t), args,
+                          complain, in_decl,
+                          /*integral_constant_expression_p=*/true);
        /* We don't have to set DECL_CONTEXT here; it is set by
           finish_member_declaration.  */
        DECL_CHAIN (r) = NULL_TREE;
index 1e51669..a8b10cd 100644 (file)
@@ -1,5 +1,7 @@
 2011-09-24  Jason Merrill  <jason@redhat.com>
 
+       * g++.dg/cpp0x/nsdmi-defer3.C: New.
+
        * g++.dg/cpp0x/nsdmi-defer1.C: New.
        * g++.dg/cpp0x/nsdmi-defer2.C: New.
 
diff --git a/gcc/testsuite/g++.dg/cpp0x/nsdmi-defer3.C b/gcc/testsuite/g++.dg/cpp0x/nsdmi-defer3.C
new file mode 100644 (file)
index 0000000..2777fb5
--- /dev/null
@@ -0,0 +1,19 @@
+// Do NSDMI get deferred instantiation?
+// { dg-options -std=c++0x }
+
+template <class T>
+struct A
+{
+  T t = T(42);
+  constexpr A() { }
+  A(T t): t(t) { }
+};
+
+struct B { };
+
+#define SA(X) static_assert(X,#X)
+
+constexpr A<int> a1;
+SA(a1.t == 42);
+
+A<B> a2 {B()};