Commit c416c52b by Nathan Sidwell

c++ ICE with nested requirement as default tpl parm[PR94827]

Template headers are not incrementally updated as we parse its parameters.
We maintain a dummy level until the closing > when we replace the dummy with
a real parameter set.  requires processing was expecting a properly populated
arg_vec in current_template_parms, and then creates a self-mapping of parameters
from that.  But we don't need to do that, just teach map_arguments to look at
TREE_VALUE when args is NULL.

	* constraint.cc (map_arguments): If ARGS is null, it's a
	self-mapping of parms.
	(finish_nested_requirement): Do not pass argified
	current_template_parms to normalization.
	(tsubst_nested_requirement): Don't assert no template parms.
parent b1983f45
2020-04-30 Jason Merrill <jason@redhat.com>
Nathan Sidwell <nathan@acm.org>
PR c++/94827
* constraint.cc (map_arguments): If ARGS is null, it's a
self-mapping of parms.
(finish_nested_requirement): Do not pass argified
current_template_parms to normalization.
(tsubst_nested_requirement): Don't assert no template parms.
2020-04-30 Iain Sandoe <iain@sandoe.co.uk> 2020-04-30 Iain Sandoe <iain@sandoe.co.uk>
PR c++/94886 PR c++/94886
......
...@@ -546,12 +546,16 @@ static tree ...@@ -546,12 +546,16 @@ static tree
map_arguments (tree parms, tree args) map_arguments (tree parms, tree args)
{ {
for (tree p = parms; p; p = TREE_CHAIN (p)) for (tree p = parms; p; p = TREE_CHAIN (p))
{ if (args)
int level; {
int index; int level;
template_parm_level_and_index (TREE_VALUE (p), &level, &index); int index;
TREE_PURPOSE (p) = TMPL_ARG (args, level, index); template_parm_level_and_index (TREE_VALUE (p), &level, &index);
} TREE_PURPOSE (p) = TMPL_ARG (args, level, index);
}
else
TREE_PURPOSE (p) = TREE_VALUE (p);
return parms; return parms;
} }
...@@ -2005,8 +2009,6 @@ tsubst_compound_requirement (tree t, tree args, subst_info info) ...@@ -2005,8 +2009,6 @@ tsubst_compound_requirement (tree t, tree args, subst_info info)
static tree static tree
tsubst_nested_requirement (tree t, tree args, subst_info info) tsubst_nested_requirement (tree t, tree args, subst_info info)
{ {
gcc_assert (!uses_template_parms (args));
/* Ensure that we're in an evaluation context prior to satisfaction. */ /* Ensure that we're in an evaluation context prior to satisfaction. */
tree norm = TREE_VALUE (TREE_TYPE (t)); tree norm = TREE_VALUE (TREE_TYPE (t));
tree result = satisfy_constraint (norm, args, info); tree result = satisfy_constraint (norm, args, info);
...@@ -2953,12 +2955,15 @@ finish_compound_requirement (location_t loc, tree expr, tree type, bool noexcept ...@@ -2953,12 +2955,15 @@ finish_compound_requirement (location_t loc, tree expr, tree type, bool noexcept
tree tree
finish_nested_requirement (location_t loc, tree expr) finish_nested_requirement (location_t loc, tree expr)
{ {
/* Currently open template headers have dummy arg vectors, so don't
pass into normalization. */
tree norm = normalize_constraint_expression (expr, NULL_TREE, false);
tree args = current_template_parms
? template_parms_to_args (current_template_parms) : NULL_TREE;
/* Save the normalized constraint and complete set of normalization /* Save the normalized constraint and complete set of normalization
arguments with the requirement. We keep the complete set of arguments arguments with the requirement. We keep the complete set of arguments
around for re-normalization during diagnostics. */ around for re-normalization during diagnostics. */
tree args = current_template_parms
? template_parms_to_args (current_template_parms) : NULL_TREE;
tree norm = normalize_constraint_expression (expr, args, false);
tree info = build_tree_list (args, norm); tree info = build_tree_list (args, norm);
/* Build the constraint, saving its normalization as its type. */ /* Build the constraint, saving its normalization as its type. */
......
// PR 94287 ICE looking inside open template-parm level
// { dg-do run { target c++17 } }
// { dg-options -fconcepts }
template <typename T,
bool X = requires { requires (sizeof(T)==1); } >
int foo(T) { return X; }
int main() {
if (!foo('4'))
return 1;
if (foo (4))
return 2;
return 0;
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment