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.
Tested x86_64-pc-linux-gnu, applying to trunk. 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/pt.c | 20 +++---- gcc/testsuite/g++.dg/cpp2a/concepts-alias5.C | 62 ++++++++++++++++++++ 2 files changed, 71 insertions(+), 11 deletions(-) create mode 100644 gcc/testsuite/g++.dg/cpp2a/concepts-alias5.C 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 <typename c> +c value; + +template <typename c> +auto func(value<c>); + +template <typename, typename...> +struct alignment_algorithm; + +template <typename... args_t> +struct select +{ + template <typename algorithm_t, typename... _args_t> + decltype(algorithm_t()(func<_args_t>...)) choose(); + + template <typename...> + static empty choose(); + + using type = decltype(choose<alignment_algorithm<int>, args_t...>()); +}; + +template <typename, typename... args_t> +struct select_algorithm : select<args_t...> +{}; + +template <typename, typename = void> struct maybe_value { int value; }; + +template <typename cn> +struct maybe_value<cn, typename cn::sfinae>; + +struct function +{ + template <typename algorithm_t, + typename = decltype( + maybe_value<select_algorithm<algorithm_t, int>>::value)> + function(algorithm_t); +}; + +template <typename> +struct alignment_configuration_traits +{ + static constexpr bool is_vectorised = 0; +}; + +template <typename config_t, typename...> +struct alignment_algorithm +{ + using traits_t = alignment_configuration_traits<config_t>; + template <typename indexed_sequence_pairs_t> + void operator()(indexed_sequence_pairs_t) requires traits_t::is_vectorised; +}; + +int main() +{ + function{alignment_algorithm<int>{}}; +} base-commit: 14e5881e37771f1f58123e77c558adb3b90c8764 -- 2.18.1