From 9efe5fbde1e89eab9d4f55838c8a641060b97abb Mon Sep 17 00:00:00 2001 From: Jason Merrill Date: Wed, 8 Oct 2014 10:15:06 -0400 Subject: [PATCH] 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 --- gcc/cp/ChangeLog | 5 ++++ gcc/cp/call.c | 29 +++++++++++++++++++++++ gcc/testsuite/g++.dg/overload/ellipsis3.C | 9 +++++++ 3 files changed, 43 insertions(+) create mode 100644 gcc/testsuite/g++.dg/overload/ellipsis3.C diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog index 77a825e86f8..c70de7e22ed 100644 --- a/gcc/cp/ChangeLog +++ b/gcc/cp/ChangeLog @@ -1,3 +1,8 @@ +2014-10-08 Jason Merrill + + * call.c (call_copy_ctor): New. + (build_over_call): Use it to avoid infinite recursion on invalid code. + 2014-10-07 Jason Merrill * 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 347070c9c96..76d8eabf33f 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* 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 00000000000..e7d34d6df43 --- /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" } +} -- 2.30.2