aboutsummaryrefslogtreecommitdiff
path: root/gcc/cp/pt.c
diff options
context:
space:
mode:
Diffstat (limited to 'gcc/cp/pt.c')
-rw-r--r--gcc/cp/pt.c75
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);