From 55dd44535d2e4e5703c0103c26e7c51ab8c502c4 Mon Sep 17 00:00:00 2001 From: Jason Merrill Date: Thu, 23 Jan 2020 16:59:54 -0500 Subject: [PATCH] c++: Fix parameter map handling of member typedef. any_template_parm_r was looking at the args of an alias template-id, but we need to look at all args of a member alias/typedef, including implicit ones from the enclosing class. PR c++/93377 - ICE with member alias in constraint. * pt.c (any_template_parm_r): Look at template arguments for all aliases, not only alias templates. --- gcc/cp/ChangeLog | 6 ++ gcc/cp/pt.c | 20 +++---- gcc/testsuite/g++.dg/cpp2a/concepts-alias5.C | 62 ++++++++++++++++++++ 3 files changed, 77 insertions(+), 11 deletions(-) create mode 100644 gcc/testsuite/g++.dg/cpp2a/concepts-alias5.C diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog index 0ed260b5da1..cddf169ea5b 100644 --- a/gcc/cp/ChangeLog +++ b/gcc/cp/ChangeLog @@ -1,3 +1,9 @@ +2020-01-24 Jason Merrill + + PR c++/93377 - ICE with member alias in constraint. + * pt.c (any_template_parm_r): Look at template arguments for all + aliases, not only alias templates. + 2020-01-24 Marek Polacek PR c++/93299 - ICE in tsubst_copy with parenthesized expression. diff --git a/gcc/cp/pt.c b/gcc/cp/pt.c index 95719927249..209044135cb 100644 --- a/gcc/cp/pt.c +++ b/gcc/cp/pt.c @@ -10427,19 +10427,15 @@ any_template_parm_r (tree t, void *data) } \ while (0) + /* A mention of a member alias/typedef is a use of all of its template + arguments, including those from the enclosing class, so we don't use + alias_template_specialization_p here. */ + if (TYPE_P (t) && typedef_variant_p (t)) + if (tree tinfo = TYPE_ALIAS_TEMPLATE_INFO (t)) + WALK_SUBTREE (TI_ARGS (tinfo)); + switch (TREE_CODE (t)) { - case RECORD_TYPE: - case UNION_TYPE: - case ENUMERAL_TYPE: - /* Search for template parameters in type aliases. */ - if (tree ats = alias_template_specialization_p (t, nt_opaque)) - { - tree tinfo = TYPE_ALIAS_TEMPLATE_INFO (ats); - WALK_SUBTREE (TI_ARGS (tinfo)); - } - break; - case TEMPLATE_TYPE_PARM: /* Type constraints of a placeholder type may contain parameters. */ if (is_auto (t)) @@ -10472,6 +10468,8 @@ any_template_parm_r (tree t, void *data) 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)))) diff --git a/gcc/testsuite/g++.dg/cpp2a/concepts-alias5.C b/gcc/testsuite/g++.dg/cpp2a/concepts-alias5.C new file mode 100644 index 00000000000..907b0c2e357 --- /dev/null +++ b/gcc/testsuite/g++.dg/cpp2a/concepts-alias5.C @@ -0,0 +1,62 @@ +// PR c++/93377 +// { dg-do compile { target c++2a } } + +struct empty +{}; + +template +c value; + +template +auto func(value); + +template +struct alignment_algorithm; + +template +struct select +{ + template + decltype(algorithm_t()(func<_args_t>...)) choose(); + + template + static empty choose(); + + using type = decltype(choose, args_t...>()); +}; + +template +struct select_algorithm : select +{}; + +template struct maybe_value { int value; }; + +template +struct maybe_value; + +struct function +{ + template >::value)> + function(algorithm_t); +}; + +template +struct alignment_configuration_traits +{ + static constexpr bool is_vectorised = 0; +}; + +template +struct alignment_algorithm +{ + using traits_t = alignment_configuration_traits; + template + void operator()(indexed_sequence_pairs_t) requires traits_t::is_vectorised; +}; + +int main() +{ + function{alignment_algorithm{}}; +} -- 2.30.2