aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPatrick Palka <ppalka@redhat.com>2024-07-15 18:07:55 -0400
committerPatrick Palka <ppalka@redhat.com>2024-07-15 18:07:55 -0400
commit7954bb4fcb6fa80f6bb840133314885011821188 (patch)
treed42ff6a25c13c10960a60c76ea04061f9ee59c6f
parenteb0c163aada970b8351067b17121f013fc58dbc9 (diff)
downloadgcc-7954bb4fcb6fa80f6bb840133314885011821188.zip
gcc-7954bb4fcb6fa80f6bb840133314885011821188.tar.gz
gcc-7954bb4fcb6fa80f6bb840133314885011821188.tar.bz2
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 <jason@redhat.com>
-rw-r--r--gcc/cp/pt.cc10
-rw-r--r--gcc/testsuite/g++.dg/cpp0x/alias-decl-77.C32
2 files changed, 42 insertions, 0 deletions
diff --git a/gcc/cp/pt.cc b/gcc/cp/pt.cc
index e38e024..4d72ff6 100644
--- a/gcc/cp/pt.cc
+++ b/gcc/cp/pt.cc
@@ -6628,6 +6628,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);
@@ -6780,6 +6785,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 0000000..f72e4cc2
--- /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>();