From 69da78025ec5e1408576eda81cb97d2e53cdace8 Mon Sep 17 00:00:00 2001 From: Martin Sebor Date: Sat, 23 Jan 2016 16:01:47 +0000 Subject: [PATCH] PR c++/58109 - alignas() fails to compile with constant expression PR c++/58109 - alignas() fails to compile with constant expression PR c++/69022 - attribute vector_size ignored with dependent bytes gcc/testsuite/ChangeLog: 2016-01-23 Martin Sebor PR c++/58109 PR c++/69022 * g++.dg/cpp0x/alignas5.C: New test. * g++.dg/ext/vector29.C: Same. gcc/cp/ChangeLog: 2016-01-23 Martin Sebor PR c++/58109 PR c++/69022 * decl2.c (is_late_template_attribute): Handle dependent argument to attribute align and attribute vector_size. From-SVN: r232766 --- gcc/cp/ChangeLog | 7 ++++ gcc/cp/decl2.c | 3 +- gcc/testsuite/ChangeLog | 7 ++++ gcc/testsuite/g++.dg/cpp0x/alignas5.C | 47 ++++++++++++++++++++++-- gcc/testsuite/g++.dg/ext/vector29.C | 53 +++++++++++++++++++++++++++ 5 files changed, 112 insertions(+), 5 deletions(-) create mode 100644 gcc/testsuite/g++.dg/ext/vector29.C diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog index 05ca52a2cbc..07fcef44987 100644 --- a/gcc/cp/ChangeLog +++ b/gcc/cp/ChangeLog @@ -1,3 +1,10 @@ +2016-01-23 Martin Sebor + + 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 PR c++/69392 diff --git a/gcc/cp/decl2.c b/gcc/cp/decl2.c index a7212ca05bb..7d68961cd20 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 f6f0fdba59b..27d03891419 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,10 @@ +2016-01-23 Martin Sebor + + PR c++/58109 + PR c++/69022 + * g++.dg/cpp0x/alignas5.C: New test. + * g++.dg/ext/vector29.C: Same. + 2016-01-23 Uros Bizjak * 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 2820ca716f6..2dcc41fae8a 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 +struct Base { + static const int Align = sizeof (T); +}; -enum alignas(16) E {}; -SA(alignof(E) == 16); +// Never instantiated. +template +struct Derived: Base +{ +#if __cplusplus >= 201102L + // This is the meat of the (simplified) regression test for c++/58109. + using B = Base; + using B::Align; + + alignas (Align) char a [1]; + alignas (Align) T b [1]; +#else + // Fake the test for C++ 98. +# define Align Base::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 +struct InstDerived: Base +{ +#if __cplusplus >= 201102L + using B = Base; + 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 dx; diff --git a/gcc/testsuite/g++.dg/ext/vector29.C b/gcc/testsuite/g++.dg/ext/vector29.C new file mode 100644 index 00000000000..4a130092a3f --- /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 +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 +struct B: A +{ +#if __cplusplus >= 201202L + using A::X; +# define VecSize X +#else +# define VecSize A::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::X))); + ASSERT (sizeof c2 == A::X); + + T d1 __attribute__ ((vector_size (VecSize))); + ASSERT (sizeof d1 == VecSize); + + T d2 __attribute__ ((vector_size (A::X))); + ASSERT (sizeof d2 == A::X); + } +}; + +void bar () +{ + B::foo (); + B::bar (); +}