aboutsummaryrefslogtreecommitdiff
path: root/gcc/cp/pt.c
diff options
context:
space:
mode:
authorIan Lance Taylor <iant@golang.org>2021-09-13 10:37:49 -0700
committerIan Lance Taylor <iant@golang.org>2021-09-13 10:37:49 -0700
commite252b51ccde010cbd2a146485d8045103cd99533 (patch)
treee060f101cdc32bf5e520de8e5275db9d4236b74c /gcc/cp/pt.c
parentf10c7c4596dda99d2ee872c995ae4aeda65adbdf (diff)
parent104c05c5284b7822d770ee51a7d91946c7e56d50 (diff)
downloadgcc-e252b51ccde010cbd2a146485d8045103cd99533.zip
gcc-e252b51ccde010cbd2a146485d8045103cd99533.tar.gz
gcc-e252b51ccde010cbd2a146485d8045103cd99533.tar.bz2
Merge from trunk revision 104c05c5284b7822d770ee51a7d91946c7e56d50.
Diffstat (limited to 'gcc/cp/pt.c')
-rw-r--r--gcc/cp/pt.c1434
1 files changed, 802 insertions, 632 deletions
diff --git a/gcc/cp/pt.c b/gcc/cp/pt.c
index 5e485f1..224dd9e 100644
--- a/gcc/cp/pt.c
+++ b/gcc/cp/pt.c
@@ -65,7 +65,6 @@ static GTY(()) struct pending_template *last_pending_template;
int processing_template_parmlist;
static int template_header_count;
-static GTY(()) tree saved_trees;
static vec<int> inline_parm_levels;
static GTY(()) struct tinst_level *current_tinst_level;
@@ -152,12 +151,11 @@ static tree coerce_template_parms (tree, tree, tree, tsubst_flags_t,
static tree coerce_innermost_template_parms (tree, tree, tree, tsubst_flags_t,
bool, bool);
static void tsubst_enum (tree, tree, tree);
-static tree add_to_template_args (tree, tree);
static bool check_instantiated_args (tree, tree, tsubst_flags_t);
static int check_non_deducible_conversion (tree, tree, int, int,
struct conversion **, bool);
-static int maybe_adjust_types_for_deduction (unification_kind_t, tree*, tree*,
- tree);
+static int maybe_adjust_types_for_deduction (tree, unification_kind_t,
+ tree*, tree*, tree);
static int type_unification_real (tree, tree, tree, const tree *,
unsigned int, int, unification_kind_t,
vec<deferred_access_check, va_gc> **,
@@ -192,7 +190,6 @@ static tree tsubst_arg_types (tree, tree, tree, tsubst_flags_t, tree);
static tree tsubst_function_type (tree, tree, tsubst_flags_t, tree);
static bool check_specialization_scope (void);
static tree process_partial_specialization (tree);
-static void set_current_access_from_decl (tree);
static enum template_base_result get_template_base (tree, tree, tree, tree,
bool , tree *);
static tree try_class_unification (tree, tree, tree, tree, bool);
@@ -227,7 +224,7 @@ static void instantiate_body (tree pattern, tree args, tree d, bool nested);
/* Make the current scope suitable for access checking when we are
processing T. T can be FUNCTION_DECL for instantiated function
template, VAR_DECL for static member variable, or TYPE_DECL for
- alias template (needed by instantiate_decl). */
+ for a class or alias template (needed by instantiate_decl). */
void
push_access_scope (tree t)
@@ -237,8 +234,15 @@ push_access_scope (tree t)
if (DECL_FRIEND_CONTEXT (t))
push_nested_class (DECL_FRIEND_CONTEXT (t));
+ else if (DECL_IMPLICIT_TYPEDEF_P (t)
+ && CLASS_TYPE_P (TREE_TYPE (t)))
+ push_nested_class (TREE_TYPE (t));
else if (DECL_CLASS_SCOPE_P (t))
push_nested_class (DECL_CONTEXT (t));
+ else if (deduction_guide_p (t) && DECL_ARTIFICIAL (t))
+ /* An artificial deduction guide should have the same access as
+ the constructor. */
+ push_nested_class (TREE_TYPE (TREE_TYPE (t)));
else
push_to_top_level ();
@@ -258,7 +262,11 @@ pop_access_scope (tree t)
if (TREE_CODE (t) == FUNCTION_DECL)
current_function_decl = saved_access_scope->pop();
- if (DECL_FRIEND_CONTEXT (t) || DECL_CLASS_SCOPE_P (t))
+ if (DECL_FRIEND_CONTEXT (t)
+ || (DECL_IMPLICIT_TYPEDEF_P (t)
+ && CLASS_TYPE_P (TREE_TYPE (t)))
+ || DECL_CLASS_SCOPE_P (t)
+ || (deduction_guide_p (t) && DECL_ARTIFICIAL (t)))
pop_nested_class ();
else
pop_from_top_level ();
@@ -554,7 +562,7 @@ maybe_end_member_template_processing (void)
/* Return a new template argument vector which contains all of ARGS,
but has as its innermost set of arguments the EXTRA_ARGS. */
-static tree
+tree
add_to_template_args (tree args, tree extra_args)
{
tree new_args;
@@ -985,6 +993,10 @@ maybe_process_partial_specialization (tree type)
if (CLASS_TYPE_P (type) && CLASSTYPE_LAMBDA_EXPR (type))
return type;
+ /* An injected-class-name is not a specialization. */
+ if (DECL_SELF_REFERENCE_P (TYPE_NAME (type)))
+ return type;
+
if (TREE_CODE (type) == BOUND_TEMPLATE_TEMPLATE_PARM)
{
error ("name of class shadows template template parameter %qD",
@@ -2198,6 +2210,7 @@ determine_specialization (tree template_id,
++header_count;
tree orig_fns = fns;
+ bool header_mismatch = false;
if (variable_template_p (fns))
{
@@ -2245,7 +2258,10 @@ determine_specialization (tree template_id,
specialization but rather a template instantiation, so there
is no check we can perform here. */
if (header_count && header_count != template_count + 1)
- continue;
+ {
+ header_mismatch = true;
+ continue;
+ }
/* Check that the number of template arguments at the
innermost level for DECL is the same as for FN. */
@@ -2479,13 +2495,12 @@ determine_specialization (tree template_id,
{
error ("template-id %qD for %q+D does not match any template "
"declaration", template_id, decl);
- if (header_count && header_count != template_count + 1)
+ if (header_mismatch)
inform (DECL_SOURCE_LOCATION (decl),
"saw %d %<template<>%>, need %d for "
"specializing a member function template",
header_count, template_count + 1);
- else
- print_candidates (orig_fns);
+ print_candidates (orig_fns);
return error_mark_node;
}
else if ((templates && TREE_CHAIN (templates))
@@ -2698,7 +2713,7 @@ check_template_variable (tree decl)
&& PRIMARY_TEMPLATE_P (DECL_TI_TEMPLATE (decl)))
{
if (cxx_dialect < cxx14)
- pedwarn (DECL_SOURCE_LOCATION (decl), 0,
+ pedwarn (DECL_SOURCE_LOCATION (decl), OPT_Wc__14_extensions,
"variable templates only available with "
"%<-std=c++14%> or %<-std=gnu++14%>");
@@ -3688,25 +3703,6 @@ get_primary_template_innermost_parameters (const_tree t)
return parms;
}
-/* Return the template parameters of the LEVELth level from the full list
- of template parameters PARMS. */
-
-tree
-get_template_parms_at_level (tree parms, int level)
-{
- tree p;
- if (!parms
- || TREE_CODE (parms) != TREE_LIST
- || level > TMPL_PARMS_DEPTH (parms))
- return NULL_TREE;
-
- for (p = parms; p; p = TREE_CHAIN (p))
- if (TMPL_PARMS_DEPTH (p) == level)
- return p;
-
- return NULL_TREE;
-}
-
/* Returns the template arguments of T if T is a template instantiation,
NULL otherwise. */
@@ -3859,6 +3855,18 @@ expand_builtin_pack_call (tree call, tree args, tsubst_flags_t complain,
return NULL_TREE;
}
+/* Return true if the tree T has the extra args mechanism for
+ avoiding partial instantiation. */
+
+static bool
+has_extra_args_mechanism_p (const_tree t)
+{
+ return (PACK_EXPANSION_P (t) /* PACK_EXPANSION_EXTRA_ARGS */
+ || TREE_CODE (t) == REQUIRES_EXPR /* REQUIRES_EXPR_EXTRA_ARGS */
+ || (TREE_CODE (t) == IF_STMT
+ && IF_STMT_CONSTEXPR_P (t))); /* IF_STMT_EXTRA_ARGS */
+}
+
/* Structure used to track the progress of find_parameter_packs_r. */
struct find_parameter_pack_data
{
@@ -3871,6 +3879,9 @@ struct find_parameter_pack_data
/* True iff we're making a type pack expansion. */
bool type_pack_expansion_p;
+
+ /* True iff we found a subtree that has the extra args mechanism. */
+ bool found_extra_args_tree_p = false;
};
/* Identifies all of the argument packs that occur in a template
@@ -3885,6 +3896,10 @@ find_parameter_packs_r (tree *tp, int *walk_subtrees, void* data)
(struct find_parameter_pack_data*)data;
bool parameter_pack_p = false;
+#define WALK_SUBTREE(NODE) \
+ cp_walk_tree (&(NODE), &find_parameter_packs_r, \
+ ppd, ppd->visited) \
+
/* Don't look through typedefs; we are interested in whether a
parameter pack is actually written in the expression/type we're
looking at, not the target type. */
@@ -3968,6 +3983,9 @@ find_parameter_packs_r (tree *tp, int *walk_subtrees, void* data)
*ppd->parameter_packs = tree_cons (NULL_TREE, t, *ppd->parameter_packs);
}
+ if (has_extra_args_mechanism_p (t) && !PACK_EXPANSION_P (t))
+ ppd->found_extra_args_tree_p = true;
+
if (TYPE_P (t))
cp_walk_tree (&TYPE_CONTEXT (t),
&find_parameter_packs_r, ppd, ppd->visited);
@@ -4056,10 +4074,32 @@ find_parameter_packs_r (tree *tp, int *walk_subtrees, void* data)
*walk_subtrees = 0;
return NULL_TREE;
+ case TAG_DEFN:
+ t = TREE_TYPE (t);
+ if (CLASS_TYPE_P (t))
+ /* Local class, need to look through the whole definition. */
+ for (tree bb : BINFO_BASE_BINFOS (TYPE_BINFO (t)))
+ cp_walk_tree (&BINFO_TYPE (bb), &find_parameter_packs_r,
+ ppd, ppd->visited);
+ else
+ /* Enum, look at the values. */
+ for (tree l = TYPE_VALUES (t); l; l = TREE_CHAIN (l))
+ cp_walk_tree (&DECL_INITIAL (TREE_VALUE (l)),
+ &find_parameter_packs_r,
+ ppd, ppd->visited);
+ return NULL_TREE;
+
+ case FUNCTION_TYPE:
+ case METHOD_TYPE:
+ WALK_SUBTREE (TYPE_RAISES_EXCEPTIONS (t));
+ break;
+
default:
return NULL_TREE;
}
+#undef WALK_SUBTREE
+
return NULL_TREE;
}
@@ -4207,6 +4247,14 @@ make_pack_expansion (tree arg, tsubst_flags_t complain)
PACK_EXPANSION_PARAMETER_PACKS (result) = parameter_packs;
PACK_EXPANSION_LOCAL_P (result) = at_function_scope_p ();
+ if (ppd.found_extra_args_tree_p)
+ /* If the pattern of this pack expansion contains a subtree that has
+ the extra args mechanism for avoiding partial instantiation, then
+ force this pack expansion to also use extra args. Otherwise
+ partial instantiation of this pack expansion may not lower the
+ level of some parameter packs within the pattern, which would
+ confuse tsubst_pack_expansion later (PR101764). */
+ PACK_EXPANSION_FORCE_EXTRA_ARGS_P (result) = true;
return result;
}
@@ -4930,16 +4978,8 @@ build_template_decl (tree decl, tree parms, bool member_template_p)
DECL_SOURCE_LOCATION (tmpl) = DECL_SOURCE_LOCATION (decl);
DECL_MEMBER_TEMPLATE_P (tmpl) = member_template_p;
- if (modules_p ())
- {
- /* Propagate module information from the decl. */
- DECL_MODULE_EXPORT_P (tmpl) = DECL_MODULE_EXPORT_P (decl);
- if (DECL_LANG_SPECIFIC (decl))
- {
- DECL_MODULE_PURVIEW_P (tmpl) = DECL_MODULE_PURVIEW_P (decl);
- gcc_checking_assert (!DECL_MODULE_IMPORT_P (decl));
- }
- }
+ /* Propagate module information from the decl. */
+ DECL_MODULE_EXPORT_P (tmpl) = DECL_MODULE_EXPORT_P (decl);
return tmpl;
}
@@ -5153,11 +5193,7 @@ process_partial_specialization (tree decl)
maintmpl);
}
- /* [temp.class.spec]
-
- A partially specialized non-type argument expression shall not
- involve template parameters of the partial specialization except
- when the argument expression is a simple identifier.
+ /* [temp.spec.partial]
The type of a template parameter corresponding to a specialized
non-type argument shall not be dependent on a parameter of the
@@ -5218,63 +5254,55 @@ process_partial_specialization (tree decl)
|| TREE_CODE (arg) == VIEW_CONVERT_EXPR)
&& TREE_CODE (TREE_OPERAND (arg, 0)) == TEMPLATE_PARM_INDEX))
{
- if ((!packed_args && tpd.arg_uses_template_parms[i])
- || (packed_args && uses_template_parms (arg)))
- error_at (cp_expr_loc_or_input_loc (arg),
- "template argument %qE involves template "
- "parameter(s)", arg);
- else
- {
- /* Look at the corresponding template parameter,
- marking which template parameters its type depends
- upon. */
- tree type = TREE_TYPE (parm);
+ /* Look at the corresponding template parameter,
+ marking which template parameters its type depends
+ upon. */
+ tree type = TREE_TYPE (parm);
- if (!tpd2.parms)
- {
- /* We haven't yet initialized TPD2. Do so now. */
- tpd2.arg_uses_template_parms = XALLOCAVEC (int, nargs);
- /* The number of parameters here is the number in the
- main template, which, as checked in the assertion
- above, is NARGS. */
- tpd2.parms = XALLOCAVEC (int, nargs);
- tpd2.level =
- TMPL_PARMS_DEPTH (DECL_TEMPLATE_PARMS (maintmpl));
- }
+ if (!tpd2.parms)
+ {
+ /* We haven't yet initialized TPD2. Do so now. */
+ tpd2.arg_uses_template_parms = XALLOCAVEC (int, nargs);
+ /* The number of parameters here is the number in the
+ main template, which, as checked in the assertion
+ above, is NARGS. */
+ tpd2.parms = XALLOCAVEC (int, nargs);
+ tpd2.level =
+ TMPL_PARMS_DEPTH (DECL_TEMPLATE_PARMS (maintmpl));
+ }
- /* Mark the template parameters. But this time, we're
- looking for the template parameters of the main
- template, not in the specialization. */
- tpd2.current_arg = i;
- tpd2.arg_uses_template_parms[i] = 0;
- memset (tpd2.parms, 0, sizeof (int) * nargs);
- for_each_template_parm (type,
- &mark_template_parm,
- &tpd2,
- NULL,
- /*include_nondeduced_p=*/false);
-
- if (tpd2.arg_uses_template_parms [i])
- {
- /* The type depended on some template parameters.
- If they are fully specialized in the
- specialization, that's OK. */
- int j;
- int count = 0;
- for (j = 0; j < nargs; ++j)
- if (tpd2.parms[j] != 0
- && tpd.arg_uses_template_parms [j])
- ++count;
- if (count != 0)
- error_n (input_location, count,
- "type %qT of template argument %qE depends "
- "on a template parameter",
- "type %qT of template argument %qE depends "
- "on template parameters",
- type,
- arg);
- }
- }
+ /* Mark the template parameters. But this time, we're
+ looking for the template parameters of the main
+ template, not in the specialization. */
+ tpd2.current_arg = i;
+ tpd2.arg_uses_template_parms[i] = 0;
+ memset (tpd2.parms, 0, sizeof (int) * nargs);
+ for_each_template_parm (type,
+ &mark_template_parm,
+ &tpd2,
+ NULL,
+ /*include_nondeduced_p=*/false);
+
+ if (tpd2.arg_uses_template_parms [i])
+ {
+ /* The type depended on some template parameters.
+ If they are fully specialized in the
+ specialization, that's OK. */
+ int j;
+ int count = 0;
+ for (j = 0; j < nargs; ++j)
+ if (tpd2.parms[j] != 0
+ && tpd.arg_uses_template_parms [j])
+ ++count;
+ if (count != 0)
+ error_n (input_location, count,
+ "type %qT of template argument %qE depends "
+ "on a template parameter",
+ "type %qT of template argument %qE depends "
+ "on template parameters",
+ type,
+ arg);
+ }
}
}
}
@@ -5799,18 +5827,7 @@ push_template_decl (tree decl, bool is_friend)
}
else if (DECL_IMPLICIT_TYPEDEF_P (decl)
&& CLASS_TYPE_P (TREE_TYPE (decl)))
- {
- /* Class template, set TEMPLATE_TYPE_PARM_FOR_CLASS. */
- tree parms = INNERMOST_TEMPLATE_PARMS (current_template_parms);
- for (int i = 0; i < TREE_VEC_LENGTH (parms); ++i)
- {
- tree t = TREE_VALUE (TREE_VEC_ELT (parms, i));
- if (TREE_CODE (t) == TYPE_DECL)
- t = TREE_TYPE (t);
- if (TREE_CODE (t) == TEMPLATE_TYPE_PARM)
- TEMPLATE_TYPE_PARM_FOR_CLASS (t) = true;
- }
- }
+ /* Class template. */;
else if (TREE_CODE (decl) == TYPE_DECL
&& TYPE_DECL_ALIAS_P (decl))
/* alias-declaration */
@@ -6290,9 +6307,6 @@ redeclare_class_template (tree type, tree parms, tree cons)
gcc_assert (DECL_CONTEXT (parm) == NULL_TREE);
DECL_CONTEXT (parm) = tmpl;
}
-
- if (TREE_CODE (parm) == TYPE_DECL)
- TEMPLATE_TYPE_PARM_FOR_CLASS (TREE_TYPE (parm)) = true;
}
tree ci = get_constraints (tmpl);
@@ -6578,6 +6592,10 @@ get_underlying_template (tree tmpl)
!= num_innermost_template_parms (underlying)))
break;
+ /* Does the alias add cv-quals? */
+ if (TYPE_QUALS (TREE_TYPE (underlying)) != TYPE_QUALS (TREE_TYPE (tmpl)))
+ break;
+
tree alias_args = INNERMOST_TEMPLATE_ARGS (generic_targs_for (tmpl));
if (!comp_template_args (TI_ARGS (tinfo), alias_args))
break;
@@ -6614,7 +6632,10 @@ convert_nontype_argument_function (tree type, tree expr,
if (value_dependent_expression_p (fn))
goto accept;
- fn_no_ptr = strip_fnptr_conv (fn);
+ fn_no_ptr = fn;
+ if (REFERENCE_REF_P (fn_no_ptr))
+ fn_no_ptr = TREE_OPERAND (fn_no_ptr, 0);
+ fn_no_ptr = strip_fnptr_conv (fn_no_ptr);
if (TREE_CODE (fn_no_ptr) == ADDR_EXPR)
fn_no_ptr = TREE_OPERAND (fn_no_ptr, 0);
if (BASELINK_P (fn_no_ptr))
@@ -6967,7 +6988,7 @@ bool
template_parm_object_p (const_tree t)
{
return (TREE_CODE (t) == VAR_DECL && DECL_ARTIFICIAL (t) && DECL_NAME (t)
- && !strncmp (IDENTIFIER_POINTER (DECL_NAME (t)), "_ZTA", 4));
+ && startswith (IDENTIFIER_POINTER (DECL_NAME (t)), "_ZTA"));
}
/* Subroutine of convert_nontype_argument, to check whether EXPR, as an
@@ -7129,6 +7150,9 @@ get_template_parm_object (tree expr, tsubst_flags_t complain)
if (invalid_tparm_referent_p (TREE_TYPE (expr), expr, complain))
return error_mark_node;
+ /* This is no longer a compound literal. */
+ gcc_assert (!TREE_HAS_CONSTRUCTOR (expr));
+
tree name = mangle_template_parm_object (expr);
tree decl = get_global_binding (name);
if (decl)
@@ -8488,7 +8512,8 @@ convert_template_argument (tree parm,
can happen in the context of -fnew-ttp-matching. */;
else if (tree a = type_uses_auto (t))
{
- t = do_auto_deduction (t, arg, a, complain, adc_unify, args);
+ t = do_auto_deduction (t, arg, a, complain, adc_unify, args,
+ LOOKUP_IMPLICIT);
if (t == error_mark_node)
return error_mark_node;
}
@@ -8498,6 +8523,10 @@ convert_template_argument (tree parm,
if (invalid_nontype_parm_type_p (t, complain))
return error_mark_node;
+ /* Drop top-level cv-qualifiers on the substituted/deduced type of
+ this non-type template parameter, as per [temp.param]/6. */
+ t = cv_unqualified (t);
+
if (t != TREE_TYPE (parm))
t = canonicalize_type_argument (t, complain);
@@ -9592,6 +9621,7 @@ lookup_template_function (tree fns, tree arglist)
if (BASELINK_P (fns))
{
+ fns = copy_node (fns);
BASELINK_FUNCTIONS (fns) = build2 (TEMPLATE_ID_EXPR,
unknown_type_node,
BASELINK_FUNCTIONS (fns),
@@ -9827,6 +9857,13 @@ lookup_template_class_1 (tree d1, tree arglist, tree in_decl, tree context,
/* From here on, we're only interested in the most general
template. */
+ /* Shortcut looking up the current class scope again. */
+ if (current_class_type)
+ if (tree ti = CLASSTYPE_TEMPLATE_INFO (current_class_type))
+ if (gen_tmpl == most_general_template (TI_TEMPLATE (ti))
+ && comp_template_args (arglist, TI_ARGS (ti)))
+ return current_class_type;
+
/* Calculate the BOUND_ARGS. These will be the args that are
actually tsubst'd into the definition to create the
instantiation. */
@@ -10167,25 +10204,7 @@ lookup_template_class_1 (tree d1, tree arglist, tree in_decl, tree context,
}
/* Build template info for the new specialization. */
- if (TYPE_ALIAS_P (t))
- {
- /* This is constructed during instantiation of the alias
- decl. But for member templates of template classes, that
- is not correct as we need to refer to the partially
- instantiated template, not the most general template.
- The incorrect knowledge will not have escaped this
- instantiation process, so we're good just updating the
- template_info we made then. */
- tree ti = DECL_TEMPLATE_INFO (TYPE_NAME (t));
- gcc_checking_assert (template_args_equal (TI_ARGS (ti), arglist));
- if (TI_TEMPLATE (ti) != found)
- {
- gcc_checking_assert (DECL_TI_TEMPLATE (found) == TI_TEMPLATE (ti));
- TI_TEMPLATE (ti) = found;
- }
- }
- else
- SET_TYPE_TEMPLATE_INFO (t, build_template_info (found, arglist));
+ SET_TYPE_TEMPLATE_INFO (t, build_template_info (found, arglist));
elt.spec = t;
slot = type_specializations->find_slot_with_hash (&elt, hash, INSERT);
@@ -10200,7 +10219,8 @@ lookup_template_class_1 (tree d1, tree arglist, tree in_decl, tree context,
= tree_cons (arglist, t,
DECL_TEMPLATE_INSTANTIATIONS (found));
- if (TREE_CODE (template_type) == ENUMERAL_TYPE && !is_dependent_type
+ if (TREE_CODE (template_type) == ENUMERAL_TYPE
+ && !uses_template_parms (current_nonlambda_scope ())
&& !DECL_ALIAS_TEMPLATE_P (gen_tmpl))
/* Now that the type has been registered on the instantiations
list, we set up the enumerators. Because the enumeration
@@ -10261,10 +10281,6 @@ finish_template_variable (tree var, tsubst_flags_t complain)
tree templ = TREE_OPERAND (var, 0);
tree arglist = TREE_OPERAND (var, 1);
- tree tmpl_args = DECL_TI_ARGS (DECL_TEMPLATE_RESULT (templ));
- arglist = add_outermost_template_args (tmpl_args, arglist);
-
- templ = most_general_template (templ);
tree parms = DECL_TEMPLATE_PARMS (templ);
arglist = coerce_innermost_template_parms (parms, arglist, templ, complain,
/*req_all*/true,
@@ -10505,6 +10521,15 @@ for_each_template_parm_r (tree *tp, int *walk_subtrees, void *d)
return error_mark_node;
break;
+ case TRAIT_EXPR:
+ case PLUS_EXPR:
+ case MULT_EXPR:
+ case SCOPE_REF:
+ /* These are non-deduced contexts. */
+ if (!pfd->include_nondeduced_p)
+ *walk_subtrees = 0;
+ break;
+
case MODOP_EXPR:
case CAST_EXPR:
case IMPLICIT_CONV_EXPR:
@@ -10520,11 +10545,6 @@ for_each_template_parm_r (tree *tp, int *walk_subtrees, void *d)
return error_mark_node;
break;
- case SCOPE_REF:
- if (pfd->include_nondeduced_p)
- WALK_SUBTREE (TREE_OPERAND (t, 0));
- break;
-
case REQUIRES_EXPR:
{
if (!fn)
@@ -10721,28 +10741,11 @@ any_template_parm_r (tree t, void *data)
break;
case TEMPLATE_DECL:
- {
- /* If T is a member template that shares template parameters with
- ctx_parms, we need to mark all those parameters for mapping. */
- tree dparms = DECL_TEMPLATE_PARMS (t);
- tree cparms = ftpi->ctx_parms;
- while (TMPL_PARMS_DEPTH (dparms) > ftpi->max_depth)
- dparms = TREE_CHAIN (dparms);
- while (TMPL_PARMS_DEPTH (cparms) > TMPL_PARMS_DEPTH (dparms))
- cparms = TREE_CHAIN (cparms);
- while (dparms
- && (TREE_TYPE (TREE_VALUE (dparms))
- != TREE_TYPE (TREE_VALUE (cparms))))
- dparms = TREE_CHAIN (dparms),
- cparms = TREE_CHAIN (cparms);
- if (dparms)
- {
- int ddepth = TMPL_PARMS_DEPTH (dparms);
- tree dargs = TI_ARGS (get_template_info (DECL_TEMPLATE_RESULT (t)));
- for (int i = 0; i < ddepth; ++i)
- WALK_SUBTREE (TMPL_ARGS_LEVEL (dargs, i+1));
- }
- }
+ /* If T is a member template that shares template parameters with
+ ctx_parms, we need to mark all those parameters for mapping.
+ To that end, it should suffice to just walk the DECL_CONTEXT of
+ the template (assuming the template is not overly general). */
+ WALK_SUBTREE (DECL_CONTEXT (t));
break;
case LAMBDA_EXPR:
@@ -10857,11 +10860,27 @@ uses_outer_template_parms (tree decl)
&depth, NULL, /*include_nondeduced_p=*/true))
return true;
if (PRIMARY_TEMPLATE_P (decl)
- && for_each_template_parm (INNERMOST_TEMPLATE_PARMS
- (DECL_TEMPLATE_PARMS (decl)),
- template_parm_outer_level,
- &depth, NULL, /*include_nondeduced_p=*/true))
- return true;
+ || DECL_TEMPLATE_TEMPLATE_PARM_P (decl))
+ {
+ tree parms = INNERMOST_TEMPLATE_PARMS (DECL_TEMPLATE_PARMS (decl));
+ for (int i = TREE_VEC_LENGTH (parms) - 1; i >= 0; --i)
+ {
+ tree parm = TREE_VALUE (TREE_VEC_ELT (parms, i));
+ tree defarg = TREE_PURPOSE (TREE_VEC_ELT (parms, i));
+ if (TREE_CODE (parm) == PARM_DECL
+ && for_each_template_parm (TREE_TYPE (parm),
+ template_parm_outer_level,
+ &depth, NULL, /*nondeduced*/true))
+ return true;
+ if (TREE_CODE (parm) == TEMPLATE_DECL
+ && uses_outer_template_parms (parm))
+ return true;
+ if (defarg
+ && for_each_template_parm (defarg, template_parm_outer_level,
+ &depth, NULL, /*nondeduced*/true))
+ return true;
+ }
+ }
tree ci = get_constraints (decl);
if (ci)
ci = CI_ASSOCIATED_CONSTRAINTS (ci);
@@ -10880,7 +10899,8 @@ neglectable_inst_p (tree d)
{
return (d && DECL_P (d)
&& !undeduced_auto_decl (d)
- && !(TREE_CODE (d) == FUNCTION_DECL ? DECL_DECLARED_CONSTEXPR_P (d)
+ && !(TREE_CODE (d) == FUNCTION_DECL
+ ? FNDECL_MANIFESTLY_CONST_EVALUATED (d)
: decl_maybe_constant_var_p (d)));
}
@@ -10892,14 +10912,31 @@ limit_bad_template_recursion (tree decl)
{
struct tinst_level *lev = current_tinst_level;
int errs = errorcount + sorrycount;
- if (lev == NULL || errs == 0 || !neglectable_inst_p (decl))
+ if (errs == 0 || !neglectable_inst_p (decl))
return false;
- for (; lev; lev = lev->next)
- if (neglectable_inst_p (lev->maybe_get_node ()))
- break;
+ /* Avoid instantiating members of an ill-formed class. */
+ bool refuse
+ = (DECL_CLASS_SCOPE_P (decl)
+ && CLASSTYPE_ERRONEOUS (DECL_CONTEXT (decl)));
- return (lev && errs > lev->errors);
+ if (!refuse)
+ {
+ for (; lev; lev = lev->next)
+ if (neglectable_inst_p (lev->maybe_get_node ()))
+ break;
+ refuse = (lev && errs > lev->errors);
+ }
+
+ if (refuse)
+ {
+ /* Don't warn about it not being defined. */
+ suppress_warning (decl, OPT_Wunused);
+ tree clone;
+ FOR_EACH_CLONE (clone, decl)
+ suppress_warning (clone, OPT_Wunused);
+ }
+ return refuse;
}
static int tinst_depth;
@@ -10932,9 +10969,9 @@ push_tinst_level_loc (tree tldcl, tree targs, location_t loc)
constant expressions. */
if (!targs && limit_bad_template_recursion (tldcl))
{
- /* Avoid no_linkage_errors and unused function warnings for this
- decl. */
- TREE_NO_WARNING (tldcl) = 1;
+ /* Avoid no_linkage_errors and unused function (and all other)
+ warnings for this decl. */
+ suppress_warning (tldcl);
return false;
}
@@ -11630,7 +11667,6 @@ static bool
apply_late_template_attributes (tree *decl_p, tree attributes, int attr_flags,
tree args, tsubst_flags_t complain, tree in_decl)
{
- tree last_dep = NULL_TREE;
tree t;
tree *p;
@@ -11656,39 +11692,35 @@ apply_late_template_attributes (tree *decl_p, tree attributes, int attr_flags,
p = &TREE_CHAIN (*p);
}
+ /* save_template_attributes puts the dependent attributes at the beginning of
+ the list; find the non-dependent ones. */
for (t = attributes; t; t = TREE_CHAIN (t))
- if (ATTR_IS_DEPENDENT (t))
- {
- last_dep = t;
- attributes = copy_list (attributes);
- break;
- }
+ if (!ATTR_IS_DEPENDENT (t))
+ break;
+ tree nondep = t;
- *p = attributes;
- if (last_dep)
- {
- tree late_attrs = NULL_TREE;
- tree *q = &late_attrs;
+ /* Apply any non-dependent attributes. */
+ *p = nondep;
- for (; *p; )
+ /* And then any dependent ones. */
+ tree late_attrs = NULL_TREE;
+ tree *q = &late_attrs;
+ for (t = attributes; t != nondep; t = TREE_CHAIN (t))
+ {
+ *q = tsubst_attribute (t, decl_p, args, complain, in_decl);
+ if (*q == error_mark_node)
+ return false;
+ if (*q == t)
{
- t = *p;
- if (ATTR_IS_DEPENDENT (t))
- {
- *q = tsubst_attribute (t, decl_p, args, complain, in_decl);
- if (*q == error_mark_node)
- return false;
- *p = TREE_CHAIN (t);
- TREE_CHAIN (t) = NULL_TREE;
- while (*q)
- q = &TREE_CHAIN (*q);
- }
- else
- p = &TREE_CHAIN (t);
+ *q = copy_node (t);
+ TREE_CHAIN (*q) = NULL_TREE;
}
-
- cplus_decl_attributes (decl_p, late_attrs, attr_flags);
+ while (*q)
+ q = &TREE_CHAIN (*q);
}
+
+ cplus_decl_attributes (decl_p, late_attrs, attr_flags);
+
return true;
}
@@ -12224,6 +12256,13 @@ instantiate_class_template_1 (tree type)
finish_struct_1 (type);
TYPE_BEING_DEFINED (type) = 0;
+ /* Remember if instantiating this class ran into errors, so we can avoid
+ instantiating member functions in limit_bad_template_recursion. We set
+ this flag even if the problem was in another instantiation triggered by
+ this one, as that will likely also cause trouble for member functions. */
+ if (errorcount + sorrycount > current_tinst_level->errors)
+ CLASSTYPE_ERRONEOUS (type) = true;
+
/* We don't instantiate default arguments for member functions. 14.7.1:
The implicit instantiation of a class template specialization causes
@@ -12392,10 +12431,15 @@ make_argument_pack_select (tree arg_pack, unsigned index)
substitution. */
static bool
-use_pack_expansion_extra_args_p (tree parm_packs,
+use_pack_expansion_extra_args_p (tree t,
+ tree parm_packs,
int arg_pack_len,
bool has_empty_arg)
{
+ if (has_empty_arg
+ && PACK_EXPANSION_FORCE_EXTRA_ARGS_P (t))
+ return true;
+
/* If one pack has an expansion and another pack has a normal
argument or if one pack has an empty argument and an another
one hasn't then tsubst_pack_expansion cannot perform the
@@ -12422,9 +12466,9 @@ use_pack_expansion_extra_args_p (tree parm_packs,
return false;
}
- bool has_expansion_arg = false;
for (int i = 0 ; i < arg_pack_len; ++i)
{
+ bool has_expansion_arg = false;
bool has_non_expansion_arg = false;
for (tree parm_pack = parm_packs;
parm_pack;
@@ -12444,7 +12488,10 @@ use_pack_expansion_extra_args_p (tree parm_packs,
}
if (has_expansion_arg && has_non_expansion_arg)
- return true;
+ {
+ gcc_checking_assert (false);
+ return true;
+ }
}
return false;
}
@@ -12784,7 +12831,11 @@ tsubst_binary_right_fold (tree t, tree args, tsubst_flags_t complain,
class el_data
{
public:
+ /* Set of variables declared within the pattern. */
hash_set<tree> internal;
+ /* Set of AST nodes that have been visited by the traversal. */
+ hash_set<tree> visited;
+ /* List of local_specializations used within the pattern. */
tree extra;
tsubst_flags_t complain;
@@ -12803,7 +12854,36 @@ extract_locals_r (tree *tp, int */*walk_subtrees*/, void *data_)
tp = &TYPE_NAME (*tp);
if (TREE_CODE (*tp) == DECL_EXPR)
- data.internal.add (DECL_EXPR_DECL (*tp));
+ {
+ tree decl = DECL_EXPR_DECL (*tp);
+ data.internal.add (decl);
+ if (VAR_P (decl)
+ && DECL_DECOMPOSITION_P (decl)
+ && TREE_TYPE (decl) != error_mark_node)
+ {
+ gcc_assert (DECL_NAME (decl) == NULL_TREE);
+ for (tree decl2 = DECL_CHAIN (decl);
+ decl2
+ && VAR_P (decl2)
+ && DECL_DECOMPOSITION_P (decl2)
+ && DECL_NAME (decl2)
+ && TREE_TYPE (decl2) != error_mark_node;
+ decl2 = DECL_CHAIN (decl2))
+ {
+ gcc_assert (DECL_DECOMP_BASE (decl2) == decl);
+ data.internal.add (decl2);
+ }
+ }
+ }
+ else if (TREE_CODE (*tp) == LAMBDA_EXPR)
+ {
+ /* Since we defer implicit capture, look in the parms and body. */
+ tree fn = lambda_function (*tp);
+ cp_walk_tree (&TREE_TYPE (fn), &extract_locals_r, &data,
+ &data.visited);
+ cp_walk_tree (&DECL_SAVED_TREE (fn), &extract_locals_r, &data,
+ &data.visited);
+ }
else if (tree spec = retrieve_local_specialization (*tp))
{
if (data.internal.contains (*tp))
@@ -12860,7 +12940,7 @@ static tree
extract_local_specs (tree pattern, tsubst_flags_t complain)
{
el_data data (complain);
- cp_walk_tree_without_duplicates (&pattern, extract_locals_r, &data);
+ cp_walk_tree (&pattern, extract_locals_r, &data, &data.visited);
return data.extra;
}
@@ -12870,7 +12950,9 @@ extract_local_specs (tree pattern, tsubst_flags_t complain)
tree
build_extra_args (tree pattern, tree args, tsubst_flags_t complain)
{
- tree extra = args;
+ /* Make a copy of the extra arguments so that they won't get changed
+ out from under us. */
+ tree extra = copy_template_args (args);
if (local_specializations)
if (tree locals = extract_local_specs (pattern, complain))
extra = tree_cons (NULL_TREE, extra, locals);
@@ -12881,7 +12963,7 @@ build_extra_args (tree pattern, tree args, tsubst_flags_t complain)
normal template args to ARGS. */
tree
-add_extra_args (tree extra, tree args)
+add_extra_args (tree extra, tree args, tsubst_flags_t complain, tree in_decl)
{
if (extra && TREE_CODE (extra) == TREE_LIST)
{
@@ -12901,20 +12983,14 @@ add_extra_args (tree extra, tree args)
gcc_assert (!TREE_PURPOSE (extra));
extra = TREE_VALUE (extra);
}
-#if 1
- /* I think we should always be able to substitute dependent args into the
- pattern. If that turns out to be incorrect in some cases, enable the
- alternate code (and add complain/in_decl parms to this function). */
- gcc_checking_assert (!uses_template_parms (extra));
-#else
- if (!uses_template_parms (extra))
+ if (uses_template_parms (extra))
{
- gcc_unreachable ();
+ /* This can happen after dependent substitution into a
+ requires-expr or a lambda that uses constexpr if. */
extra = tsubst_template_args (extra, args, complain, in_decl);
args = add_outermost_template_args (args, extra);
}
else
-#endif
args = add_to_template_args (extra, args);
return args;
}
@@ -12940,7 +13016,7 @@ tsubst_pack_expansion (tree t, tree args, tsubst_flags_t complain,
pattern = PACK_EXPANSION_PATTERN (t);
/* Add in any args remembered from an earlier partial instantiation. */
- args = add_extra_args (PACK_EXPANSION_EXTRA_ARGS (t), args);
+ args = add_extra_args (PACK_EXPANSION_EXTRA_ARGS (t), args, complain, in_decl);
levels = TMPL_ARGS_DEPTH (args);
@@ -13116,7 +13192,7 @@ tsubst_pack_expansion (tree t, tree args, tsubst_flags_t complain,
/* We cannot expand this expansion expression, because we don't have
all of the argument packs we need. */
- if (use_pack_expansion_extra_args_p (packs, len, unsubstituted_packs))
+ if (use_pack_expansion_extra_args_p (t, packs, len, unsubstituted_packs))
{
/* We got some full packs, but we can't substitute them in until we
have values for all the packs. So remember these until then. */
@@ -13141,12 +13217,25 @@ tsubst_pack_expansion (tree t, tree args, tsubst_flags_t complain,
pattern and return a PACK_EXPANSION_*. The caller will need to
deal with that. */
if (TREE_CODE (t) == EXPR_PACK_EXPANSION)
- t = tsubst_expr (pattern, args, complain, in_decl,
+ result = tsubst_expr (pattern, args, complain, in_decl,
/*integral_constant_expression_p=*/false);
else
- t = tsubst (pattern, args, complain, in_decl);
- t = make_pack_expansion (t, complain);
- return t;
+ result = tsubst (pattern, args, complain, in_decl);
+ result = make_pack_expansion (result, complain);
+ PACK_EXPANSION_LOCAL_P (result) = PACK_EXPANSION_LOCAL_P (t);
+ PACK_EXPANSION_SIZEOF_P (result) = PACK_EXPANSION_SIZEOF_P (t);
+ if (PACK_EXPANSION_AUTO_P (t))
+ {
+ /* This is a fake auto... pack expansion created in add_capture with
+ _PACKS that don't appear in the pattern. Copy one over. */
+ packs = PACK_EXPANSION_PARAMETER_PACKS (t);
+ pack = retrieve_local_specialization (TREE_VALUE (packs));
+ gcc_checking_assert (DECL_PACK_P (pack));
+ PACK_EXPANSION_PARAMETER_PACKS (result)
+ = build_tree_list (NULL_TREE, pack);
+ PACK_EXPANSION_AUTO_P (result) = true;
+ }
+ return result;
}
gcc_assert (len >= 0);
@@ -13206,36 +13295,6 @@ tsubst_pack_expansion (tree t, tree args, tsubst_flags_t complain,
return result;
}
-/* Given PARM_DECL PARM, find the corresponding PARM_DECL in the template
- TMPL. We do this using DECL_PARM_INDEX, which should work even with
- parameter packs; all parms generated from a function parameter pack will
- have the same DECL_PARM_INDEX. */
-
-tree
-get_pattern_parm (tree parm, tree tmpl)
-{
- tree pattern = DECL_TEMPLATE_RESULT (tmpl);
- tree patparm;
-
- if (DECL_ARTIFICIAL (parm))
- {
- for (patparm = DECL_ARGUMENTS (pattern);
- patparm; patparm = DECL_CHAIN (patparm))
- if (DECL_ARTIFICIAL (patparm)
- && DECL_NAME (parm) == DECL_NAME (patparm))
- break;
- }
- else
- {
- patparm = FUNCTION_FIRST_USER_PARM (DECL_TEMPLATE_RESULT (tmpl));
- patparm = chain_index (DECL_PARM_INDEX (parm)-1, patparm);
- gcc_assert (DECL_PARM_INDEX (patparm)
- == DECL_PARM_INDEX (parm));
- }
-
- return patparm;
-}
-
/* Make an argument pack out of the TREE_VEC VEC. */
static tree
@@ -13329,7 +13388,9 @@ tsubst_template_args (tree t, tree args, tsubst_flags_t complain, tree in_decl)
tree orig_arg = TREE_VEC_ELT (t, i);
tree new_arg;
- if (TREE_CODE (orig_arg) == TREE_VEC)
+ if (!orig_arg)
+ new_arg = NULL_TREE;
+ else if (TREE_CODE (orig_arg) == TREE_VEC)
new_arg = tsubst_template_args (orig_arg, args, complain, in_decl);
else if (PACK_EXPANSION_P (orig_arg))
{
@@ -13379,8 +13440,9 @@ tsubst_template_args (tree t, tree args, tsubst_flags_t complain, tree in_decl)
}
for (i = 0, out = 0; i < len; i++)
{
- if ((PACK_EXPANSION_P (TREE_VEC_ELT (orig_t, i))
- || ARGUMENT_PACK_P (TREE_VEC_ELT (orig_t, i)))
+ tree orig_arg = TREE_VEC_ELT (orig_t, i);
+ if (orig_arg
+ && (PACK_EXPANSION_P (orig_arg) || ARGUMENT_PACK_P (orig_arg))
&& TREE_CODE (elts[i]) == TREE_VEC)
{
int idx;
@@ -13887,45 +13949,6 @@ tsubst_function_decl (tree t, tree args, tsubst_flags_t complain,
if (tree spec = retrieve_specialization (gen_tmpl, argvec, hash))
return spec;
}
-
- /* We can see more levels of arguments than parameters if
- there was a specialization of a member template, like
- this:
-
- template <class T> struct S { template <class U> void f(); }
- template <> template <class U> void S<int>::f(U);
-
- Here, we'll be substituting into the specialization,
- because that's where we can find the code we actually
- want to generate, but we'll have enough arguments for
- the most general template.
-
- We also deal with the peculiar case:
-
- template <class T> struct S {
- template <class U> friend void f();
- };
- template <class U> void f() {}
- template S<int>;
- template void f<double>();
-
- Here, the ARGS for the instantiation of will be {int,
- double}. But, we only need as many ARGS as there are
- levels of template parameters in CODE_PATTERN. We are
- careful not to get fooled into reducing the ARGS in
- situations like:
-
- template <class T> struct S { template <class U> void f(U); }
- template <class T> template <> void S<T>::f(int) {}
-
- which we can spot because the pattern will be a
- specialization in this case. */
- int args_depth = TMPL_ARGS_DEPTH (args);
- int parms_depth =
- TMPL_PARMS_DEPTH (DECL_TEMPLATE_PARMS (DECL_TI_TEMPLATE (t)));
-
- if (args_depth > parms_depth && !DECL_TEMPLATE_SPECIALIZATION (t))
- args = get_innermost_template_args (args, parms_depth);
}
else
{
@@ -14060,10 +14083,7 @@ tsubst_function_decl (tree t, tree args, tsubst_flags_t complain,
don't substitute through the constraints; that's only done when
they are checked. */
if (tree ci = get_constraints (t))
- /* Unless we're regenerating a lambda, in which case we'll set the
- lambda's constraints in tsubst_lambda_expr. */
- if (!lambda_fntype)
- set_constraints (r, ci);
+ set_constraints (r, ci);
if (DECL_FRIEND_CONTEXT (t))
SET_DECL_FRIEND_CONTEXT (r,
@@ -14297,8 +14317,7 @@ tsubst_template_decl (tree t, tree args, tsubst_flags_t complain,
}
else
{
- if (TREE_CODE (decl) != TYPE_DECL || !TYPE_DECL_ALIAS_P (decl))
- DECL_TI_TEMPLATE (inner) = r;
+ DECL_TI_TEMPLATE (inner) = r;
DECL_TI_ARGS (r) = DECL_TI_ARGS (inner);
}
@@ -14311,17 +14330,13 @@ tsubst_template_decl (tree t, tree args, tsubst_flags_t complain,
/* Propagate module information from the decl. */
DECL_MODULE_EXPORT_P (r) = DECL_MODULE_EXPORT_P (inner);
if (DECL_LANG_SPECIFIC (inner))
- {
- DECL_MODULE_PURVIEW_P (r) = DECL_MODULE_PURVIEW_P (inner);
- /* If this is a constrained template, the above tsubst of
- inner can find the unconstrained template, which may have
- come from an import. This is ok, because we don't
- register this instantiation (see below). */
- gcc_checking_assert (!DECL_MODULE_IMPORT_P (inner)
- || (TEMPLATE_PARMS_CONSTRAINTS
- (DECL_TEMPLATE_PARMS (t))));
- DECL_MODULE_IMPORT_P (r) = false;
- }
+ /* If this is a constrained template, the above tsubst of
+ inner can find the unconstrained template, which may have
+ come from an import. This is ok, because we don't
+ register this instantiation (see below). */
+ gcc_checking_assert (!DECL_MODULE_IMPORT_P (inner)
+ || (TEMPLATE_PARMS_CONSTRAINTS
+ (DECL_TEMPLATE_PARMS (t))));
}
DECL_TEMPLATE_INSTANTIATIONS (r) = NULL_TREE;
@@ -14354,52 +14369,43 @@ lambda_fn_in_template_p (tree fn)
which the above is true. */
bool
-instantiated_lambda_fn_p (tree fn)
+regenerated_lambda_fn_p (tree fn)
{
if (!fn || !LAMBDA_FUNCTION_P (fn))
return false;
tree closure = DECL_CONTEXT (fn);
tree lam = CLASSTYPE_LAMBDA_EXPR (closure);
- return LAMBDA_EXPR_INSTANTIATED (lam);
+ return LAMBDA_EXPR_REGEN_INFO (lam) != NULL_TREE;
+}
+
+/* Return the LAMBDA_EXPR from which T was ultimately regenerated.
+ If T is not a regenerated LAMBDA_EXPR, return T. */
+
+tree
+most_general_lambda (tree t)
+{
+ while (tree ti = LAMBDA_EXPR_REGEN_INFO (t))
+ t = TI_TEMPLATE (ti);
+ return t;
}
/* We're instantiating a variable from template function TCTX. Return the
- corresponding current enclosing scope. This gets complicated because lambda
- functions in templates are regenerated rather than instantiated, but generic
- lambda functions are subsequently instantiated. */
+ corresponding current enclosing scope. We can match them up using
+ DECL_SOURCE_LOCATION because lambdas only ever have one source location, and
+ the DECL_SOURCE_LOCATION for a function instantiation is updated to match
+ the template definition in regenerate_decl_from_template. */
static tree
-enclosing_instantiation_of (tree otctx)
+enclosing_instantiation_of (tree tctx)
{
- tree tctx = otctx;
tree fn = current_function_decl;
- int lambda_count = 0;
- for (; tctx && (lambda_fn_in_template_p (tctx)
- || instantiated_lambda_fn_p (tctx));
- tctx = decl_function_context (tctx))
- ++lambda_count;
+ /* We shouldn't ever need to do this for other artificial functions. */
+ gcc_assert (!DECL_ARTIFICIAL (tctx) || LAMBDA_FUNCTION_P (tctx));
+
for (; fn; fn = decl_function_context (fn))
- {
- tree ofn = fn;
- int flambda_count = 0;
- for (; fn && instantiated_lambda_fn_p (fn);
- fn = decl_function_context (fn))
- ++flambda_count;
- if ((fn && DECL_TEMPLATE_INFO (fn))
- ? most_general_template (fn) != most_general_template (tctx)
- : fn != tctx)
- continue;
- if (flambda_count != lambda_count)
- {
- gcc_assert (flambda_count > lambda_count);
- for (; flambda_count > lambda_count; --flambda_count)
- ofn = decl_function_context (ofn);
- }
- gcc_assert (DECL_NAME (ofn) == DECL_NAME (otctx)
- || DECL_CONV_FN_P (ofn));
- return ofn;
- }
+ if (DECL_SOURCE_LOCATION (fn) == DECL_SOURCE_LOCATION (tctx))
+ return fn;
gcc_unreachable ();
}
@@ -14979,20 +14985,13 @@ tsubst_arg_types (tree arg_types,
tsubst_flags_t complain,
tree in_decl)
{
- tree remaining_arg_types;
tree type = NULL_TREE;
- int i = 1;
+ int len = 1;
tree expanded_args = NULL_TREE;
- tree default_arg;
if (!arg_types || arg_types == void_list_node || arg_types == end)
return arg_types;
- remaining_arg_types = tsubst_arg_types (TREE_CHAIN (arg_types),
- args, end, complain, in_decl);
- if (remaining_arg_types == error_mark_node)
- return error_mark_node;
-
if (PACK_EXPANSION_P (TREE_VALUE (arg_types)))
{
/* For a pack expansion, perform substitution on the
@@ -15003,7 +15002,7 @@ tsubst_arg_types (tree arg_types,
if (TREE_CODE (expanded_args) == TREE_VEC)
/* So that we'll spin through the parameters, one by one. */
- i = TREE_VEC_LENGTH (expanded_args);
+ len = TREE_VEC_LENGTH (expanded_args);
else
{
/* We only partially substituted into the parameter
@@ -15012,59 +15011,71 @@ tsubst_arg_types (tree arg_types,
expanded_args = NULL_TREE;
}
}
+ else
+ type = tsubst (TREE_VALUE (arg_types), args, complain, in_decl);
- while (i > 0) {
- --i;
-
- if (expanded_args)
- type = TREE_VEC_ELT (expanded_args, i);
- else if (!type)
- type = tsubst (TREE_VALUE (arg_types), args, complain, in_decl);
+ /* Check if a substituted type is erroneous before substituting into
+ the rest of the chain. */
+ for (int i = 0; i < len; i++)
+ {
+ if (expanded_args)
+ type = TREE_VEC_ELT (expanded_args, i);
- if (type == error_mark_node)
- return error_mark_node;
- if (VOID_TYPE_P (type))
- {
- if (complain & tf_error)
- {
- error ("invalid parameter type %qT", type);
- if (in_decl)
- error ("in declaration %q+D", in_decl);
- }
- return error_mark_node;
+ if (type == error_mark_node)
+ return error_mark_node;
+ if (VOID_TYPE_P (type))
+ {
+ if (complain & tf_error)
+ {
+ error ("invalid parameter type %qT", type);
+ if (in_decl)
+ error ("in declaration %q+D", in_decl);
+ }
+ return error_mark_node;
+ }
}
- /* Do array-to-pointer, function-to-pointer conversion, and ignore
- top-level qualifiers as required. */
- type = cv_unqualified (type_decays_to (type));
+ /* We do not substitute into default arguments here. The standard
+ mandates that they be instantiated only when needed, which is
+ done in build_over_call. */
+ tree default_arg = TREE_PURPOSE (arg_types);
+
+ /* Except that we do substitute default arguments under tsubst_lambda_expr,
+ since the new op() won't have any associated template arguments for us
+ to refer to later. */
+ if (lambda_fn_in_template_p (in_decl))
+ default_arg = tsubst_copy_and_build (default_arg, args, complain, in_decl,
+ false/*fn*/, false/*constexpr*/);
+
+ tree remaining_arg_types = tsubst_arg_types (TREE_CHAIN (arg_types),
+ args, end, complain, in_decl);
+ if (remaining_arg_types == error_mark_node)
+ return error_mark_node;
- /* We do not substitute into default arguments here. The standard
- mandates that they be instantiated only when needed, which is
- done in build_over_call. */
- default_arg = TREE_PURPOSE (arg_types);
+ for (int i = len-1; i >= 0; i--)
+ {
+ if (expanded_args)
+ type = TREE_VEC_ELT (expanded_args, i);
- /* Except that we do substitute default arguments under tsubst_lambda_expr,
- since the new op() won't have any associated template arguments for us
- to refer to later. */
- if (lambda_fn_in_template_p (in_decl))
- default_arg = tsubst_copy_and_build (default_arg, args, complain, in_decl,
- false/*fn*/, false/*constexpr*/);
+ /* Do array-to-pointer, function-to-pointer conversion, and ignore
+ top-level qualifiers as required. */
+ type = cv_unqualified (type_decays_to (type));
- if (default_arg && TREE_CODE (default_arg) == DEFERRED_PARSE)
- {
- /* We've instantiated a template before its default arguments
- have been parsed. This can happen for a nested template
- class, and is not an error unless we require the default
- argument in a call of this function. */
- remaining_arg_types =
- tree_cons (default_arg, type, remaining_arg_types);
- vec_safe_push (DEFPARSE_INSTANTIATIONS (default_arg),
- remaining_arg_types);
- }
- else
- remaining_arg_types =
- hash_tree_cons (default_arg, type, remaining_arg_types);
- }
+ if (default_arg && TREE_CODE (default_arg) == DEFERRED_PARSE)
+ {
+ /* We've instantiated a template before its default arguments
+ have been parsed. This can happen for a nested template
+ class, and is not an error unless we require the default
+ argument in a call of this function. */
+ remaining_arg_types
+ = tree_cons (default_arg, type, remaining_arg_types);
+ vec_safe_push (DEFPARSE_INSTANTIATIONS (default_arg),
+ remaining_arg_types);
+ }
+ else
+ remaining_arg_types
+ = hash_tree_cons (default_arg, type, remaining_arg_types);
+ }
return remaining_arg_types;
}
@@ -16270,8 +16281,19 @@ tsubst_baselink (tree baselink, tree object_type,
fns = BASELINK_FUNCTIONS (baselink);
}
else
- /* We're going to overwrite pieces below, make a duplicate. */
- baselink = copy_node (baselink);
+ {
+ /* We're going to overwrite pieces below, make a duplicate. */
+ baselink = copy_node (baselink);
+
+ if (qualifying_scope != BINFO_TYPE (BASELINK_ACCESS_BINFO (baselink)))
+ {
+ /* The decl we found was from non-dependent scope, but we still need
+ to update the binfos for the instantiated qualifying_scope. */
+ BASELINK_ACCESS_BINFO (baselink) = TYPE_BINFO (qualifying_scope);
+ BASELINK_BINFO (baselink) = lookup_base (qualifying_scope, binfo_type,
+ ba_unique, nullptr, complain);
+ }
+ }
/* If lookup found a single function, mark it as used at this point.
(If lookup found multiple functions the one selected later by
@@ -17083,7 +17105,7 @@ tsubst_copy (tree t, tree args, tsubst_flags_t complain, tree in_decl)
tree op1 = tsubst_copy (TREE_OPERAND (t, 1), args, complain, in_decl);
tree op2 = tsubst_copy (TREE_OPERAND (t, 2), args, complain, in_decl);
r = build_nt (code, op0, op1, op2);
- TREE_NO_WARNING (r) = TREE_NO_WARNING (t);
+ copy_warning (r, t);
return r;
}
@@ -17397,6 +17419,7 @@ tsubst_omp_clauses (tree clauses, enum c_omp_region_type ort,
case OMP_CLAUSE_COPYPRIVATE:
case OMP_CLAUSE_UNIFORM:
case OMP_CLAUSE_DEPEND:
+ case OMP_CLAUSE_AFFINITY:
case OMP_CLAUSE_FROM:
case OMP_CLAUSE_TO:
case OMP_CLAUSE_MAP:
@@ -17428,6 +17451,7 @@ tsubst_omp_clauses (tree clauses, enum c_omp_region_type ort,
case OMP_CLAUSE_PRIORITY:
case OMP_CLAUSE_ORDERED:
case OMP_CLAUSE_HINT:
+ case OMP_CLAUSE_FILTER:
case OMP_CLAUSE_NUM_GANGS:
case OMP_CLAUSE_NUM_WORKERS:
case OMP_CLAUSE_VECTOR_LENGTH:
@@ -17513,6 +17537,7 @@ tsubst_omp_clauses (tree clauses, enum c_omp_region_type ort,
case OMP_CLAUSE_SEQ:
case OMP_CLAUSE_IF_PRESENT:
case OMP_CLAUSE_FINALIZE:
+ case OMP_CLAUSE_NOHOST:
break;
default:
gcc_unreachable ();
@@ -18150,9 +18175,8 @@ tsubst_expr (tree t, tree args, tsubst_flags_t complain, tree in_decl,
{
case STATEMENT_LIST:
{
- tree_stmt_iterator i;
- for (i = tsi_start (t); !tsi_end_p (i); tsi_next (&i))
- RECUR (tsi_stmt (i));
+ for (tree stmt : tsi_range (t))
+ RECUR (stmt);
break;
}
@@ -18446,8 +18470,9 @@ tsubst_expr (tree t, tree args, tsubst_flags_t complain, tree in_decl,
case IF_STMT:
stmt = begin_if_stmt ();
IF_STMT_CONSTEXPR_P (stmt) = IF_STMT_CONSTEXPR_P (t);
+ IF_STMT_CONSTEVAL_P (stmt) = IF_STMT_CONSTEVAL_P (t);
if (IF_STMT_CONSTEXPR_P (t))
- args = add_extra_args (IF_STMT_EXTRA_ARGS (t), args);
+ args = add_extra_args (IF_STMT_EXTRA_ARGS (t), args, complain, in_decl);
tmp = RECUR (IF_COND (t));
tmp = finish_if_stmt_cond (tmp, stmt);
if (IF_STMT_CONSTEXPR_P (t)
@@ -18466,6 +18491,13 @@ tsubst_expr (tree t, tree args, tsubst_flags_t complain, tree in_decl,
}
if (IF_STMT_CONSTEXPR_P (t) && integer_zerop (tmp))
/* Don't instantiate the THEN_CLAUSE. */;
+ else if (IF_STMT_CONSTEVAL_P (t))
+ {
+ bool save_in_consteval_if_p = in_consteval_if_p;
+ in_consteval_if_p = true;
+ RECUR (THEN_CLAUSE (t));
+ in_consteval_if_p = save_in_consteval_if_p;
+ }
else
{
tree folded = fold_non_dependent_expr (tmp, complain);
@@ -18812,9 +18844,11 @@ tsubst_expr (tree t, tree args, tsubst_flags_t complain, tree in_decl,
break;
case OMP_SECTIONS:
+ case OMP_MASKED:
omp_parallel_combined_clauses = NULL;
/* FALLTHRU */
case OMP_SINGLE:
+ case OMP_SCOPE:
case OMP_TEAMS:
case OMP_CRITICAL:
case OMP_TASKGROUP:
@@ -18882,9 +18916,12 @@ tsubst_expr (tree t, tree args, tsubst_flags_t complain, tree in_decl,
case OACC_DATA:
case OMP_TARGET_DATA:
case OMP_TARGET:
- tmp = tsubst_omp_clauses (OMP_CLAUSES (t), (TREE_CODE (t) == OACC_DATA)
- ? C_ORT_ACC : C_ORT_OMP, args, complain,
- in_decl);
+ tmp = tsubst_omp_clauses (OMP_CLAUSES (t),
+ TREE_CODE (t) == OACC_DATA
+ ? C_ORT_ACC
+ : TREE_CODE (t) == OMP_TARGET
+ ? C_ORT_OMP_TARGET : C_ORT_OMP,
+ args, complain, in_decl);
keep_next_level (true);
stmt = begin_omp_structured_block ();
@@ -19165,8 +19202,7 @@ tsubst_omp_udr (tree t, tree args, tsubst_flags_t complain, tree in_decl)
block = finish_omp_structured_block (block);
block = maybe_cleanup_point_expr_void (block);
add_decl_expr (omp_out);
- if (TREE_NO_WARNING (DECL_EXPR_DECL (stmts[0])))
- TREE_NO_WARNING (omp_out) = 1;
+ copy_warning (omp_out, DECL_EXPR_DECL (stmts[0]));
add_decl_expr (omp_in);
finish_expr_stmt (block);
}
@@ -19258,7 +19294,12 @@ tsubst_lambda_expr (tree t, tree args, tsubst_flags_t complain, tree in_decl)
LAMBDA_EXPR_DEFAULT_CAPTURE_MODE (r)
= LAMBDA_EXPR_DEFAULT_CAPTURE_MODE (t);
LAMBDA_EXPR_MUTABLE_P (r) = LAMBDA_EXPR_MUTABLE_P (t);
- LAMBDA_EXPR_INSTANTIATED (r) = true;
+ if (tree ti = LAMBDA_EXPR_REGEN_INFO (t))
+ LAMBDA_EXPR_REGEN_INFO (r)
+ = build_template_info (t, add_to_template_args (TI_ARGS (ti), args));
+ else
+ LAMBDA_EXPR_REGEN_INFO (r)
+ = build_template_info (t, args);
gcc_assert (LAMBDA_EXPR_THIS_CAPTURE (t) == NULL_TREE
&& LAMBDA_EXPR_PENDING_PROXIES (t) == NULL);
@@ -19400,17 +19441,6 @@ tsubst_lambda_expr (tree t, tree args, tsubst_flags_t complain, tree in_decl)
finish_member_declaration (fn);
}
- if (tree ci = get_constraints (oldfn))
- {
- /* Substitute into the lambda's constraints. */
- if (oldtmpl)
- ++processing_template_decl;
- ci = tsubst_constraint_info (ci, args, complain, in_decl);
- if (oldtmpl)
- --processing_template_decl;
- set_constraints (fn, ci);
- }
-
/* Let finish_function set this. */
DECL_DECLARED_CONSTEXPR_P (fn) = false;
@@ -19424,6 +19454,9 @@ tsubst_lambda_expr (tree t, tree args, tsubst_flags_t complain, tree in_decl)
local_specialization_stack s (lss_copy);
+ bool save_in_consteval_if_p = in_consteval_if_p;
+ in_consteval_if_p = false;
+
tree body = start_lambda_function (fn, r);
/* Now record them for lookup_init_capture_pack. */
@@ -19454,11 +19487,18 @@ tsubst_lambda_expr (tree t, tree args, tsubst_flags_t complain, tree in_decl)
the purposes of template argument deduction. */
complain = tf_warning_or_error;
- tsubst_expr (DECL_SAVED_TREE (oldfn), args, complain, r,
- /*constexpr*/false);
+ tree saved = DECL_SAVED_TREE (oldfn);
+ if (TREE_CODE (saved) == BIND_EXPR && BIND_EXPR_BODY_BLOCK (saved))
+ /* We already have a body block from start_lambda_function, we don't
+ need another to confuse NRV (91217). */
+ saved = BIND_EXPR_BODY (saved);
+
+ tsubst_expr (saved, args, complain, r, /*constexpr*/false);
finish_lambda_function (body);
+ in_consteval_if_p = save_in_consteval_if_p;
+
if (nested)
pop_function_context ();
else
@@ -19481,6 +19521,63 @@ out:
return r;
}
+/* Subroutine of maybe_fold_fn_template_args. */
+
+static bool
+fold_targs_r (tree targs, tsubst_flags_t complain)
+{
+ int len = TREE_VEC_LENGTH (targs);
+ for (int i = 0; i < len; ++i)
+ {
+ tree &elt = TREE_VEC_ELT (targs, i);
+ if (!elt || TYPE_P (elt)
+ || TREE_CODE (elt) == TEMPLATE_DECL)
+ continue;
+ if (TREE_CODE (elt) == NONTYPE_ARGUMENT_PACK)
+ {
+ if (!fold_targs_r (ARGUMENT_PACK_ARGS (elt), complain))
+ return false;
+ }
+ else if (/* We can only safely preevaluate scalar prvalues. */
+ SCALAR_TYPE_P (TREE_TYPE (elt))
+ && !glvalue_p (elt)
+ && !TREE_CONSTANT (elt))
+ {
+ elt = cxx_constant_value_sfinae (elt, complain);
+ if (elt == error_mark_node)
+ return false;
+ }
+ }
+
+ return true;
+}
+
+/* Try to do constant evaluation of any explicit template arguments in FN
+ before overload resolution, to get any errors only once. Return true iff
+ we didn't have any problems folding. */
+
+static bool
+maybe_fold_fn_template_args (tree fn, tsubst_flags_t complain)
+{
+ if (processing_template_decl || fn == NULL_TREE)
+ return true;
+ if (fn == error_mark_node)
+ return false;
+ if (TREE_CODE (fn) == OFFSET_REF
+ || TREE_CODE (fn) == COMPONENT_REF)
+ fn = TREE_OPERAND (fn, 1);
+ if (BASELINK_P (fn))
+ fn = BASELINK_FUNCTIONS (fn);
+ if (TREE_CODE (fn) != TEMPLATE_ID_EXPR)
+ return true;
+ tree targs = TREE_OPERAND (fn, 1);
+ if (targs == NULL_TREE)
+ return true;
+ if (targs == error_mark_node)
+ return false;
+ return fold_targs_r (targs, complain);
+}
+
/* Like tsubst but deals with expressions and performs semantic
analysis. FUNCTION_P is true if T is the "F" in "F (ARGS)" or
"F<TARGS> (ARGS)". */
@@ -19716,6 +19813,7 @@ tsubst_copy_and_build (tree t,
warning_sentinel s(warn_useless_cast);
warning_sentinel s2(warn_ignored_qualifiers);
+ warning_sentinel s3(warn_int_in_bool_context);
switch (TREE_CODE (t))
{
case CAST_EXPR:
@@ -19770,6 +19868,7 @@ tsubst_copy_and_build (tree t,
complain|decltype_flag));
case FIX_TRUNC_EXPR:
+ /* convert_like should have created an IMPLICIT_CONV_EXPR. */
gcc_unreachable ();
case ADDR_EXPR:
@@ -19817,15 +19916,21 @@ tsubst_copy_and_build (tree t,
case MEMBER_REF:
case DOTSTAR_EXPR:
{
- /* If T was type-dependent, suppress warnings that depend on the range
- of the types involved. */
- ++processing_template_decl;
- const bool was_dep = (potential_constant_expression (t)
- ? value_dependent_expression_p (t)
- : type_dependent_expression_p (t));
- --processing_template_decl;
- tree op0 = RECUR (TREE_OPERAND (t, 0));
- tree op1 = RECUR (TREE_OPERAND (t, 1));
+ /* If either OP0 or OP1 was value- or type-dependent, suppress
+ warnings that depend on the range of the types involved. */
+ tree op0 = TREE_OPERAND (t, 0);
+ tree op1 = TREE_OPERAND (t, 1);
+ auto dep_p = [](tree t) {
+ ++processing_template_decl;
+ bool r = (potential_constant_expression (t)
+ ? value_dependent_expression_p (t)
+ : type_dependent_expression_p (t));
+ --processing_template_decl;
+ return r;
+ };
+ const bool was_dep = dep_p (op0) || dep_p (op1);
+ op0 = RECUR (op0);
+ op1 = RECUR (op1);
warning_sentinel s1(warn_type_limits, was_dep);
warning_sentinel s2(warn_div_by_zero, was_dep);
@@ -19835,17 +19940,17 @@ tsubst_copy_and_build (tree t,
tree r = build_x_binary_op
(input_location, TREE_CODE (t),
op0,
- (TREE_NO_WARNING (TREE_OPERAND (t, 0))
+ (warning_suppressed_p (TREE_OPERAND (t, 0))
? ERROR_MARK
: TREE_CODE (TREE_OPERAND (t, 0))),
op1,
- (TREE_NO_WARNING (TREE_OPERAND (t, 1))
+ (warning_suppressed_p (TREE_OPERAND (t, 1))
? ERROR_MARK
: TREE_CODE (TREE_OPERAND (t, 1))),
/*overload=*/NULL,
complain|decltype_flag);
- if (EXPR_P (r) && TREE_NO_WARNING (t))
- TREE_NO_WARNING (r) = TREE_NO_WARNING (t);
+ if (EXPR_P (r))
+ copy_warning (r, t);
RETURN (r);
}
@@ -19981,8 +20086,8 @@ tsubst_copy_and_build (tree t,
set and must be copied. In the latter case,
build_x_modify_expr sets it and it must not be reset
here. */
- if (TREE_NO_WARNING (t))
- TREE_NO_WARNING (r) = TREE_NO_WARNING (t);
+ if (warning_suppressed_p (t, OPT_Wparentheses))
+ suppress_warning (r, OPT_Wparentheses);
RETURN (r);
}
@@ -20137,7 +20242,13 @@ tsubst_copy_and_build (tree t,
/* Avoid error about taking the address of a constructor. */
function = TREE_OPERAND (function, 0);
- function = tsubst_copy_and_build (function, args, complain,
+ tsubst_flags_t subcomplain = complain;
+ if (koenig_p && TREE_CODE (function) == FUNCTION_DECL)
+ /* When KOENIG_P, we don't want to mark_used the callee before
+ augmenting the overload set via ADL, so during this initial
+ substitution we disable mark_used by setting tf_conv (68942). */
+ subcomplain |= tf_conv;
+ function = tsubst_copy_and_build (function, args, subcomplain,
in_decl,
!qualified_p,
integral_constant_expression_p);
@@ -20345,6 +20456,9 @@ tsubst_copy_and_build (tree t,
&& !mark_used (function, complain) && !(complain & tf_error))
RETURN (error_mark_node);
+ if (!maybe_fold_fn_template_args (function, complain))
+ return error_mark_node;
+
/* Put back tf_decltype for the actual call. */
complain |= decltype_flag;
@@ -20383,6 +20497,15 @@ tsubst_copy_and_build (tree t,
RETURN (ret);
break;
+ case IFN_SHUFFLEVECTOR:
+ {
+ ret = build_x_shufflevector (input_location, call_args,
+ complain);
+ if (ret != error_mark_node)
+ RETURN (ret);
+ break;
+ }
+
default:
/* Unsupported internal function with arguments. */
gcc_unreachable ();
@@ -20527,7 +20650,13 @@ tsubst_copy_and_build (tree t,
if (member == error_mark_node)
RETURN (error_mark_node);
- if (TREE_CODE (member) == FIELD_DECL)
+ if (object_type && TYPE_PTRMEMFUNC_P (object_type)
+ && TREE_CODE (member) == FIELD_DECL)
+ {
+ r = build_ptrmemfunc_access_expr (object, DECL_NAME (member));
+ RETURN (r);
+ }
+ else if (TREE_CODE (member) == FIELD_DECL)
{
r = finish_non_static_data_member (member, object, NULL_TREE);
if (TREE_CODE (r) == COMPONENT_REF)
@@ -21093,7 +21222,7 @@ instantiate_template_1 (tree tmpl, tree orig_args, tsubst_flags_t complain)
/* We need to determine if we're using a partial or explicit
specialization now, because the type of the variable could be
different. */
- tree tid = lookup_template_variable (gen_tmpl, targ_ptr);
+ tree tid = lookup_template_variable (tmpl, targ_ptr);
tree elt = most_specialized_partial_spec (tid, complain);
if (elt == error_mark_node)
pattern = error_mark_node;
@@ -21693,6 +21822,41 @@ fn_type_unification (tree fn,
return r;
}
+/* Returns true iff PARM is a forwarding reference in the context of
+ template argument deduction for TMPL. */
+
+static bool
+forwarding_reference_p (tree parm, tree tmpl)
+{
+ /* [temp.deduct.call], "A forwarding reference is an rvalue reference to a
+ cv-unqualified template parameter ..." */
+ if (TYPE_REF_P (parm)
+ && TYPE_REF_IS_RVALUE (parm)
+ && TREE_CODE (TREE_TYPE (parm)) == TEMPLATE_TYPE_PARM
+ && cp_type_quals (TREE_TYPE (parm)) == TYPE_UNQUALIFIED)
+ {
+ parm = TREE_TYPE (parm);
+ /* [temp.deduct.call], "... that does not represent a template parameter
+ of a class template (during class template argument deduction)." */
+ if (tmpl
+ && deduction_guide_p (tmpl)
+ && DECL_ARTIFICIAL (tmpl))
+ {
+ /* Since the template parameters of a synthesized guide consist of
+ the template parameters of the class template followed by those of
+ the constructor (if any), we can tell if PARM represents a template
+ parameter of the class template by comparing its index with the
+ arity of the class template. */
+ tree ctmpl = CLASSTYPE_TI_TEMPLATE (TREE_TYPE (TREE_TYPE (tmpl)));
+ if (TEMPLATE_TYPE_IDX (parm)
+ < TREE_VEC_LENGTH (DECL_INNERMOST_TEMPLATE_PARMS (ctmpl)))
+ return false;
+ }
+ return true;
+ }
+ return false;
+}
+
/* Adjust types before performing type deduction, as described in
[temp.deduct.call] and [temp.deduct.conv]. The rules in these two
sections are symmetric. PARM is the type of a function parameter
@@ -21702,7 +21866,8 @@ fn_type_unification (tree fn,
ARG_EXPR is the original argument expression, which may be null. */
static int
-maybe_adjust_types_for_deduction (unification_kind_t strict,
+maybe_adjust_types_for_deduction (tree tparms,
+ unification_kind_t strict,
tree* parm,
tree* arg,
tree arg_expr)
@@ -21725,10 +21890,7 @@ maybe_adjust_types_for_deduction (unification_kind_t strict,
/* Core issue #873: Do the DR606 thing (see below) for these cases,
too, but here handle it by stripping the reference from PARM
rather than by adding it to ARG. */
- if (TYPE_REF_P (*parm)
- && TYPE_REF_IS_RVALUE (*parm)
- && TREE_CODE (TREE_TYPE (*parm)) == TEMPLATE_TYPE_PARM
- && cp_type_quals (TREE_TYPE (*parm)) == TYPE_UNQUALIFIED
+ if (forwarding_reference_p (*parm, TPARMS_PRIMARY_TEMPLATE (tparms))
&& TYPE_REF_P (*arg)
&& !TYPE_REF_IS_RVALUE (*arg))
*parm = TREE_TYPE (*parm);
@@ -21765,17 +21927,10 @@ maybe_adjust_types_for_deduction (unification_kind_t strict,
*arg = TYPE_MAIN_VARIANT (*arg);
}
- /* [14.8.2.1/3 temp.deduct.call], "A forwarding reference is an rvalue
- reference to a cv-unqualified template parameter that does not represent a
- template parameter of a class template (during class template argument
- deduction (13.3.1.8)). If P is a forwarding reference and the argument is
- an lvalue, the type "lvalue reference to A" is used in place of A for type
- deduction. */
- if (TYPE_REF_P (*parm)
- && TYPE_REF_IS_RVALUE (*parm)
- && TREE_CODE (TREE_TYPE (*parm)) == TEMPLATE_TYPE_PARM
- && !TEMPLATE_TYPE_PARM_FOR_CLASS (TREE_TYPE (*parm))
- && cp_type_quals (TREE_TYPE (*parm)) == TYPE_UNQUALIFIED
+ /* [temp.deduct.call], "If P is a forwarding reference and the argument is
+ an lvalue, the type 'lvalue reference to A' is used in place of A for
+ type deduction." */
+ if (forwarding_reference_p (*parm, TPARMS_PRIMARY_TEMPLATE (tparms))
&& (arg_expr ? lvalue_p (arg_expr)
/* try_one_overload doesn't provide an arg_expr, but
functions are always lvalues. */
@@ -21858,8 +22013,10 @@ static bool uses_deducible_template_parms (tree type);
static bool
deducible_expression (tree expr)
{
- /* Strip implicit conversions. */
- while (CONVERT_EXPR_P (expr) || TREE_CODE (expr) == VIEW_CONVERT_EXPR)
+ /* Strip implicit conversions and implicit INDIRECT_REFs. */
+ while (CONVERT_EXPR_P (expr)
+ || TREE_CODE (expr) == VIEW_CONVERT_EXPR
+ || REFERENCE_REF_P (expr))
expr = TREE_OPERAND (expr, 0);
return (TREE_CODE (expr) == TEMPLATE_PARM_INDEX);
}
@@ -22062,8 +22219,8 @@ unify_one_argument (tree tparms, tree targs, tree parm, tree arg,
return unify_invalid (explain_p);
}
- arg_strict |=
- maybe_adjust_types_for_deduction (strict, &parm, &arg, arg_expr);
+ arg_strict |= maybe_adjust_types_for_deduction (tparms, strict,
+ &parm, &arg, arg_expr);
}
else
if ((TYPE_P (parm) || TREE_CODE (parm) == TEMPLATE_DECL)
@@ -22732,7 +22889,8 @@ try_one_overload (tree tparms,
else if (addr_p)
arg = build_pointer_type (arg);
- sub_strict |= maybe_adjust_types_for_deduction (strict, &parm, &arg, NULL);
+ sub_strict |= maybe_adjust_types_for_deduction (tparms, strict,
+ &parm, &arg, NULL_TREE);
/* We don't copy orig_targs for this because if we have already deduced
some template args from previous args, unify would complain when we
@@ -23431,7 +23589,7 @@ unify (tree tparms, tree targs, tree parm, tree arg, int strict,
/* It should only be possible to get here for a call. */
gcc_assert (elt_strict & UNIFY_ALLOW_OUTER_LEVEL);
elt_strict |= maybe_adjust_types_for_deduction
- (DEDUCE_CALL, &elttype, &type, elt);
+ (tparms, DEDUCE_CALL, &elttype, &type, elt);
elt = type;
}
@@ -23564,6 +23722,10 @@ unify (tree tparms, tree targs, tree parm, tree arg, int strict,
return 1;
arg = TYPE_TI_TEMPLATE (arg);
+ if (DECL_TEMPLATE_TEMPLATE_PARM_P (arg))
+ /* If the template is a template template parameter, use the
+ TEMPLATE_TEMPLATE_PARM for matching. */
+ arg = TREE_TYPE (arg);
/* Fall through to deduce template name. */
}
@@ -24206,7 +24368,10 @@ mark_decl_instantiated (tree result, int extern_p)
DECL_COMDAT (result) = 0;
if (extern_p)
- DECL_NOT_REALLY_EXTERN (result) = 0;
+ {
+ DECL_EXTERNAL (result) = 1;
+ DECL_NOT_REALLY_EXTERN (result) = 0;
+ }
else
{
mark_definable (result);
@@ -24937,26 +25102,33 @@ most_specialized_partial_spec (tree target, tsubst_flags_t complain)
tree outer_args = NULL_TREE;
tree tmpl, args;
+ tree decl;
if (TYPE_P (target))
{
tree tinfo = CLASSTYPE_TEMPLATE_INFO (target);
tmpl = TI_TEMPLATE (tinfo);
args = TI_ARGS (tinfo);
+ decl = TYPE_NAME (target);
}
else if (TREE_CODE (target) == TEMPLATE_ID_EXPR)
{
tmpl = TREE_OPERAND (target, 0);
args = TREE_OPERAND (target, 1);
+ decl = DECL_TEMPLATE_RESULT (tmpl);
}
else if (VAR_P (target))
{
tree tinfo = DECL_TEMPLATE_INFO (target);
tmpl = TI_TEMPLATE (tinfo);
args = TI_ARGS (tinfo);
+ decl = target;
}
else
gcc_unreachable ();
+ push_access_scope_guard pas (decl);
+ deferring_access_check_sentinel acs (dk_no_deferred);
+
tree main_tmpl = most_general_template (tmpl);
/* For determining which partial specialization to use, only the
@@ -25384,12 +25556,13 @@ regenerate_decl_from_template (tree decl, tree tmpl, tree args)
if (TREE_CODE (decl) == FUNCTION_DECL)
{
- tree decl_parm;
- tree pattern_parm;
tree specs;
int args_depth;
int parms_depth;
+ /* Use the source location of the definition. */
+ DECL_SOURCE_LOCATION (decl) = DECL_SOURCE_LOCATION (tmpl);
+
args_depth = TMPL_ARGS_DEPTH (args);
parms_depth = TMPL_PARMS_DEPTH (DECL_TEMPLATE_PARMS (tmpl));
if (args_depth > parms_depth)
@@ -25409,65 +25582,18 @@ regenerate_decl_from_template (tree decl, tree tmpl, tree args)
}
/* Merge parameter declarations. */
- decl_parm = skip_artificial_parms_for (decl,
- DECL_ARGUMENTS (decl));
- pattern_parm
- = skip_artificial_parms_for (code_pattern,
- DECL_ARGUMENTS (code_pattern));
- while (decl_parm && !DECL_PACK_P (pattern_parm))
- {
- tree parm_type;
- tree attributes;
-
- if (DECL_NAME (decl_parm) != DECL_NAME (pattern_parm))
- DECL_NAME (decl_parm) = DECL_NAME (pattern_parm);
- parm_type = tsubst (TREE_TYPE (pattern_parm), args, tf_error,
- NULL_TREE);
- parm_type = type_decays_to (parm_type);
- if (!same_type_p (TREE_TYPE (decl_parm), parm_type))
- TREE_TYPE (decl_parm) = parm_type;
- attributes = DECL_ATTRIBUTES (pattern_parm);
- if (DECL_ATTRIBUTES (decl_parm) != attributes)
- {
- DECL_ATTRIBUTES (decl_parm) = attributes;
- cplus_decl_attributes (&decl_parm, attributes, /*flags=*/0);
- }
- decl_parm = DECL_CHAIN (decl_parm);
- pattern_parm = DECL_CHAIN (pattern_parm);
+ if (tree pattern_parm
+ = skip_artificial_parms_for (code_pattern,
+ DECL_ARGUMENTS (code_pattern)))
+ {
+ tree *p = &DECL_ARGUMENTS (decl);
+ for (int skip = num_artificial_parms_for (decl); skip; --skip)
+ p = &DECL_CHAIN (*p);
+ *p = tsubst_decl (pattern_parm, args, tf_error);
+ for (tree t = *p; t; t = DECL_CHAIN (t))
+ DECL_CONTEXT (t) = decl;
}
- /* Merge any parameters that match with the function parameter
- pack. */
- if (pattern_parm && DECL_PACK_P (pattern_parm))
- {
- int i, len;
- tree expanded_types;
- /* Expand the TYPE_PACK_EXPANSION that provides the types for
- the parameters in this function parameter pack. */
- expanded_types = tsubst_pack_expansion (TREE_TYPE (pattern_parm),
- args, tf_error, NULL_TREE);
- len = TREE_VEC_LENGTH (expanded_types);
- for (i = 0; i < len; i++)
- {
- tree parm_type;
- tree attributes;
-
- if (DECL_NAME (decl_parm) != DECL_NAME (pattern_parm))
- /* Rename the parameter to include the index. */
- DECL_NAME (decl_parm) =
- make_ith_pack_parameter_name (DECL_NAME (pattern_parm), i);
- parm_type = TREE_VEC_ELT (expanded_types, i);
- parm_type = type_decays_to (parm_type);
- if (!same_type_p (TREE_TYPE (decl_parm), parm_type))
- TREE_TYPE (decl_parm) = parm_type;
- attributes = DECL_ATTRIBUTES (pattern_parm);
- if (DECL_ATTRIBUTES (decl_parm) != attributes)
- {
- DECL_ATTRIBUTES (decl_parm) = attributes;
- cplus_decl_attributes (&decl_parm, attributes, /*flags=*/0);
- }
- decl_parm = DECL_CHAIN (decl_parm);
- }
- }
+
/* Merge additional specifiers from the CODE_PATTERN. */
if (DECL_DECLARED_INLINE_P (code_pattern)
&& !DECL_DECLARED_INLINE_P (decl))
@@ -26004,11 +26130,10 @@ instantiate_decl (tree d, bool defer_ok, bool expl_inst_class_mem_p)
td = template_for_substitution (d);
args = gen_args;
- if (VAR_P (d))
+ if (variable_template_specialization_p (d))
{
/* Look up an explicit specialization, if any. */
- tree tid = lookup_template_variable (gen_tmpl, gen_args);
- tree elt = most_specialized_partial_spec (tid, tf_warning_or_error);
+ tree elt = most_specialized_partial_spec (d, tf_warning_or_error);
if (elt && elt != error_mark_node)
{
td = TREE_VALUE (elt);
@@ -26338,9 +26463,16 @@ tsubst_initializer_list (tree t, tree argvec)
tree expanded_exprs;
/* Expand the argument. */
- SET_PACK_EXPANSION_PATTERN (expr, TREE_VALUE (arg));
+ tree value;
+ if (TREE_CODE (TREE_VALUE (arg)) == EXPR_PACK_EXPANSION)
+ value = TREE_VALUE (arg);
+ else
+ {
+ value = expr;
+ SET_PACK_EXPANSION_PATTERN (value, TREE_VALUE (arg));
+ }
expanded_exprs
- = tsubst_pack_expansion (expr, argvec,
+ = tsubst_pack_expansion (value, argvec,
tf_warning_or_error,
NULL_TREE);
if (expanded_exprs == error_mark_node)
@@ -26349,12 +26481,17 @@ tsubst_initializer_list (tree t, tree argvec)
/* Prepend each of the expanded expressions to the
corresponding TREE_LIST in EXPANDED_ARGUMENTS. */
for (i = 0; i < len; i++)
- {
- TREE_VEC_ELT (expanded_arguments, i) =
- tree_cons (NULL_TREE,
- TREE_VEC_ELT (expanded_exprs, i),
- TREE_VEC_ELT (expanded_arguments, i));
- }
+ if (TREE_CODE (TREE_VALUE (arg)) == EXPR_PACK_EXPANSION)
+ for (int j = 0; j < TREE_VEC_LENGTH (expanded_exprs); j++)
+ TREE_VEC_ELT (expanded_arguments, i)
+ = tree_cons (NULL_TREE,
+ TREE_VEC_ELT (expanded_exprs, j),
+ TREE_VEC_ELT (expanded_arguments, i));
+ else
+ TREE_VEC_ELT (expanded_arguments, i)
+ = tree_cons (NULL_TREE,
+ TREE_VEC_ELT (expanded_exprs, i),
+ TREE_VEC_ELT (expanded_arguments, i));
}
in_base_initializer = 0;
@@ -26437,19 +26574,6 @@ tsubst_initializer_list (tree t, tree argvec)
return inits;
}
-/* Set CURRENT_ACCESS_SPECIFIER based on the protection of DECL. */
-
-static void
-set_current_access_from_decl (tree decl)
-{
- if (TREE_PRIVATE (decl))
- current_access_specifier = access_private_node;
- else if (TREE_PROTECTED (decl))
- current_access_specifier = access_protected_node;
- else
- current_access_specifier = access_public_node;
-}
-
/* Instantiate an enumerated type. TAG is the template type, NEWTAG
is the instantiation (which should have been created with
start_enum) and ARGS are the template arguments to use. */
@@ -26575,6 +26699,8 @@ invalid_nontype_parm_type_p (tree type, tsubst_flags_t complain)
else if (cxx_dialect >= cxx11
&& TREE_CODE (type) == BOUND_TEMPLATE_TEMPLATE_PARM)
return false;
+ else if (TREE_CODE (type) == COMPLEX_TYPE)
+ /* Fall through. */;
else if (VOID_TYPE_P (type))
/* Fall through. */;
else if (cxx_dialect >= cxx20)
@@ -28219,6 +28345,11 @@ placeholder_type_constraint_dependent_p (tree t)
tree id = unpack_concept_check (t);
tree args = TREE_OPERAND (id, 1);
tree first = TREE_VEC_ELT (args, 0);
+ if (ARGUMENT_PACK_P (first))
+ {
+ args = expand_template_argument_pack (args);
+ first = TREE_VEC_ELT (args, 0);
+ }
gcc_checking_assert (TREE_CODE (first) == WILDCARD_DECL
|| is_auto (first));
for (int i = 1; i < TREE_VEC_LENGTH (args); ++i)
@@ -28424,8 +28555,7 @@ dguide_name_p (tree name)
{
return (TREE_CODE (name) == IDENTIFIER_NODE
&& TREE_TYPE (name)
- && !strncmp (IDENTIFIER_POINTER (name), dguide_base,
- strlen (dguide_base)));
+ && startswith (IDENTIFIER_POINTER (name), dguide_base));
}
/* True if FN is a deduction guide. */
@@ -28505,9 +28635,6 @@ rewrite_template_parm (tree olddecl, unsigned index, unsigned level,
tree oldtype = TREE_TYPE (olddecl);
newtype = cxx_make_type (TREE_CODE (oldtype));
TYPE_MAIN_VARIANT (newtype) = newtype;
- if (TREE_CODE (oldtype) == TEMPLATE_TYPE_PARM)
- TEMPLATE_TYPE_PARM_FOR_CLASS (newtype)
- = TEMPLATE_TYPE_PARM_FOR_CLASS (oldtype);
}
else
{
@@ -28624,7 +28751,8 @@ rewrite_tparm_list (tree oldelt, unsigned index, unsigned level,
/* Returns a C++17 class deduction guide template based on the constructor
CTOR. As a special case, CTOR can be a RECORD_TYPE for an implicit default
guide, REFERENCE_TYPE for an implicit copy/move guide, or TREE_LIST for an
- aggregate initialization guide. */
+ aggregate initialization guide. OUTER_ARGS are the template arguments
+ for the enclosing scope of the class. */
static tree
build_deduction_guide (tree type, tree ctor, tree outer_args, tsubst_flags_t complain)
@@ -28750,7 +28878,15 @@ build_deduction_guide (tree type, tree ctor, tree outer_args, tsubst_flags_t com
if (fparms == error_mark_node)
ok = false;
if (ci)
- ci = tsubst_constraint_info (ci, tsubst_args, complain, ctor);
+ {
+ if (outer_args)
+ /* FIXME: We'd like to avoid substituting outer template
+ arguments into the constraint ahead of time, but the
+ construction of tsubst_args assumes that outer arguments
+ are already substituted in. */
+ ci = tsubst_constraint_info (ci, outer_args, complain, ctor);
+ ci = tsubst_constraint_info (ci, tsubst_args, complain, ctor);
+ }
/* Parms are to have DECL_CHAIN tsubsted, which would be skipped if
cp_unevaluated_operand. */
@@ -28766,7 +28902,12 @@ build_deduction_guide (tree type, tree ctor, tree outer_args, tsubst_flags_t com
fparms = tsubst_arg_types (fparms, targs, NULL_TREE, complain, ctor);
fargs = tsubst (fargs, targs, complain, ctor);
if (ci)
- ci = tsubst_constraint_info (ci, targs, complain, ctor);
+ {
+ if (outer_args)
+ /* FIXME: As above. */
+ ci = tsubst_constraint_info (ci, outer_args, complain, ctor);
+ ci = tsubst_constraint_info (ci, targs, complain, ctor);
+ }
}
--processing_template_decl;
@@ -28812,12 +28953,7 @@ collect_ctor_idx_types (tree ctor, tree list, tree elt = NULL_TREE)
{
tree ftype = elt ? elt : TREE_TYPE (idx);
if (BRACE_ENCLOSED_INITIALIZER_P (val)
- && CONSTRUCTOR_NELTS (val)
- /* As in reshape_init_r, a non-aggregate or array-of-dependent-bound
- type gets a single initializer. */
- && CP_AGGREGATE_TYPE_P (ftype)
- && !(TREE_CODE (ftype) == ARRAY_TYPE
- && uses_template_parms (TYPE_DOMAIN (ftype))))
+ && CONSTRUCTOR_BRACES_ELIDED_P (val))
{
tree subelt = NULL_TREE;
if (TREE_CODE (ftype) == ARRAY_TYPE)
@@ -28870,6 +29006,8 @@ is_spec_or_derived (tree etype, tree tmpl)
return !err;
}
+static tree alias_ctad_tweaks (tree, tree);
+
/* Return a C++20 aggregate deduction candidate for TYPE initialized from
INIT. */
@@ -28882,6 +29020,15 @@ maybe_aggr_guide (tree tmpl, tree init, vec<tree,va_gc> *args)
if (init == NULL_TREE)
return NULL_TREE;
+ if (DECL_ALIAS_TEMPLATE_P (tmpl))
+ {
+ tree under = DECL_ORIGINAL_TYPE (DECL_TEMPLATE_RESULT (tmpl));
+ tree tinfo = get_template_info (under);
+ if (tree guide = maybe_aggr_guide (TI_TEMPLATE (tinfo), init, args))
+ return alias_ctad_tweaks (tmpl, guide);
+ return NULL_TREE;
+ }
+
/* We might be creating a guide for a class member template, e.g.,
template<typename U> struct A {
@@ -29040,7 +29187,8 @@ alias_ctad_tweaks (tree tmpl, tree uguides)
unsigned len = TREE_VEC_LENGTH (ftparms);
tree targs = make_tree_vec (len);
int err = unify (ftparms, targs, ret, utype, UNIFY_ALLOW_NONE, false);
- gcc_assert (!err);
+ if (err)
+ continue;
/* The number of parms for f' is the number of parms for A plus
non-deduced parms of f. */
@@ -29071,9 +29219,15 @@ alias_ctad_tweaks (tree tmpl, tree uguides)
/* Substitute the deduced arguments plus the rewritten template
parameters into f to get g. This covers the type, copyness,
guideness, and explicit-specifier. */
- tree g = tsubst_decl (DECL_TEMPLATE_RESULT (f), targs, complain);
+ tree g;
+ {
+ /* Parms are to have DECL_CHAIN tsubsted, which would be skipped
+ if cp_unevaluated_operand. */
+ cp_evaluated ev;
+ g = tsubst_decl (DECL_TEMPLATE_RESULT (f), targs, complain);
+ }
if (g == error_mark_node)
- return error_mark_node;
+ continue;
DECL_USE_TEMPLATE (g) = 0;
fprime = build_template_decl (g, gtparms, false);
DECL_TEMPLATE_RESULT (fprime) = g;
@@ -29087,7 +29241,7 @@ alias_ctad_tweaks (tree tmpl, tree uguides)
if (ci)
ci = tsubst_constraint_info (ci, targs, complain, in_decl);
if (ci == error_mark_node)
- return error_mark_node;
+ continue;
/* Add a constraint that the return type matches the instantiation of
A with the same template arguments. */
@@ -29272,7 +29426,11 @@ do_class_deduction (tree ptype, tree tmpl, tree init,
return ptype;
/* Initializing one placeholder from another. */
- if (init && TREE_CODE (init) == TEMPLATE_PARM_INDEX
+ if (init
+ && (TREE_CODE (init) == TEMPLATE_PARM_INDEX
+ || (TREE_CODE (init) == EXPR_PACK_EXPANSION
+ && (TREE_CODE (PACK_EXPANSION_PATTERN (init))
+ == TEMPLATE_PARM_INDEX)))
&& is_auto (TREE_TYPE (init))
&& CLASS_PLACEHOLDER_TEMPLATE (TREE_TYPE (init)) == tmpl)
return cp_build_qualified_type (TREE_TYPE (init), cp_type_quals (ptype));
@@ -29287,12 +29445,16 @@ do_class_deduction (tree ptype, tree tmpl, tree init,
}
else if (cxx_dialect < cxx20 && DECL_ALIAS_TEMPLATE_P (tmpl))
{
- /* This doesn't affect conforming C++17 code, so just pedwarn. */
- if (complain & tf_warning_or_error)
- pedwarn (input_location, 0, "alias template deduction only available "
- "with %<-std=c++20%> or %<-std=gnu++20%>");
+ if (complain & tf_error)
+ error ("alias template deduction only available "
+ "with %<-std=c++20%> or %<-std=gnu++20%>");
+ return error_mark_node;
}
+ /* Wait until the initializer is non-dependent. */
+ if (type_dependent_expression_p (init))
+ return ptype;
+
tree type = TREE_TYPE (tmpl);
bool try_list_ctor = false;
@@ -29306,7 +29468,8 @@ do_class_deduction (tree ptype, tree tmpl, tree init,
{
list_init_p = true;
try_list_ctor = TYPE_HAS_LIST_CTOR (type);
- if (try_list_ctor && CONSTRUCTOR_NELTS (init) == 1)
+ if (try_list_ctor && CONSTRUCTOR_NELTS (init) == 1
+ && !CONSTRUCTOR_IS_DESIGNATED_INIT (init))
{
/* As an exception, the first phase in 16.3.1.7 (considering the
initializer list as a single argument) is omitted if the
@@ -29362,7 +29525,7 @@ do_class_deduction (tree ptype, tree tmpl, tree init,
if (tree guide = maybe_aggr_guide (tmpl, init, args))
cands = lookup_add (guide, cands);
- tree call = error_mark_node;
+ tree fndecl = error_mark_node;
/* If this is list-initialization and the class has a list constructor, first
try deducing from the list as a single argument, as [over.match.list]. */
@@ -29376,11 +29539,9 @@ do_class_deduction (tree ptype, tree tmpl, tree init,
}
if (list_cands)
{
- ++cp_unevaluated_operand;
- call = build_new_function_call (list_cands, &args, tf_decltype);
- --cp_unevaluated_operand;
+ fndecl = perform_dguide_overload_resolution (list_cands, args, tf_none);
- if (call == error_mark_node)
+ if (fndecl == error_mark_node)
{
/* That didn't work, now try treating the list as a sequence of
arguments. */
@@ -29396,31 +29557,22 @@ do_class_deduction (tree ptype, tree tmpl, tree init,
"user-declared constructors", type);
return error_mark_node;
}
- else if (!cands && call == error_mark_node)
+ else if (!cands && fndecl == error_mark_node)
{
error ("cannot deduce template arguments of %qT, as it has no viable "
"deduction guides", type);
return error_mark_node;
}
- if (call == error_mark_node)
- {
- ++cp_unevaluated_operand;
- call = build_new_function_call (cands, &args, tf_decltype);
- --cp_unevaluated_operand;
- }
+ if (fndecl == error_mark_node)
+ fndecl = perform_dguide_overload_resolution (cands, args, tf_none);
- if (call == error_mark_node)
+ if (fndecl == error_mark_node)
{
if (complain & tf_warning_or_error)
{
error ("class template argument deduction failed:");
-
- ++cp_unevaluated_operand;
- call = build_new_function_call (cands, &args,
- complain | tf_decltype);
- --cp_unevaluated_operand;
-
+ perform_dguide_overload_resolution (cands, args, complain);
if (elided)
inform (input_location, "explicit deduction guides not considered "
"for copy-initialization");
@@ -29431,8 +29583,7 @@ do_class_deduction (tree ptype, tree tmpl, tree init,
constructor is chosen, the initialization is ill-formed. */
else if (flags & LOOKUP_ONLYCONVERTING)
{
- tree fndecl = cp_get_callee_fndecl_nofold (call);
- if (fndecl && DECL_NONCONVERTING_P (fndecl))
+ if (DECL_NONCONVERTING_P (fndecl))
{
if (complain & tf_warning_or_error)
{
@@ -29450,12 +29601,10 @@ do_class_deduction (tree ptype, tree tmpl, tree init,
/* If CTAD succeeded but the type doesn't have any explicit deduction
guides, this deduction might not be what the user intended. */
- if (call != error_mark_node && !any_dguides_p)
+ if (fndecl != error_mark_node && !any_dguides_p)
{
- tree fndecl = cp_get_callee_fndecl_nofold (call);
- if (fndecl != NULL_TREE
- && (!DECL_IN_SYSTEM_HEADER (fndecl)
- || global_dc->dc_warn_system_headers)
+ if ((!DECL_IN_SYSTEM_HEADER (fndecl)
+ || global_dc->dc_warn_system_headers)
&& warning (OPT_Wctad_maybe_unsupported,
"%qT may not intend to support class template argument "
"deduction", type))
@@ -29463,7 +29612,8 @@ do_class_deduction (tree ptype, tree tmpl, tree init,
"warning");
}
- return cp_build_qualified_type (TREE_TYPE (call), cp_type_quals (ptype));
+ return cp_build_qualified_type (TREE_TYPE (TREE_TYPE (fndecl)),
+ cp_type_quals (ptype));
}
/* Replace occurrences of 'auto' in TYPE with the appropriate type deduced
@@ -29484,8 +29634,6 @@ do_auto_deduction (tree type, tree init, tree auto_node,
tsubst_flags_t complain, auto_deduction_context context,
tree outer_targs, int flags)
{
- tree targs;
-
if (init == error_mark_node)
return error_mark_node;
@@ -29549,14 +29697,17 @@ do_auto_deduction (tree type, tree init, tree auto_node,
else
init = resolve_nondeduced_context (init, complain);
+ tree targs;
if (context == adc_decomp_type
&& auto_node == type
&& init != error_mark_node
&& TREE_CODE (TREE_TYPE (init)) == ARRAY_TYPE)
- /* [dcl.decomp]/1 - if decomposition declaration has no ref-qualifiers
- and initializer has array type, deduce cv-qualified array type. */
- return cp_build_qualified_type_real (TREE_TYPE (init), TYPE_QUALS (type),
- complain);
+ {
+ /* [dcl.struct.bind]/1 - if decomposition declaration has no ref-qualifiers
+ and initializer has array type, deduce cv-qualified array type. */
+ targs = make_tree_vec (1);
+ TREE_VEC_ELT (targs, 0) = TREE_TYPE (init);
+ }
else if (AUTO_IS_DECLTYPE (auto_node))
{
tree stripped_init = tree_strip_any_location_wrapper (init);
@@ -29642,7 +29793,8 @@ do_auto_deduction (tree type, tree init, tree auto_node,
if (processing_template_decl)
{
gcc_checking_assert (context == adc_variable_type
- || context == adc_return_type);
+ || context == adc_return_type
+ || context == adc_decomp_type);
gcc_checking_assert (!type_dependent_expression_p (init));
/* If the constraint is dependent, we need to wait until
instantiation time to resolve the placeholder. */
@@ -29650,7 +29802,9 @@ do_auto_deduction (tree type, tree init, tree auto_node,
return type;
}
- if ((context == adc_return_type || context == adc_variable_type)
+ if ((context == adc_return_type
+ || context == adc_variable_type
+ || context == adc_decomp_type)
&& current_function_decl
&& DECL_TEMPLATE_INFO (current_function_decl))
outer_targs = DECL_TI_ARGS (current_function_decl);
@@ -30008,25 +30162,41 @@ get_mergeable_specialization_flags (tree tmpl, tree decl)
get_mergeable_specialization_flags. */
void
-add_mergeable_specialization (bool decl_p, spec_entry *elt,
+add_mergeable_specialization (bool decl_p, bool alias_p, spec_entry *elt,
tree decl, unsigned flags)
{
- hash_table<spec_hasher> *specializations
- = decl_p ? decl_specializations : type_specializations;
-
hashval_t hash = spec_hasher::hash (elt);
- auto *slot = specializations->find_slot_with_hash (elt, hash, INSERT);
-
- /* We don't distinguish different constrained partial type
- specializations, so there could be duplicates. Everything else
- must be new. */
- if (!(flags & 2 && *slot))
+ if (decl_p)
{
- gcc_checking_assert (!*slot);
+ auto *slot = decl_specializations->find_slot_with_hash (elt, hash, INSERT);
+ gcc_checking_assert (!*slot);
auto entry = ggc_alloc<spec_entry> ();
*entry = *elt;
*slot = entry;
+
+ if (alias_p)
+ {
+ elt->spec = TREE_TYPE (elt->spec);
+ gcc_checking_assert (elt->spec);
+ }
+ }
+
+ if (!decl_p || alias_p)
+ {
+ auto *slot = type_specializations->find_slot_with_hash (elt, hash, INSERT);
+
+ /* We don't distinguish different constrained partial type
+ specializations, so there could be duplicates. Everything else
+ must be new. */
+ if (!(flags & 2 && *slot))
+ {
+ gcc_checking_assert (!*slot);
+
+ auto entry = ggc_alloc<spec_entry> ();
+ *entry = *elt;
+ *slot = entry;
+ }
}
if (flags & 1)