From bcc7f9c93dae57aad8bbcb6b5f32594a21f889bb Mon Sep 17 00:00:00 2001 From: jason Date: Wed, 8 Oct 2014 14:15:06 +0000 Subject: [PATCH] * call.c (call_copy_ctor): New. (build_over_call): Use it to avoid infinite recursion on invalid code. git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@216005 138bc75d-0d04-0410-961f-82ee72b054a4 --- 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 77a825e..c70de7e 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 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* 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" } +} -- 2.7.4