From 6fda5f4981f1d249813c124576b037b12f6e8a61 Mon Sep 17 00:00:00 2001 From: Jason Merrill Date: Tue, 5 Nov 2019 18:50:41 -0500 Subject: [PATCH] Use vec instead of raw array for built-in candidates. My operator<=> patch wants to split up build_new_op_1, which makes using a tree array as well as the vec inconvenient. build_new_op_1 already has a vec, and build_conditional_expr_1 can release its vec right away, so this doesn't increase garbage at all. * call.c (build_builtin_candidate): Take args in a vec. (add_builtin_candidate, add_builtin_candidates): Likewise. (build_conditional_expr_1, build_new_op_1): Adjust. From-SVN: r277863 --- gcc/cp/ChangeLog | 7 ++++++ gcc/cp/call.c | 66 ++++++++++++++++++++++---------------------------------- 2 files changed, 33 insertions(+), 40 deletions(-) diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog index f6abb84..2085319 100644 --- a/gcc/cp/ChangeLog +++ b/gcc/cp/ChangeLog @@ -1,5 +1,12 @@ 2019-11-04 Jason Merrill + Use vec instead of raw array for built-in candidates. + * call.c (build_builtin_candidate): Take args in a vec. + (add_builtin_candidate, add_builtin_candidates): Likewise. + (build_conditional_expr_1, build_new_op_1): Adjust. + +2019-11-04 Jason Merrill + * constexpr.c (explain_invalid_constexpr_fn): Show location of fn. * pt.c (maybe_instantiate_noexcept): Only update clones if we diff --git a/gcc/cp/call.c b/gcc/cp/call.c index c1969bc..2a1da3cc 100644 --- a/gcc/cp/call.c +++ b/gcc/cp/call.c @@ -182,16 +182,7 @@ static struct z_candidate *add_template_candidate static struct z_candidate *add_template_candidate_real (struct z_candidate **, tree, tree, tree, tree, const vec *, tree, tree, tree, int, tree, unification_kind_t, tsubst_flags_t); -static void add_builtin_candidates - (struct z_candidate **, enum tree_code, enum tree_code, - tree, tree *, int, tsubst_flags_t); -static void add_builtin_candidate - (struct z_candidate **, enum tree_code, enum tree_code, - tree, tree, tree, tree *, tree *, int, tsubst_flags_t); static bool is_complete (tree); -static void build_builtin_candidate - (struct z_candidate **, tree, tree, tree, tree *, tree *, - int, tsubst_flags_t); static struct z_candidate *add_conv_candidate (struct z_candidate **, tree, tree, const vec *, tree, tree, tsubst_flags_t); @@ -2512,20 +2503,20 @@ add_conv_candidate (struct z_candidate **candidates, tree fn, tree obj, static void build_builtin_candidate (struct z_candidate **candidates, tree fnname, - tree type1, tree type2, tree *args, tree *argtypes, - int flags, tsubst_flags_t complain) + tree type1, tree type2, const vec &args, + tree *argtypes, int flags, tsubst_flags_t complain) { conversion *t; conversion **convs; size_t num_convs; - int viable = 1, i; + int viable = 1; tree types[2]; struct rejection_reason *reason = NULL; types[0] = type1; types[1] = type2; - num_convs = args[2] ? 3 : (args[1] ? 2 : 1); + num_convs = args.length (); convs = alloc_conversions (num_convs); /* TRUTH_*_EXPR do "contextual conversion to bool", which means explicit @@ -2536,11 +2527,8 @@ build_builtin_candidate (struct z_candidate **candidates, tree fnname, if (type1 != boolean_type_node) flags |= LOOKUP_ONLYCONVERTING; - for (i = 0; i < 2; ++i) + for (unsigned i = 0; i < 2 && i < num_convs; ++i) { - if (! args[i]) - break; - t = implicit_conversion (types[i], argtypes[i], args[i], /*c_cast_p=*/false, flags, complain); if (! t) @@ -2562,7 +2550,7 @@ build_builtin_candidate (struct z_candidate **candidates, tree fnname, } /* For COND_EXPR we rearranged the arguments; undo that now. */ - if (args[2]) + if (num_convs == 3) { convs[2] = convs[1]; convs[1] = convs[0]; @@ -2623,8 +2611,8 @@ promoted_arithmetic_type_p (tree type) static void add_builtin_candidate (struct z_candidate **candidates, enum tree_code code, enum tree_code code2, tree fnname, tree type1, - tree type2, tree *args, tree *argtypes, int flags, - tsubst_flags_t complain) + tree type2, vec &args, tree *argtypes, + int flags, tsubst_flags_t complain) { switch (code) { @@ -3083,18 +3071,21 @@ type_decays_to (tree type) static void add_builtin_candidates (struct z_candidate **candidates, enum tree_code code, - enum tree_code code2, tree fnname, tree *args, + enum tree_code code2, tree fnname, + vec *argv, int flags, tsubst_flags_t complain) { - int ref1, i; + int ref1; int enum_p = 0; tree type, argtypes[3], t; /* TYPES[i] is the set of possible builtin-operator parameter types we will consider for the Ith argument. */ vec *types[2]; unsigned ix; + vec &args = *argv; + unsigned len = args.length (); - for (i = 0; i < 3; ++i) + for (unsigned i = 0; i < len; ++i) { if (args[i]) argtypes[i] = unlowered_expr_type (args[i]); @@ -3157,11 +3148,11 @@ add_builtin_candidates (struct z_candidate **candidates, enum tree_code code, types[0] = make_tree_vector (); types[1] = make_tree_vector (); - for (i = 0; i < 2; ++i) + if (len == 3) + len = 2; + for (unsigned i = 0; i < len; ++i) { - if (! args[i]) - ; - else if (MAYBE_CLASS_TYPE_P (argtypes[i])) + if (MAYBE_CLASS_TYPE_P (argtypes[i])) { tree convs; @@ -5397,16 +5388,16 @@ build_conditional_expr_1 (const op_location_t &loc, if (!same_type_p (arg2_type, arg3_type) && (CLASS_TYPE_P (arg2_type) || CLASS_TYPE_P (arg3_type))) { - tree args[3]; + releasing_vec args; conversion *conv; bool any_viable_p; /* Rearrange the arguments so that add_builtin_candidate only has to know about two args. In build_builtin_candidate, the arguments are unscrambled. */ - args[0] = arg2; - args[1] = arg3; - args[2] = arg1; + args->quick_push (arg2); + args->quick_push (arg3); + args->quick_push (arg1); add_builtin_candidates (&candidates, COND_EXPR, NOP_EXPR, @@ -5816,7 +5807,6 @@ build_new_op_1 (const op_location_t &loc, enum tree_code code, int flags, { struct z_candidate *candidates = 0, *cand; vec *arglist; - tree args[3]; tree result = NULL_TREE; bool result_valid_p = false; enum tree_code code2 = NOP_EXPR; @@ -5929,10 +5919,6 @@ build_new_op_1 (const op_location_t &loc, enum tree_code code, int flags, flags, &candidates, complain); } - args[0] = arg1; - args[1] = arg2; - args[2] = NULL_TREE; - /* Add class-member operators to the candidate set. */ if (CLASS_TYPE_P (arg1_type)) { @@ -5952,7 +5938,7 @@ build_new_op_1 (const op_location_t &loc, enum tree_code code, int flags, BASELINK_ACCESS_BINFO (fns), flags, &candidates, complain); } - /* Per 13.3.1.2/3, 2nd bullet, if no operand has a class type, then + /* Per [over.match.oper]3.2, if no operand has a class type, then only non-member functions that have type T1 or reference to cv-qualified-opt T1 for the first argument, if the first argument has an enumeration type, or T2 or reference to cv-qualified-opt @@ -5978,9 +5964,9 @@ build_new_op_1 (const op_location_t &loc, enum tree_code code, int flags, if (TYPE_REF_P (parmtype)) parmtype = TREE_TYPE (parmtype); - if (TREE_CODE (unlowered_expr_type (args[i])) == ENUMERAL_TYPE + if (TREE_CODE (unlowered_expr_type ((*arglist)[i])) == ENUMERAL_TYPE && (same_type_ignoring_top_level_qualifiers_p - (unlowered_expr_type (args[i]), parmtype))) + (unlowered_expr_type ((*arglist)[i]), parmtype))) break; parmlist = TREE_CHAIN (parmlist); @@ -5996,7 +5982,7 @@ build_new_op_1 (const op_location_t &loc, enum tree_code code, int flags, } } - add_builtin_candidates (&candidates, code, code2, fnname, args, + add_builtin_candidates (&candidates, code, code2, fnname, arglist, flags, complain); switch (code) -- 2.7.4