From bd84e5607ef5c01b9fc5f3cbd004aed807a084f2 Mon Sep 17 00:00:00 2001 From: Jason Merrill Date: Sat, 23 Jul 2016 22:59:34 -0400 Subject: [PATCH] PR c++/66617 - virtual base list-initialization * call.c (add_list_candidates): Handle VTT parm. (build_new_method_call_1): Likewise. From-SVN: r238689 --- gcc/cp/ChangeLog | 4 +++ gcc/cp/call.c | 37 +++++++++++++-------- gcc/testsuite/g++.dg/cpp0x/initlist-base1.C | 15 +++++++++ 3 files changed, 43 insertions(+), 13 deletions(-) create mode 100644 gcc/testsuite/g++.dg/cpp0x/initlist-base1.C diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog index d60846b1dc1..6c5b5de2923 100644 --- a/gcc/cp/ChangeLog +++ b/gcc/cp/ChangeLog @@ -1,5 +1,9 @@ 2016-07-23 Jason Merrill + PR c++/66617 + * call.c (add_list_candidates): Handle VTT parm. + (build_new_method_call_1): Likewise. + PR c++/55922 PR c++/63151 * init.c (expand_aggr_init_1): Handle list-initialization from {}. diff --git a/gcc/cp/call.c b/gcc/cp/call.c index 2f373a37b98..802c3258e8f 100644 --- a/gcc/cp/call.c +++ b/gcc/cp/call.c @@ -3577,15 +3577,13 @@ merge_conversion_sequences (conversion *user_seq, conversion *std_seq) static void add_list_candidates (tree fns, tree first_arg, - tree init_list, tree totype, + const vec *args, tree totype, tree explicit_targs, bool template_only, tree conversion_path, tree access_path, int flags, struct z_candidate **candidates, tsubst_flags_t complain) { - vec *args; - gcc_assert (*candidates == NULL); /* We're looking for a ctor for list-initialization. */ @@ -3594,6 +3592,9 @@ add_list_candidates (tree fns, tree first_arg, avoid the copy constructor call for copy-list-initialization. */ flags |= LOOKUP_NO_NARROWING; + unsigned nart = num_artificial_parms_for (get_first_fn (fns)) - 1; + tree init_list = (*args)[nart]; + /* Always use the default constructor if the list is empty (DR 990). */ if (CONSTRUCTOR_NELTS (init_list) == 0 && TYPE_HAS_DEFAULT_CONSTRUCTOR (totype)) @@ -3603,7 +3604,6 @@ add_list_candidates (tree fns, tree first_arg, else if (TYPE_HAS_LIST_CTOR (totype)) { flags |= LOOKUP_LIST_ONLY; - args = make_tree_vector_single (init_list); add_candidates (fns, first_arg, args, NULL_TREE, explicit_targs, template_only, conversion_path, access_path, flags, candidates, complain); @@ -3611,14 +3611,20 @@ add_list_candidates (tree fns, tree first_arg, return; } - args = ctor_to_vec (init_list); + /* Expand the CONSTRUCTOR into a new argument vec. */ + vec *new_args; + vec_alloc (new_args, nart + CONSTRUCTOR_NELTS (init_list)); + for (unsigned i = 0; i < nart; ++i) + new_args->quick_push ((*args)[i]); + for (unsigned i = 0; i < CONSTRUCTOR_NELTS (init_list); ++i) + new_args->quick_push (CONSTRUCTOR_ELT (init_list, i)->value); /* We aren't looking for list-ctors anymore. */ flags &= ~LOOKUP_LIST_ONLY; /* We allow more user-defined conversions within an init-list. */ flags &= ~LOOKUP_NO_CONVERSION; - add_candidates (fns, first_arg, args, NULL_TREE, + add_candidates (fns, first_arg, new_args, NULL_TREE, explicit_targs, template_only, conversion_path, access_path, flags, candidates, complain); } @@ -3698,16 +3704,16 @@ build_user_type_conversion_1 (tree totype, tree expr, int flags, gcc_assert (!DECL_HAS_IN_CHARGE_PARM_P (OVL_CURRENT (ctors)) && !DECL_HAS_VTT_PARM_P (OVL_CURRENT (ctors))); + args = make_tree_vector_single (expr); if (BRACE_ENCLOSED_INITIALIZER_P (expr)) { /* List-initialization. */ - add_list_candidates (ctors, first_arg, expr, totype, NULL_TREE, + add_list_candidates (ctors, first_arg, args, totype, NULL_TREE, false, TYPE_BINFO (totype), TYPE_BINFO (totype), ctorflags, &candidates, complain); } else { - args = make_tree_vector_single (expr); add_candidates (ctors, first_arg, args, NULL_TREE, NULL_TREE, false, TYPE_BINFO (totype), TYPE_BINFO (totype), ctorflags, &candidates, complain); @@ -8350,15 +8356,20 @@ build_new_method_call_1 (tree instance, tree fns, vec **args, /* Get the high-water mark for the CONVERSION_OBSTACK. */ p = conversion_obstack_alloc (0); + /* The number of arguments artificial parms in ARGS; we subtract one because + there's no 'this' in ARGS. */ + unsigned skip = num_artificial_parms_for (fn) - 1; + /* If CONSTRUCTOR_IS_DIRECT_INIT is set, this was a T{ } form initializer, not T({ }). */ - if (DECL_CONSTRUCTOR_P (fn) && args != NULL && !vec_safe_is_empty (*args) - && DIRECT_LIST_INIT_P ((**args)[0])) + if (DECL_CONSTRUCTOR_P (fn) + && vec_safe_length (user_args) > skip + && DIRECT_LIST_INIT_P ((*user_args)[skip])) { - tree init_list = (**args)[0]; + tree init_list = (*user_args)[skip]; tree init = NULL_TREE; - gcc_assert ((*args)->length () == 1 + gcc_assert (user_args->length () == skip + 1 && !(flags & LOOKUP_ONLYCONVERTING)); /* If the initializer list has no elements and T is a class type with @@ -8391,7 +8402,7 @@ build_new_method_call_1 (tree instance, tree fns, vec **args, } /* Otherwise go ahead with overload resolution. */ - add_list_candidates (fns, first_mem_arg, init_list, + add_list_candidates (fns, first_mem_arg, user_args, basetype, explicit_targs, template_only, conversion_path, access_binfo, flags, &candidates, complain); diff --git a/gcc/testsuite/g++.dg/cpp0x/initlist-base1.C b/gcc/testsuite/g++.dg/cpp0x/initlist-base1.C new file mode 100644 index 00000000000..cbae170b028 --- /dev/null +++ b/gcc/testsuite/g++.dg/cpp0x/initlist-base1.C @@ -0,0 +1,15 @@ +// PR c++/66617 +// { dg-do compile { target c++11 } } + +struct A { }; +struct B: virtual A +{ +protected: + B(int, int); +}; +struct C: B +{ + C(): B{1,2} {} +}; + + -- 2.30.2