https://gcc.gnu.org/g:2249c6348835c817f43c9fc55eac66e54ac1efeb
commit r14-10450-g2249c6348835c817f43c9fc55eac66e54ac1efeb Author: Patrick Palka <ppa...@redhat.com> Date: Mon Jul 15 18:07:55 2024 -0400 c++: alias template with dependent attributes [PR115897] Here we're prematurely stripping the dependent alias template-id A<T> to its defining-type-id T when used as a template argument, which in turn causes us to essentially ignore A's vector_size attribute in the outer template-id. This has always been a problem for class template-ids it seems, and after r14-2170 variable template-ids are affected as well. This patch marks alias templates that have a dependent attribute as complex (as with e.g. constrained alias templates) so that we don't look through them prematurely. PR c++/115897 gcc/cp/ChangeLog: * pt.cc (complex_alias_template_p): Return true for an alias template with attributes. (get_underlying_template): Don't look through an alias template with attributes. gcc/testsuite/ChangeLog: * g++.dg/cpp0x/alias-decl-77.C: New test. Reviewed-by: Jason Merrill <ja...@redhat.com> (cherry picked from commit 7954bb4fcb6fa80f6bb840133314885011821188) Diff: --- gcc/cp/pt.cc | 10 ++++++++++ gcc/testsuite/g++.dg/cpp0x/alias-decl-77.C | 32 ++++++++++++++++++++++++++++++ 2 files changed, 42 insertions(+) diff --git a/gcc/cp/pt.cc b/gcc/cp/pt.cc index 580c3fc2cb2b..83638fd74b4d 100644 --- a/gcc/cp/pt.cc +++ b/gcc/cp/pt.cc @@ -6655,6 +6655,11 @@ complex_alias_template_p (const_tree tmpl, tree *seen_out) if (get_constraints (tmpl)) return true; + /* An alias with dependent type attributes is complex. */ + if (any_dependent_type_attributes_p (DECL_ATTRIBUTES + (DECL_TEMPLATE_RESULT (tmpl)))) + return true; + if (!complex_alias_tmpl_info) complex_alias_tmpl_info = hash_map<const_tree, tree>::create_ggc (13); @@ -6807,6 +6812,11 @@ get_underlying_template (tree tmpl) if (!at_least_as_constrained (underlying, tmpl)) break; + /* If TMPL adds dependent type attributes, it isn't equivalent. */ + if (any_dependent_type_attributes_p (DECL_ATTRIBUTES + (DECL_TEMPLATE_RESULT (tmpl)))) + break; + /* Alias is equivalent. Strip it and repeat. */ tmpl = underlying; } diff --git a/gcc/testsuite/g++.dg/cpp0x/alias-decl-77.C b/gcc/testsuite/g++.dg/cpp0x/alias-decl-77.C new file mode 100644 index 000000000000..f72e4cc26538 --- /dev/null +++ b/gcc/testsuite/g++.dg/cpp0x/alias-decl-77.C @@ -0,0 +1,32 @@ +// PR c++/115897 +// { dg-do compile { target c++11 } } + +template<class T, class U> +struct is_same { static constexpr bool value = __is_same(T, U); }; + +#if __cpp_variable_templates +template<class T, class U> +constexpr bool is_same_v = __is_same(T, U); +#endif + +template<class T> +using A [[gnu::vector_size(16)]] = T; + +template<class T> +using B = T; + +template<class T> +using C [[gnu::vector_size(16)]] = B<T>; + +template<class T> +void f() { + static_assert(!is_same<T, A<T>>::value, ""); + static_assert(is_same<C<T>, A<T>>::value, ""); + +#if __cpp_variable_templates + static_assert(!is_same_v<T, A<T>>, ""); + static_assert(is_same_v<C<T>, A<T>>, ""); +#endif +}; + +template void f<float>();