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.
This commit is contained in:
parent
b1983f4582
commit
c416c52bcd
@ -1,3 +1,13 @@
|
||||
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>
|
||||
|
||||
PR c++/94886
|
||||
|
@ -546,12 +546,16 @@ static tree
|
||||
map_arguments (tree parms, tree args)
|
||||
{
|
||||
for (tree p = parms; p; p = TREE_CHAIN (p))
|
||||
{
|
||||
int level;
|
||||
int index;
|
||||
template_parm_level_and_index (TREE_VALUE (p), &level, &index);
|
||||
TREE_PURPOSE (p) = TMPL_ARG (args, level, index);
|
||||
}
|
||||
if (args)
|
||||
{
|
||||
int level;
|
||||
int 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;
|
||||
}
|
||||
|
||||
@ -2005,8 +2009,6 @@ tsubst_compound_requirement (tree t, tree args, subst_info info)
|
||||
static tree
|
||||
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. */
|
||||
tree norm = TREE_VALUE (TREE_TYPE (t));
|
||||
tree result = satisfy_constraint (norm, args, info);
|
||||
@ -2953,12 +2955,15 @@ finish_compound_requirement (location_t loc, tree expr, tree type, bool noexcept
|
||||
tree
|
||||
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
|
||||
arguments with the requirement. We keep the complete set of arguments
|
||||
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);
|
||||
|
||||
/* Build the constraint, saving its normalization as its type. */
|
||||
|
15
gcc/testsuite/g++.dg/concepts/pr94827.C
Normal file
15
gcc/testsuite/g++.dg/concepts/pr94827.C
Normal file
@ -0,0 +1,15 @@
|
||||
// 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;
|
||||
}
|
Loading…
Reference in New Issue
Block a user