1// RUN: %clang_cc1 -std=c++11 -verify %s
2
3alignas(4) extern int n1; // expected-note {{previous declaration}}
4alignas(8) int n1; // expected-error {{redeclaration has different alignment requirement (8 vs 4)}}
5
6alignas(8) int n2; // expected-note {{previous declaration}}
7alignas(4) extern int n2; // expected-error {{different alignment requirement (4 vs 8)}}
8
9alignas(8) extern int n3; // expected-note {{previous declaration}}
10alignas(4) extern int n3; // expected-error {{different alignment requirement (4 vs 8)}}
11
12extern int n4;
13alignas(8) extern int n4;
14
15alignas(8) extern int n5;
16extern int n5;
17
18int n6; // expected-error {{'alignas' must be specified on definition if it is specified on any declaration}}
19alignas(8) extern int n6; // expected-note {{declared with 'alignas' attribute here}}
20
21extern int n7;
22alignas(8) int n7;
23
24alignas(8) extern int n8; // expected-note {{declared with 'alignas' attribute here}}
25int n8; // expected-error {{'alignas' must be specified on definition if it is specified on any declaration}}
26
27int n9; // expected-error {{'alignas' must be specified on definition if it is specified on any declaration}}
28alignas(4) extern int n9; // expected-note {{declared with 'alignas' attribute here}}
29
30
31enum alignas(2) E : char; // expected-note {{declared with 'alignas' attribute here}}
32enum E : char {}; // expected-error {{'alignas' must be specified on definition if it is specified on any declaration}}
33
34enum alignas(4) F : char; // expected-note {{previous declaration is here}}
35enum alignas(2) F : char; // expected-error {{redeclaration has different alignment requirement (2 vs 4)}}
36
37enum G : char;
38enum alignas(8) G : char {};
39enum G : char;
40
41enum H : char {}; // expected-error {{'alignas' must be specified on definition if it is specified on any declaration}}
42enum alignas(1) H : char; // expected-note {{declared with 'alignas' attribute here}}
43
44
45struct S;
46struct alignas(16) S; // expected-note {{declared with 'alignas' attribute here}}
47struct S;
48struct S { int n; }; // expected-error {{'alignas' must be specified on definition if it is specified on any declaration}}
49
50struct alignas(2) T;
51struct alignas(2) T { char c; }; // expected-note {{previous declaration is here}}
52struct T;
53struct alignas(4) T; // expected-error {{redeclaration has different alignment requirement (4 vs 2)}}
54
55struct U;
56struct alignas(2) U {};
57
58struct V {}; // expected-error {{'alignas' must be specified on definition if it is specified on any declaration}}
59struct alignas(1) V; // expected-note {{declared with 'alignas' attribute here}}
60
61template<int M, int N> struct alignas(M) W;
62template<int M, int N> struct alignas(N) W {};
63W<4,4> w44; // ok
64// FIXME: We should reject this.
65W<1,2> w12;
66static_assert(alignof(W<4,4>) == 4, "");
67
68template<int M, int N, int O, int P> struct X {
69  alignas(M) alignas(N) static char Buffer[32]; // expected-note {{previous declaration is here}}
70};
71template<int M, int N, int O, int P>
72alignas(O) alignas(P) char X<M, N, O, P>::Buffer[32]; // expected-error {{redeclaration has different alignment requirement (8 vs 2)}}
73char *x1848 = X<1,8,4,8>::Buffer; // ok
74char *x1248 = X<1,2,4,8>::Buffer; // expected-note {{in instantiation of}}
75
76template<int M, int N, int O, int P> struct Y {
77  enum alignas(M) alignas(N) E : char;
78};
79template<int M, int N, int O, int P>
80enum alignas(O) alignas(P) Y<M,N,O,P>::E : char { e };
81int y1848 = Y<1,8,4,8>::e;
82// FIXME: We should reject this.
83int y1248 = Y<1,2,4,8>::e;
84
85// Don't crash here.
86alignas(4) struct Incomplete incomplete; // expected-error {{incomplete type}} expected-note {{forward declaration}}
87