re PR c++/34758 (Bad diagnostic for circular dependency in constructor default argument)
authorJason Merrill <jason@gcc.gnu.org>
Tue, 15 Mar 2011 18:27:09 +0000 (14:27 -0400)
committerJason Merrill <jason@gcc.gnu.org>
Tue, 15 Mar 2011 18:27:09 +0000 (14:27 -0400)
PR c++/34758
* call.c (convert_default_arg): Use DECL_ORIGIN of fn.  Check for
recursion first.
(push_defarg_context, pop_defarg_context): New.
* parser.c (cp_parser_late_parsing_default_args): Use them.
* cp-tree.h: Declare them.

From-SVN: r171009

gcc/cp/ChangeLog
gcc/cp/call.c
gcc/cp/cp-tree.h
gcc/cp/parser.c
gcc/testsuite/ChangeLog
gcc/testsuite/g++.dg/parse/pr34758.C [new file with mode: 0644]

index bebb1fcee5d463d110a13a1657bf2f3b895008ab..34a3a5347881eceeb853544507b4787ec99fa18d 100644 (file)
@@ -1,3 +1,12 @@
+2011-03-15  Jason Merrill  <jason@redhat.com>
+
+       PR c++/34758
+       * call.c (convert_default_arg): Use DECL_ORIGIN of fn.  Check for
+       recursion first.
+       (push_defarg_context, pop_defarg_context): New.
+       * parser.c (cp_parser_late_parsing_default_args): Use them.
+       * cp-tree.h: Declare them.
+
 2011-03-11  Dodji Seketeli  <dodji@redhat.com>
 
        * call.c (add_builtin_candidate)<case INDIRECT_REF>: The type of
index 5953e3524ccb1e4ba720bfb547b2d3bbaaf2858e..499ed03f3f9e0ceb711e9a71c5e95608d32c86db 100644 (file)
@@ -5746,10 +5746,17 @@ cxx_type_promotes_to (tree type)
 }
 
 /* ARG is a default argument expression being passed to a parameter of
-   the indicated TYPE, which is a parameter to FN.  Do any required
-   conversions.  Return the converted value.  */
+   the indicated TYPE, which is a parameter to FN.  PARMNUM is the
+   zero-based argument number.  Do any required conversions.  Return
+   the converted value.  */
 
 static GTY(()) VEC(tree,gc) *default_arg_context;
+void
+push_defarg_context (tree fn)
+{ VEC_safe_push (tree, gc, default_arg_context, fn); }
+void
+pop_defarg_context (void)
+{ VEC_pop (tree, default_arg_context); }
 
 tree
 convert_default_arg (tree type, tree arg, tree fn, int parmnum)
@@ -5757,15 +5764,8 @@ convert_default_arg (tree type, tree arg, tree fn, int parmnum)
   int i;
   tree t;
 
-  /* If the ARG is an unparsed default argument expression, the
-     conversion cannot be performed.  */
-  if (TREE_CODE (arg) == DEFAULT_ARG)
-    {
-      error ("the default argument for parameter %d of %qD has "
-            "not yet been parsed",
-            parmnum, fn);
-      return error_mark_node;
-    }
+  /* See through clones.  */
+  fn = DECL_ORIGIN (fn);
 
   /* Detect recursion.  */
   FOR_EACH_VEC_ELT (tree, default_arg_context, i, t)
@@ -5774,7 +5774,17 @@ convert_default_arg (tree type, tree arg, tree fn, int parmnum)
        error ("recursive evaluation of default argument for %q#D", fn);
        return error_mark_node;
       }
-  VEC_safe_push (tree, gc, default_arg_context, fn);
+
+  /* If the ARG is an unparsed default argument expression, the
+     conversion cannot be performed.  */
+  if (TREE_CODE (arg) == DEFAULT_ARG)
+    {
+      error ("call to %qD uses the default argument for parameter %P, which "
+            "is not yet defined", fn, parmnum);
+      return error_mark_node;
+    }
+
+  push_defarg_context (fn);
 
   if (fn && DECL_TEMPLATE_INFO (fn))
     arg = tsubst_default_argument (fn, type, arg);
@@ -5814,7 +5824,7 @@ convert_default_arg (tree type, tree arg, tree fn, int parmnum)
     }
   pop_deferring_access_checks();
 
-  VEC_pop (tree, default_arg_context);
+  pop_defarg_context ();
 
   return arg;
 }
index 4b49046105f4f4323523b4f16a1e7703b77b7724..6ef6e6eb3ec77e612b8c4bef4882da9bb6ba48c6 100644 (file)
@@ -4638,6 +4638,8 @@ extern bool can_convert                           (tree, tree);
 extern bool can_convert_arg                    (tree, tree, tree, int);
 extern bool can_convert_arg_bad                        (tree, tree, tree, int);
 extern bool enforce_access                     (tree, tree, tree);
+extern void push_defarg_context                        (tree);
+extern void pop_defarg_context                 (void);
 extern tree convert_default_arg                        (tree, tree, tree, int);
 extern tree convert_arg_to_ellipsis            (tree);
 extern tree build_x_va_arg                     (tree, tree);
index 4260f6d135a9f3eb5c3c0f2b15471cab4dc5bbd2..a9fd2010b253495aae40e551ae7904901d48ea27 100644 (file)
@@ -20521,6 +20521,8 @@ cp_parser_late_parsing_default_args (cp_parser *parser, tree fn)
   saved_local_variables_forbidden_p = parser->local_variables_forbidden_p;
   parser->local_variables_forbidden_p = true;
 
+  push_defarg_context (fn);
+
   for (parm = TYPE_ARG_TYPES (TREE_TYPE (fn)),
         parmdecl = DECL_ARGUMENTS (fn);
        parm && parm != void_list_node;
@@ -20579,6 +20581,8 @@ cp_parser_late_parsing_default_args (cp_parser *parser, tree fn)
       cp_parser_pop_lexer (parser);
     }
 
+  pop_defarg_context ();
+
   /* Make sure no default arg is missing.  */
   check_default_args (fn);
 
index 3947797014be952b5b70325709c1a1a7d2dd4323..3529a65bccf61c9548d939d4cd81ab0862ad7c2c 100644 (file)
@@ -1,3 +1,7 @@
+2011-03-15  Manuel López-Ibáñez  <manu@gcc.gnu.org>
+
+       * g++.dg/parse/pr34758.C: New.
+
 2011-03-15  Xinliang David Li  <davidxl@google.com>
 
        PR c/47837
diff --git a/gcc/testsuite/g++.dg/parse/pr34758.C b/gcc/testsuite/g++.dg/parse/pr34758.C
new file mode 100644 (file)
index 0000000..d694853
--- /dev/null
@@ -0,0 +1,28 @@
+// PR 34758 Bad diagnostic for circular dependency in constructor default argument
+// { dg-do compile }
+// { dg-options "" }
+struct A
+{
+  A (const A& = A()); // { dg-error "recursive evaluation of default argument" }
+};
+
+
+struct S {
+  S(const S& = f()); // { dg-error "default argument\[^\n\]*which is not yet defined" }
+  static const S& f(int i = 3);
+};
+
+struct J {
+  J(const J& = f(2)); // { dg-error "default argument.*which is not yet defined" }
+  static const J& f(int i = 3, int j = 4);
+};
+
+struct Z {
+  Z(const Z& = f(4));
+  static const Z& f(int i = 3);
+};
+
+struct X {
+  X(const X& = g());
+  static const X& g(void);
+};