re PR c++/58583 ([c++11] ICE with invalid non-static data member initialization in...
authorNathan Sidwell <nathan@acm.org>
Tue, 16 Jun 2015 01:59:55 +0000 (01:59 +0000)
committerNathan Sidwell <nathan@gcc.gnu.org>
Tue, 16 Jun 2015 01:59:55 +0000 (01:59 +0000)
cp/
PR c++/58583
* cp-tree.h (DECL_INSTANTIATING_NSDMI_P): New.
* init.c (get_nsdmi): Check for DEFAULT_ARG in template case and
protect it from recursive instantiation.

testsuite/
PR c++/58583
* g++.dg/cpp0x/nsdmi-template14.C: New test.

From-SVN: r224502

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

index cf311c731785da8094ece51ab76de2326b6c4e63..15766f4d7267bdaacfd95813a4c9aa29d570536f 100644 (file)
@@ -1,3 +1,10 @@
+2015-06-15  Nathan Sidwell  <nathan@acm.org>
+
+       PR c++/58583
+       * cp-tree.h (DECL_INSTANTIATING_NSDMI_P): New.
+       * init.c (get_nsdmi): Check for DEFAULT_ARG in template case and
+       protect it from recursive instantiation.
+
 2015-06-15  Paolo Carlini  <paolo.carlini@oracle.com>
 
        PR c++/51048
index 1eac6367d25083b55464c98d4ba919a00e1a3f6e..303a432760a023f94c5625fdaab104a199a927ec 100644 (file)
@@ -156,6 +156,7 @@ c-common.h, not after.
    2: DECL_THIS_EXTERN (in VAR_DECL or FUNCTION_DECL).
       DECL_IMPLICIT_TYPEDEF_P (in a TYPE_DECL)
       TEMPLATE_DECL_COMPLEX_ALIAS_P (in TEMPLATE_DECL)
+      DECL_INSTANTIATING_NSDMI_P (in a FIELD_DECL)
    3: DECL_IN_AGGR_P.
    4: DECL_C_BIT_FIELD (in a FIELD_DECL)
       DECL_ANON_UNION_VAR_P (in a VAR_DECL)
@@ -3785,6 +3786,11 @@ more_aggr_init_expr_args_p (const aggr_init_expr_arg_iterator *iter)
 #define DECL_ARRAY_PARAMETER_P(NODE) \
   DECL_LANG_FLAG_1 (PARM_DECL_CHECK (NODE))
 
+/* Nonzero for a FIELD_DECL who's NSMDI is currently being
+   instantiated.  */
+#define DECL_INSTANTIATING_NSDMI_P(NODE) \
+  DECL_LANG_FLAG_2 (FIELD_DECL_CHECK (NODE))
+
 /* Nonzero for FIELD_DECL node means that this field is a base class
    of the parent object, as opposed to a member field.  */
 #define DECL_FIELD_IS_BASE(NODE) \
index ef4f0ff65d37b6ad084be73f17400ef1526ac0ca..aa964b9e8e3ac2cf1374fa6a6fbbd2a0a4cccbe9 100644 (file)
@@ -541,6 +541,7 @@ get_nsdmi (tree member, bool in_ctor)
   tree init;
   tree save_ccp = current_class_ptr;
   tree save_ccr = current_class_ref;
+  
   if (!in_ctor)
     {
       /* Use a PLACEHOLDER_EXPR when we don't have a 'this' parameter to
@@ -548,22 +549,40 @@ get_nsdmi (tree member, bool in_ctor)
       current_class_ref = build0 (PLACEHOLDER_EXPR, DECL_CONTEXT (member));
       current_class_ptr = build_address (current_class_ref);
     }
+
   if (DECL_LANG_SPECIFIC (member) && DECL_TEMPLATE_INFO (member))
     {
-      /* Do deferred instantiation of the NSDMI.  */
-      init = (tsubst_copy_and_build
-             (DECL_INITIAL (DECL_TI_TEMPLATE (member)),
-              DECL_TI_ARGS (member),
-              tf_warning_or_error, member, /*function_p=*/false,
-              /*integral_constant_expression_p=*/false));
-
-      init = digest_nsdmi_init (member, init);
+      init = DECL_INITIAL (DECL_TI_TEMPLATE (member));
+      if (TREE_CODE (init) == DEFAULT_ARG)
+       goto unparsed;
+
+      /* Check recursive instantiation.  */
+      if (DECL_INSTANTIATING_NSDMI_P (member))
+       {
+         error ("recursive instantiation of non-static data member "
+                "initializer for %qD", member);
+         init = error_mark_node;
+       }
+      else
+       {
+         DECL_INSTANTIATING_NSDMI_P (member) = 1;
+         
+         /* Do deferred instantiation of the NSDMI.  */
+         init = (tsubst_copy_and_build
+                 (init, DECL_TI_ARGS (member),
+                  tf_warning_or_error, member, /*function_p=*/false,
+                  /*integral_constant_expression_p=*/false));
+         init = digest_nsdmi_init (member, init);
+         
+         DECL_INSTANTIATING_NSDMI_P (member) = 0;
+       }
     }
   else
     {
       init = DECL_INITIAL (member);
       if (init && TREE_CODE (init) == DEFAULT_ARG)
        {
+       unparsed:
          error ("constructor required before non-static data member "
                 "for %qD has been parsed", member);
          DECL_INITIAL (member) = error_mark_node;
index 68356fc31e3c1ac96813bef688f2ba5e232104d3..57c33d6be5ad88cba56115a1f68c83c6a453e7e4 100644 (file)
@@ -1,3 +1,8 @@
+2015-06-15  Nathan Sidwell  <nathan@acm.org>
+
+       PR c++/58583
+       * g++.dg/cpp0x/nsdmi-template14.C: New test.
+
 2015-06-15  Paolo Carlini  <paolo.carlini@oracle.com>
 
        PR c++/51048
diff --git a/gcc/testsuite/g++.dg/cpp0x/nsdmi-template14.C b/gcc/testsuite/g++.dg/cpp0x/nsdmi-template14.C
new file mode 100644 (file)
index 0000000..9cb01f1
--- /dev/null
@@ -0,0 +1,22 @@
+// PR c++/58583
+// { dg-do compile { target c++11 } }
+
+template<int> struct A // { dg-error "has been parsed" }
+{
+  int i = (A<0>(), 0); // { dg-error "has been parsed" }
+};
+
+template<int N> struct B
+{
+  B* p = new B<N>;
+};
+
+B<1> x; // { dg-error "recursive instantiation of non-static data" }
+
+struct C
+{
+  template<int N> struct D
+  {
+    D* p = new D<0>;
+  };
+};