CONSTRUCTOR_C99_COMPOUND_LITERAL (in CONSTRUCTOR)
OVL_NESTED_P (in OVERLOAD)
DECL_MODULE_EXPORT_P (in _DECL)
+ PACK_EXPANSION_FORCE_EXTRA_ARGS_P (in *_PACK_EXPANSION)
4: IDENTIFIER_MARKED (IDENTIFIER_NODEs)
TREE_HAS_CONSTRUCTOR (in INDIRECT_REF, SAVE_EXPR, CONSTRUCTOR,
CALL_EXPR, or FIELD_DECL).
/* True iff this pack expansion is for auto... in lambda init-capture. */
#define PACK_EXPANSION_AUTO_P(NODE) TREE_LANG_FLAG_2 (NODE)
+/* True if we must use PACK_EXPANSION_EXTRA_ARGS and avoid partial
+ instantiation of this pack expansion. */
+#define PACK_EXPANSION_FORCE_EXTRA_ARGS_P(NODE) TREE_LANG_FLAG_3 (NODE)
+
/* True iff the wildcard can match a template parameter pack. */
#define WILDCARD_PACK_P(NODE) TREE_LANG_FLAG_0 (NODE)
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
{
/* 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
*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);
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;
}
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
/* 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. */