mirror of
git://gcc.gnu.org/git/gcc.git
synced 2025-04-14 01:50:35 +08:00
PR c++/92582 - ICE with member template as requirement.
Here, we weren't recognizing that the template parameter of A is used by the reference to d in the requires-clause of f. Fixed by passing down the active template parameters in the context of normalization, and adding to the mapping any such parameters shared by a member template used in the constraint-expression. * pt.c (struct find_template_parameter_info): Add ctx_parms. (any_template_parm_r): Handle TEMPLATE_DECL. (find_template_parameters): Take parms instead of their depth. * constraint.cc (build_parameter_mapping): Pass them.
This commit is contained in:
parent
f1ba88b1b2
commit
8ca4435f43
@ -1,5 +1,11 @@
|
||||
2020-01-13 Jason Merrill <jason@redhat.com>
|
||||
|
||||
PR c++/92582 - ICE with member template as requirement.
|
||||
* pt.c (struct find_template_parameter_info): Add ctx_parms.
|
||||
(any_template_parm_r): Handle TEMPLATE_DECL.
|
||||
(find_template_parameters): Take parms instead of their depth.
|
||||
* constraint.cc (build_parameter_mapping): Pass them.
|
||||
|
||||
PR c++/33799 - destroy return value if local cleanup throws.
|
||||
* cp-tree.h (current_retval_sentinel): New macro.
|
||||
* decl.c (start_preparsed_function): Set up cleanup for retval.
|
||||
|
@ -559,12 +559,11 @@ map_arguments (tree parms, tree args)
|
||||
static tree
|
||||
build_parameter_mapping (tree expr, tree args, tree decl)
|
||||
{
|
||||
int depth = 0;
|
||||
tree ctx_parms = NULL_TREE;
|
||||
if (decl)
|
||||
{
|
||||
gcc_assert (TREE_CODE (decl) == TEMPLATE_DECL);
|
||||
tree parms = DECL_TEMPLATE_PARMS (decl);
|
||||
depth = TREE_INT_CST_LOW (TREE_PURPOSE (parms));
|
||||
ctx_parms = DECL_TEMPLATE_PARMS (decl);
|
||||
}
|
||||
else if (current_template_parms)
|
||||
{
|
||||
@ -572,10 +571,10 @@ build_parameter_mapping (tree expr, tree args, tree decl)
|
||||
point of declaration of concepts is currently set after the
|
||||
initializer, the template parameter lists are not available
|
||||
when normalizing concept definitions, hence the case above. */
|
||||
depth = TMPL_PARMS_DEPTH (current_template_parms);
|
||||
ctx_parms = current_template_parms;
|
||||
}
|
||||
|
||||
tree parms = find_template_parameters (expr, depth);
|
||||
tree parms = find_template_parameters (expr, ctx_parms);
|
||||
tree map = map_arguments (parms, args);
|
||||
return map;
|
||||
}
|
||||
|
@ -7865,7 +7865,7 @@ extern bool constraints_satisfied_p (tree, tree);
|
||||
extern void clear_satisfaction_cache ();
|
||||
extern bool* lookup_subsumption_result (tree, tree);
|
||||
extern bool save_subsumption_result (tree, tree, bool);
|
||||
extern tree find_template_parameters (tree, int);
|
||||
extern tree find_template_parameters (tree, tree);
|
||||
extern bool equivalent_constraints (tree, tree);
|
||||
extern bool equivalently_constrained (tree, tree);
|
||||
extern bool subsumes_constraints (tree, tree);
|
||||
|
39
gcc/cp/pt.c
39
gcc/cp/pt.c
@ -10364,12 +10364,14 @@ for_each_template_parm (tree t, tree_fn_t fn, void* data,
|
||||
|
||||
struct find_template_parameter_info
|
||||
{
|
||||
explicit find_template_parameter_info (int d)
|
||||
: max_depth (d)
|
||||
explicit find_template_parameter_info (tree ctx_parms)
|
||||
: ctx_parms (ctx_parms),
|
||||
max_depth (TMPL_PARMS_DEPTH (ctx_parms))
|
||||
{}
|
||||
|
||||
hash_set<tree> visited;
|
||||
hash_set<tree> parms;
|
||||
tree ctx_parms;
|
||||
int max_depth;
|
||||
};
|
||||
|
||||
@ -10459,6 +10461,29 @@ any_template_parm_r (tree t, void *data)
|
||||
WALK_SUBTREE (TREE_TYPE (t));
|
||||
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 (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));
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
@ -10467,12 +10492,16 @@ any_template_parm_r (tree t, void *data)
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Returns a list of unique template parameters found within T. */
|
||||
/* Returns a list of unique template parameters found within T, where CTX_PARMS
|
||||
are the template parameters in scope. */
|
||||
|
||||
tree
|
||||
find_template_parameters (tree t, int depth)
|
||||
find_template_parameters (tree t, tree ctx_parms)
|
||||
{
|
||||
find_template_parameter_info ftpi (depth);
|
||||
if (!ctx_parms)
|
||||
return NULL_TREE;
|
||||
|
||||
find_template_parameter_info ftpi (ctx_parms);
|
||||
for_each_template_parm (t, keep_template_parm, &ftpi, &ftpi.visited,
|
||||
/*include_nondeduced*/true, any_template_parm_r);
|
||||
tree list = NULL_TREE;
|
||||
|
12
gcc/testsuite/g++.dg/cpp2a/concepts-memtmpl3.C
Normal file
12
gcc/testsuite/g++.dg/cpp2a/concepts-memtmpl3.C
Normal file
@ -0,0 +1,12 @@
|
||||
// PR c++/92582
|
||||
// { dg-do compile { target concepts } }
|
||||
|
||||
template <class a, class> concept b = true;
|
||||
template <typename> struct A {
|
||||
template <typename c> static constexpr bool d = b<c, int>;
|
||||
template <typename c> static void f(c) requires d<c>;
|
||||
};
|
||||
int main()
|
||||
{
|
||||
A<void>::f(0);
|
||||
}
|
Loading…
x
Reference in New Issue
Block a user