aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJason Merrill <jason@redhat.com>2014-10-08 10:15:06 -0400
committerJason Merrill <jason@gcc.gnu.org>2014-10-08 10:15:06 -0400
commit9efe5fbde1e89eab9d4f55838c8a641060b97abb (patch)
treebb8de79e5cf30cc8a35f32d7f3c8fd2456c4c076
parent19d4baed5721eb7c95e56c2bec68ae7db6308f9e (diff)
downloadgcc-9efe5fbde1e89eab9d4f55838c8a641060b97abb.zip
gcc-9efe5fbde1e89eab9d4f55838c8a641060b97abb.tar.gz
gcc-9efe5fbde1e89eab9d4f55838c8a641060b97abb.tar.bz2
call.c (call_copy_ctor): New.
* call.c (call_copy_ctor): New. (build_over_call): Use it to avoid infinite recursion on invalid code. From-SVN: r216005
-rw-r--r--gcc/cp/ChangeLog5
-rw-r--r--gcc/cp/call.c29
-rw-r--r--gcc/testsuite/g++.dg/overload/ellipsis3.C9
3 files changed, 43 insertions, 0 deletions
diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog
index 77a825e..c70de7e 100644
--- a/gcc/cp/ChangeLog
+++ b/gcc/cp/ChangeLog
@@ -1,3 +1,8 @@
+2014-10-08 Jason Merrill <jason@redhat.com>
+
+ * call.c (call_copy_ctor): New.
+ (build_over_call): Use it to avoid infinite recursion on invalid code.
+
2014-10-07 Jason Merrill <jason@redhat.com>
* tree.c (cp_tree_equal) [TRAIT_EXPR]: Use cp_tree_equal for type2.
diff --git a/gcc/cp/call.c b/gcc/cp/call.c
index 347070c..76d8eab 100644
--- a/gcc/cp/call.c
+++ b/gcc/cp/call.c
@@ -6896,6 +6896,25 @@ mark_versions_used (tree fn)
}
}
+/* Build a call to "the copy constructor" for the type of A, even if it
+ wouldn't be selected by normal overload resolution. Used for
+ diagnostics. */
+
+static tree
+call_copy_ctor (tree a, tsubst_flags_t complain)
+{
+ tree ctype = TYPE_MAIN_VARIANT (TREE_TYPE (a));
+ tree binfo = TYPE_BINFO (ctype);
+ tree copy = get_copy_ctor (ctype, complain);
+ copy = build_baselink (binfo, binfo, copy, NULL_TREE);
+ tree ob = build_dummy_object (ctype);
+ vec<tree, va_gc>* args = make_tree_vector_single (a);
+ tree r = build_new_method_call (ob, copy, &args, NULL_TREE,
+ LOOKUP_NORMAL, NULL, complain);
+ release_tree_vector (args);
+ return r;
+}
+
/* Subroutine of the various build_*_call functions. Overload resolution
has chosen a winning candidate CAND; build up a CALL_EXPR accordingly.
ARGS is a TREE_LIST of the unconverted arguments to the call. FLAGS is a
@@ -7234,6 +7253,16 @@ build_over_call (struct z_candidate *cand, int flags, tsubst_flags_t complain)
if (magic_varargs_p (fn))
/* Do no conversions for magic varargs. */
a = mark_type_use (a);
+ else if (DECL_CONSTRUCTOR_P (fn)
+ && same_type_ignoring_top_level_qualifiers_p (DECL_CONTEXT (fn),
+ TREE_TYPE (a)))
+ {
+ /* Avoid infinite recursion trying to call A(...). */
+ if (complain & tf_error)
+ /* Try to call the actual copy constructor for a good error. */
+ call_copy_ctor (a, complain);
+ return error_mark_node;
+ }
else
a = convert_arg_to_ellipsis (a, complain);
argarray[j++] = a;
diff --git a/gcc/testsuite/g++.dg/overload/ellipsis3.C b/gcc/testsuite/g++.dg/overload/ellipsis3.C
new file mode 100644
index 0000000..e7d34d6
--- /dev/null
+++ b/gcc/testsuite/g++.dg/overload/ellipsis3.C
@@ -0,0 +1,9 @@
+struct A {
+ A(...);
+};
+
+int main()
+{
+ volatile A a;
+ volatile A a2(a); // { dg-error "volatile" }
+}