aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
authorJason Merrill <jason@redhat.com>2007-10-27 11:19:45 -0400
committerJason Merrill <jason@gcc.gnu.org>2007-10-27 11:19:45 -0400
commitd02dbde6c7e32fb62ea6ee372b0b9748ff9d39b9 (patch)
treeaba63fd3f30b037b722fb938b8e158b301a6952e /gcc
parent1200489c4624638d172b15bb9adb303867bc9639 (diff)
downloadgcc-d02dbde6c7e32fb62ea6ee372b0b9748ff9d39b9.zip
gcc-d02dbde6c7e32fb62ea6ee372b0b9748ff9d39b9.tar.gz
gcc-d02dbde6c7e32fb62ea6ee372b0b9748ff9d39b9.tar.bz2
re PR c++/5247 (Memory eating infinite loop on default parameter in constructor which is reference to class)
PR c++/5247 * call.c (convert_default_arg): Detect recursion. From-SVN: r129681
Diffstat (limited to 'gcc')
-rw-r--r--gcc/cp/ChangeLog5
-rw-r--r--gcc/cp/call.c16
-rw-r--r--gcc/testsuite/g++.dg/overload/defarg1.C9
3 files changed, 30 insertions, 0 deletions
diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog
index c103fe9..be18c36 100644
--- a/gcc/cp/ChangeLog
+++ b/gcc/cp/ChangeLog
@@ -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
diff --git a/gcc/cp/call.c b/gcc/cp/call.c
index 121092d..297a372 100644
--- a/gcc/cp/call.c
+++ b/gcc/cp/call.c
@@ -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
index 0000000..44de733
--- /dev/null
+++ b/gcc/testsuite/g++.dg/overload/defarg1.C
@@ -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" }
+}