PR c++/50614
authorjason <jason@138bc75d-0d04-0410-961f-82ee72b054a4>
Thu, 13 Oct 2011 21:23:47 +0000 (21:23 +0000)
committerjason <jason@138bc75d-0d04-0410-961f-82ee72b054a4>
Thu, 13 Oct 2011 21:23:47 +0000 (21:23 +0000)
* cp-tree.h (VAR_TEMPL_TYPE_FIELD_OR_FUNCTION_DECL_CHECK): New.
(DECL_TEMPLATE_INFO): Use it.
* pt.c (tsubst_decl) [FIELD_DECL]: Set DECL_TEMPLATE_INFO
if the decl has an NSDMI.
* init.c (perform_member_init): Use it.

git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@179945 138bc75d-0d04-0410-961f-82ee72b054a4

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

index 0322103..9a214b5 100644 (file)
@@ -1,5 +1,12 @@
 2011-10-13  Jason Merrill  <jason@redhat.com>
 
+       PR c++/50614
+       * cp-tree.h (VAR_TEMPL_TYPE_FIELD_OR_FUNCTION_DECL_CHECK): New.
+       (DECL_TEMPLATE_INFO): Use it.
+       * pt.c (tsubst_decl) [FIELD_DECL]: Set DECL_TEMPLATE_INFO
+       if the decl has an NSDMI.
+       * init.c (perform_member_init): Use it.
+
        PR c++/50437
        * cp-tree.h (struct tree_lambda_expr): Add closure field.
        (LAMBDA_EXPR_CLOSURE): New.
index bae6071..88f7fbd 100644 (file)
@@ -201,6 +201,9 @@ c-common.h, not after.
 #define VAR_TEMPL_TYPE_OR_FUNCTION_DECL_CHECK(NODE) \
   TREE_CHECK4(NODE,VAR_DECL,FUNCTION_DECL,TYPE_DECL,TEMPLATE_DECL)
 
+#define VAR_TEMPL_TYPE_FIELD_OR_FUNCTION_DECL_CHECK(NODE) \
+  TREE_CHECK5(NODE,VAR_DECL,FIELD_DECL,FUNCTION_DECL,TYPE_DECL,TEMPLATE_DECL)
+
 #define BOUND_TEMPLATE_TEMPLATE_PARM_TYPE_CHECK(NODE) \
   TREE_CHECK(NODE,BOUND_TEMPLATE_TEMPLATE_PARM)
 
@@ -2556,7 +2559,7 @@ extern void decl_shadowed_for_var_insert (tree, tree);
    global function f.  In this case, DECL_TEMPLATE_INFO for S<int>::f
    will be non-NULL, but DECL_USE_TEMPLATE will be zero.  */
 #define DECL_TEMPLATE_INFO(NODE) \
-  (DECL_LANG_SPECIFIC (VAR_TEMPL_TYPE_OR_FUNCTION_DECL_CHECK (NODE)) \
+  (DECL_LANG_SPECIFIC (VAR_TEMPL_TYPE_FIELD_OR_FUNCTION_DECL_CHECK (NODE)) \
    ->u.min.template_info)
 
 /* For a VAR_DECL, indicates that the variable is actually a
@@ -2701,7 +2704,10 @@ extern void decl_shadowed_for_var_insert (tree, tree);
      template <class T> struct S { friend void f<int>(int, double); }
 
    the DECL_TI_TEMPLATE will be an IDENTIFIER_NODE for `f' and the
-   DECL_TI_ARGS will be {int}.  */
+   DECL_TI_ARGS will be {int}.
+
+   For a FIELD_DECL with a non-static data member initializer, this value
+   is the FIELD_DECL it was instantiated from.  */
 #define DECL_TI_TEMPLATE(NODE)      TI_TEMPLATE (DECL_TEMPLATE_INFO (NODE))
 
 /* The template arguments used to obtain this decl from the most
index a21e566..4561979 100644 (file)
@@ -497,11 +497,11 @@ perform_member_init (tree member, tree init)
      mem-initializer for this field.  */
   if (init == NULL_TREE)
     {
-      if (CLASSTYPE_TEMPLATE_INSTANTIATION (DECL_CONTEXT (member)))
+      if (DECL_LANG_SPECIFIC (member) && DECL_TEMPLATE_INFO (member))
        /* Do deferred instantiation of the NSDMI.  */
        init = (tsubst_copy_and_build
-               (DECL_INITIAL (member),
-                CLASSTYPE_TI_ARGS (DECL_CONTEXT (member)),
+               (DECL_INITIAL (DECL_TI_TEMPLATE (member)),
+                DECL_TI_ARGS (member),
                 tf_warning_or_error, member, /*function_p=*/false,
                 /*integral_constant_expression_p=*/false));
       else
index 880f3d1..1632c01 100644 (file)
@@ -10269,6 +10269,16 @@ tsubst_decl (tree t, tree args, tsubst_flags_t complain)
            = tsubst_expr (DECL_INITIAL (t), args,
                           complain, in_decl,
                           /*integral_constant_expression_p=*/true);
+       else if (DECL_INITIAL (t))
+         {
+           /* Set up DECL_TEMPLATE_INFO so that we can get at the
+              NSDMI in perform_member_init.  Still set DECL_INITIAL
+              to error_mark_node so that we know there is one.  */
+           DECL_INITIAL (r) = error_mark_node;
+           gcc_assert (DECL_LANG_SPECIFIC (r) == NULL);
+           retrofit_lang_decl (r);
+           DECL_TEMPLATE_INFO (r) = build_template_info (t, args);
+         }
        /* We don't have to set DECL_CONTEXT here; it is set by
           finish_member_declaration.  */
        DECL_CHAIN (r) = NULL_TREE;
index 3c15036..9c29b70 100644 (file)
@@ -1,5 +1,8 @@
 2011-10-13  Jason Merrill  <jason@redhat.com>
 
+       PR c++/50614
+       * g++.dg/cpp0x/nsdmi-template2.C: New.
+
        PR c++/50437
        * g++.dg/cpp0x/lambda/lambda-auto1.C: New.
 
diff --git a/gcc/testsuite/g++.dg/cpp0x/nsdmi-template2.C b/gcc/testsuite/g++.dg/cpp0x/nsdmi-template2.C
new file mode 100644 (file)
index 0000000..27b0aa5
--- /dev/null
@@ -0,0 +1,14 @@
+// PR c++/50614
+// { dg-options "-std=c++0x -fcompare-debug" }
+
+struct A
+{
+  int f ();
+};
+
+template <int> struct B : A
+{
+  int i = this->f ();
+};
+
+B<0> b;