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  <msebor@redhat.com>
    
	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  <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.

From-SVN: r232766
This commit is contained in:
Martin Sebor 2016-01-23 16:01:47 +00:00 committed by Martin Sebor
parent 6af801f52a
commit 69da78025e
5 changed files with 112 additions and 5 deletions

View File

@ -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> 2016-01-21 Jason Merrill <jason@redhat.com>
PR c++/69392 PR c++/69392

View File

@ -1193,7 +1193,8 @@ is_late_template_attribute (tree attr, tree decl)
second and following arguments. Attributes like mode, format, second and following arguments. Attributes like mode, format,
cleanup and several target specific attributes aren't late cleanup and several target specific attributes aren't late
just because they have an IDENTIFIER_NODE as first argument. */ 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; continue;
if (value_dependent_expression_p (t) if (value_dependent_expression_p (t)

View File

@ -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> 2016-01-23 Uros Bizjak <ubizjak@gmail.com>
* gcc.target/i386/chkp-strlen-2.c: Define _GNU_SOURCE. * gcc.target/i386/chkp-strlen-2.c: Define _GNU_SOURCE.

View File

@ -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 {}; // Never instantiated.
SA(alignof(E) == 16); 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;

View File

@ -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 ();
}