diff options
-rw-r--r-- | gcc/cp/ChangeLog | 7 | ||||
-rw-r--r-- | gcc/cp/decl2.c | 3 | ||||
-rw-r--r-- | gcc/testsuite/ChangeLog | 7 | ||||
-rw-r--r-- | gcc/testsuite/g++.dg/cpp0x/alignas5.C | 47 | ||||
-rw-r--r-- | gcc/testsuite/g++.dg/ext/vector29.C | 53 |
5 files changed, 112 insertions, 5 deletions
diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog index 05ca52a..07fcef4 100644 --- a/gcc/cp/ChangeLog +++ b/gcc/cp/ChangeLog @@ -1,3 +1,10 @@ +2016-01-23 Martin Sebor <msebor@redhat.com> + + PR c++/58109 + PR c++/69022 + * decl2.c (is_late_template_attribute): Handle dependent argument + to attribute align and attribute vector_size. + 2016-01-21 Jason Merrill <jason@redhat.com> PR c++/69392 diff --git a/gcc/cp/decl2.c b/gcc/cp/decl2.c index a7212ca0..7d68961 100644 --- a/gcc/cp/decl2.c +++ b/gcc/cp/decl2.c @@ -1193,7 +1193,8 @@ is_late_template_attribute (tree attr, tree decl) second and following arguments. Attributes like mode, format, cleanup and several target specific attributes aren't late just because they have an IDENTIFIER_NODE as first argument. */ - if (arg == args && identifier_p (t)) + if (arg == args && attribute_takes_identifier_p (name) + && identifier_p (t)) continue; if (value_dependent_expression_p (t) diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index f6f0fdb..27d0389 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,10 @@ +2016-01-23 Martin Sebor <msebor@redhat.com> + + PR c++/58109 + PR c++/69022 + * g++.dg/cpp0x/alignas5.C: New test. + * g++.dg/ext/vector29.C: Same. + 2016-01-23 Uros Bizjak <ubizjak@gmail.com> * gcc.target/i386/chkp-strlen-2.c: Define _GNU_SOURCE. diff --git a/gcc/testsuite/g++.dg/cpp0x/alignas5.C b/gcc/testsuite/g++.dg/cpp0x/alignas5.C index 2820ca7..2dcc41f 100644 --- a/gcc/testsuite/g++.dg/cpp0x/alignas5.C +++ b/gcc/testsuite/g++.dg/cpp0x/alignas5.C @@ -1,6 +1,45 @@ -// { dg-do compile { target c++11 } } +// PR c++/58109 - alignas() fails to compile with constant expression +// { dg-do compile } -#define SA(X) static_assert(X,#X) +template <typename T> +struct Base { + static const int Align = sizeof (T); +}; -enum alignas(16) E {}; -SA(alignof(E) == 16); +// Never instantiated. +template <typename T> +struct Derived: Base<T> +{ +#if __cplusplus >= 201102L + // This is the meat of the (simplified) regression test for c++/58109. + using B = Base<T>; + using B::Align; + + alignas (Align) char a [1]; + alignas (Align) T b [1]; +#else + // Fake the test for C++ 98. +# define Align Base<T>::Align +#endif + + char __attribute__ ((aligned (Align))) c [1]; + T __attribute__ ((aligned (Align))) d [1]; +}; + +// Instantiated to verify that the code is accepted even when instantiated. +template <typename T> +struct InstDerived: Base<T> +{ +#if __cplusplus >= 201102L + using B = Base<T>; + using B::Align; + + alignas (Align) char a [1]; + alignas (Align) T b [1]; +#endif + + char __attribute__ ((aligned (Align))) c [1]; + T __attribute__ ((aligned (Align))) d [1]; +}; + +InstDerived<int> dx; diff --git a/gcc/testsuite/g++.dg/ext/vector29.C b/gcc/testsuite/g++.dg/ext/vector29.C new file mode 100644 index 0000000..4a13009 --- /dev/null +++ b/gcc/testsuite/g++.dg/ext/vector29.C @@ -0,0 +1,53 @@ +// PR c++/69022 - attribute vector_size ignored with dependent bytes +// { dg-do compile } + +template <int N> +struct A { static const int X = N; }; + +#if __cplusplus >= 201202L +# define ASSERT(e) static_assert (e, #e) +#else +# define ASSERT(e) \ + do { struct S { bool: !!(e); } asrt; (void)&asrt; } while (0) +#endif + +template <class T, int N> +struct B: A<N> +{ +#if __cplusplus >= 201202L + using A<N>::X; +# define VecSize X +#else +# define VecSize A<N>::X +#endif + + static void foo () + { + char a __attribute__ ((vector_size (N))); + ASSERT (sizeof a == N); + + T b __attribute__ ((vector_size (N))); + ASSERT (sizeof b == N); + } + + static void bar () + { + char c1 __attribute__ ((vector_size (VecSize))); + ASSERT (sizeof c1 == VecSize); + + char c2 __attribute__ ((vector_size (A<N>::X))); + ASSERT (sizeof c2 == A<N>::X); + + T d1 __attribute__ ((vector_size (VecSize))); + ASSERT (sizeof d1 == VecSize); + + T d2 __attribute__ ((vector_size (A<N>::X))); + ASSERT (sizeof d2 == A<N>::X); + } +}; + +void bar () +{ + B<int, 16>::foo (); + B<int, 16>::bar (); +} |