re PR c++/5247 (Memory eating infinite loop on default parameter in constructor which...
authorJason Merrill <jason@redhat.com>
Sat, 27 Oct 2007 15:19:45 +0000 (11:19 -0400)
committerJason Merrill <jason@gcc.gnu.org>
Sat, 27 Oct 2007 15:19:45 +0000 (11:19 -0400)
        PR c++/5247
        * call.c (convert_default_arg): Detect recursion.

From-SVN: r129681

gcc/cp/ChangeLog
gcc/cp/call.c
gcc/testsuite/g++.dg/overload/defarg1.C [new file with mode: 0644]

index c103fe99288ab28ddfe22f8a8516374429fb5a32..be18c36c78fd4986d846cc0e5999e5085316be1b 100644 (file)
@@ -1,3 +1,8 @@
+2007-10-27  Jason Merrill  <jason@redhat.com>
+
+       PR c++/5247
+       * call.c (convert_default_arg): Detect recursion.
+
 2007-10-27  Jakub Jelinek  <jakub@redhat.com>
 
        PR c++/33842
index 121092de3325697f2a91cc8b197a7b73e51348da..297a37242012422f5fa80df59b8a7a3ffd6a598e 100644 (file)
@@ -4672,9 +4672,14 @@ cxx_type_promotes_to (tree type)
    the indicated TYPE, which is a parameter to FN.  Do any required
    conversions.  Return the converted value.  */
 
+static GTY(()) VEC(tree,gc) *default_arg_context;
+
 tree
 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)
@@ -4685,6 +4690,15 @@ convert_default_arg (tree type, tree arg, tree fn, int parmnum)
       return error_mark_node;
     }
 
+  /* Detect recursion.  */
+  for (i = 0; VEC_iterate (tree, default_arg_context, i, t); ++i)
+    if (t == fn)
+      {
+       error ("recursive evaluation of default argument for %q#D", fn);
+       return error_mark_node;
+      }
+  VEC_safe_push (tree, gc, default_arg_context, fn);
+
   if (fn && DECL_TEMPLATE_INFO (fn))
     arg = tsubst_default_argument (fn, type, arg);
 
@@ -4711,6 +4725,8 @@ convert_default_arg (tree type, tree arg, tree fn, int parmnum)
       arg = convert_for_arg_passing (type, arg);
     }
 
+  VEC_pop (tree, default_arg_context);
+
   return arg;
 }
 
diff --git a/gcc/testsuite/g++.dg/overload/defarg1.C b/gcc/testsuite/g++.dg/overload/defarg1.C
new file mode 100644 (file)
index 0000000..44de733
--- /dev/null
@@ -0,0 +1,9 @@
+// PR c++/5247
+
+template<typename T>
+int foo (T t, int = foo(T()));
+
+int main()
+{
+  foo(0);                      // { dg-error "default argument" }
+}