diff options
Diffstat (limited to 'gcc/cp/pt.c')
-rw-r--r-- | gcc/cp/pt.c | 75 |
1 files changed, 63 insertions, 12 deletions
diff --git a/gcc/cp/pt.c b/gcc/cp/pt.c index 9815df63c28..71077a3b049 100644 --- a/gcc/cp/pt.c +++ b/gcc/cp/pt.c @@ -4864,7 +4864,7 @@ static void fixed_parameter_pack_p_1 (tree parm, struct find_parameter_pack_data *ppd) { /* A type parm can't refer to another parm. */ - if (TREE_CODE (parm) == TYPE_DECL) + if (TREE_CODE (parm) == TYPE_DECL || parm == error_mark_node) return; else if (TREE_CODE (parm) == PARM_DECL) { @@ -8265,7 +8265,11 @@ coerce_template_parms (tree parms, } if (lost) - return error_mark_node; + { + if ((complain & tf_error) && !seen_error()) + error ("wrong number of template arguments"); + return error_mark_node; + } if (CHECKING_P && !NON_DEFAULT_TEMPLATE_ARGS_COUNT (new_inner_args)) SET_NON_DEFAULT_TEMPLATE_ARGS_COUNT (new_inner_args, @@ -11475,7 +11479,9 @@ tsubst_pack_expansion (tree t, tree args, tsubst_flags_t complain, { /* This parameter pack was used in an unevaluated context. Just make a dummy decl, since it's only used for its type. */ + ++cp_unevaluated_operand; arg_pack = tsubst_decl (parm_pack, args, complain); + --cp_unevaluated_operand; if (arg_pack && DECL_PACK_P (arg_pack)) /* Partial instantiation of the parm_pack, we can't build up an argument pack yet. */ @@ -11545,7 +11551,7 @@ tsubst_pack_expansion (tree t, tree args, tsubst_flags_t complain, /* We can't substitute for this parameter pack. We use a flag as well as the missing_level counter because function parameter packs don't have a level. */ - gcc_assert (processing_template_decl); + gcc_assert (processing_template_decl || is_auto (parm_pack)); unsubstituted_packs = true; } } @@ -13776,8 +13782,7 @@ tsubst (tree t, tree args, tsubst_flags_t complain, tree in_decl) = tsubst_constraint (constr, args, complain, in_decl); else if (tree pl = CLASS_PLACEHOLDER_TEMPLATE (t)) { - if (DECL_TEMPLATE_TEMPLATE_PARM_P (pl)) - pl = tsubst (pl, args, complain, in_decl); + pl = tsubst_copy (pl, args, complain, in_decl); CLASS_PLACEHOLDER_TEMPLATE (r) = pl; } } @@ -15799,6 +15804,12 @@ tsubst_decomp_names (tree decl, tree pattern_decl, tree args, DECL_HAS_VALUE_EXPR_P (decl2) = 1; if (VAR_P (decl3)) DECL_TEMPLATE_INSTANTIATED (decl3) = 1; + else + { + gcc_assert (errorcount); + decl = error_mark_node; + continue; + } maybe_push_decl (decl3); if (error_operand_p (decl3)) decl = error_mark_node; @@ -16787,14 +16798,14 @@ tsubst_copy_and_build (tree t, if (targs) targs = tsubst_template_args (targs, args, complain, in_decl); if (targs == error_mark_node) - return error_mark_node; + RETURN (error_mark_node); if (TREE_CODE (templ) == SCOPE_REF) { tree name = TREE_OPERAND (templ, 1); tree tid = lookup_template_function (name, targs); TREE_OPERAND (templ, 1) = tid; - return templ; + RETURN (templ); } if (variable_template_p (templ)) @@ -16859,6 +16870,8 @@ tsubst_copy_and_build (tree t, { tree type = tsubst (TREE_TYPE (t), args, complain, in_decl); tree op0 = RECUR (TREE_OPERAND (t, 0)); + if (op0 == error_mark_node) + RETURN (error_mark_node); RETURN (build1 (CONVERT_EXPR, type, op0)); } @@ -17006,7 +17019,7 @@ tsubst_copy_and_build (tree t, { tree op0 = RECUR (TREE_OPERAND (t, 0)); tree op1 = RECUR (TREE_OPERAND (t, 1)); - return fold_build_pointer_plus (op0, op1); + RETURN (fold_build_pointer_plus (op0, op1)); } case SCOPE_REF: @@ -19229,6 +19242,24 @@ try_array_deduction (tree tparms, tree targs, tree parm) /*nondeduced*/false, array_deduction_r); } +/* Returns how many levels of { } INIT contains. */ + +static int +braced_init_depth (tree init) +{ + if (!init || !BRACE_ENCLOSED_INITIALIZER_P (init)) + return 0; + unsigned i; tree val; + unsigned max = 0; + FOR_EACH_CONSTRUCTOR_VALUE (CONSTRUCTOR_ELTS (init), i, val) + { + unsigned elt_d = braced_init_depth (val); + if (elt_d > max) + max = elt_d; + } + return max + 1; +} + /* Most parms like fn_type_unification. If SUBR is 1, we're being called recursively (to unify the @@ -19465,6 +19496,10 @@ type_unification_real (tree tparms, if (uses_template_parms (parm)) continue; + /* Workaround for c++/80290: avoid combinatorial explosion on + deeply nested braced init-lists. */ + if (braced_init_depth (arg) > 2) + continue; if (check_non_deducible_conversion (parm, arg, strict, flags, explain_p)) return 1; @@ -19491,10 +19526,10 @@ type_unification_real (tree tparms, if (DECL_P (parm)) input_location = DECL_SOURCE_LOCATION (parm); arg = tsubst_template_arg (arg, full_targs, complain, NULL_TREE); - if (arg != error_mark_node && !uses_template_parms (arg)) + if (!uses_template_parms (arg)) arg = convert_template_argument (parm, arg, full_targs, complain, i, NULL_TREE); - else if (saw_undeduced == 1) + else if (saw_undeduced < 2) arg = NULL_TREE; else arg = error_mark_node; @@ -25130,8 +25165,21 @@ rewrite_template_parm (tree olddecl, unsigned index, unsigned level, = TEMPLATE_TYPE_PARM_FOR_CLASS (oldtype); } else - newtype = tsubst (TREE_TYPE (olddecl), tsubst_args, - complain, NULL_TREE); + { + newtype = TREE_TYPE (olddecl); + if (type_uses_auto (newtype)) + { + // Substitute once to fix references to other template parameters. + newtype = tsubst (newtype, tsubst_args, + complain|tf_partial, NULL_TREE); + // Now substitute again to reduce the level of the auto. + newtype = tsubst (newtype, current_template_args (), + complain, NULL_TREE); + } + else + newtype = tsubst (newtype, tsubst_args, + complain, NULL_TREE); + } tree newdecl = build_decl (DECL_SOURCE_LOCATION (olddecl), TREE_CODE (olddecl), @@ -25411,6 +25459,9 @@ do_class_deduction (tree ptype, tree tmpl, tree init, int flags, // FIXME cache artificial deduction guides for (tree fns = CLASSTYPE_CONSTRUCTORS (type); fns; fns = OVL_NEXT (fns)) { + if (TREE_CODE (fns) == OVERLOAD && OVL_USED (fns)) + continue; + tree fn = OVL_CURRENT (fns); tree guide = build_deduction_guide (fn, outer_args, complain); cands = ovl_cons (guide, cands); |