xref: /aosp_15_r20/external/clang/test/SemaCXX/alignof.cpp (revision 67e74705e28f6214e480b399dd47ea732279e315)
1*67e74705SXin Li // RUN: %clang_cc1 -std=c++11 -fsyntax-only -verify %s
2*67e74705SXin Li 
3*67e74705SXin Li // rdar://13784901
4*67e74705SXin Li 
5*67e74705SXin Li struct S0 {
6*67e74705SXin Li   int x;
7*67e74705SXin Li   static const int test0 = __alignof__(x); // expected-error {{invalid application of 'alignof' to a field of a class still being defined}}
8*67e74705SXin Li   static const int test1 = __alignof__(S0::x); // expected-error {{invalid application of 'alignof' to a field of a class still being defined}}
9*67e74705SXin Li   auto test2() -> char(&)[__alignof__(x)]; // expected-error {{invalid application of 'alignof' to a field of a class still being defined}}
10*67e74705SXin Li };
11*67e74705SXin Li 
12*67e74705SXin Li struct S1; // expected-note 6 {{forward declaration}}
13*67e74705SXin Li extern S1 s1;
14*67e74705SXin Li const int test3 = __alignof__(s1); // expected-error {{invalid application of 'alignof' to an incomplete type 'S1'}}
15*67e74705SXin Li 
16*67e74705SXin Li struct S2 {
17*67e74705SXin Li   S2();
18*67e74705SXin Li   S1 &s;
19*67e74705SXin Li   int x;
20*67e74705SXin Li 
21*67e74705SXin Li   int test4 = __alignof__(x); // ok
22*67e74705SXin Li   int test5 = __alignof__(s); // expected-error {{invalid application of 'alignof' to an incomplete type 'S1'}}
23*67e74705SXin Li };
24*67e74705SXin Li 
25*67e74705SXin Li const int test6 = __alignof__(S2::x);
26*67e74705SXin Li const int test7 = __alignof__(S2::s); // expected-error {{invalid application of 'alignof' to an incomplete type 'S1'}}
27*67e74705SXin Li 
28*67e74705SXin Li // Arguably, these should fail like the S1 cases do: the alignment of
29*67e74705SXin Li // 's2.x' should depend on the alignment of both x-within-S2 and
30*67e74705SXin Li // s2-within-S3 and thus require 'S3' to be complete.  If we start
31*67e74705SXin Li // doing the appropriate recursive walk to do that, we should make
32*67e74705SXin Li // sure that these cases don't explode.
33*67e74705SXin Li struct S3 {
34*67e74705SXin Li   S2 s2;
35*67e74705SXin Li 
36*67e74705SXin Li   static const int test8 = __alignof__(s2.x);
37*67e74705SXin Li   static const int test9 = __alignof__(s2.s); // expected-error {{invalid application of 'alignof' to an incomplete type 'S1'}}
38*67e74705SXin Li   auto test10() -> char(&)[__alignof__(s2.x)];
39*67e74705SXin Li   static const int test11 = __alignof__(S3::s2.x);
40*67e74705SXin Li   static const int test12 = __alignof__(S3::s2.s); // expected-error {{invalid application of 'alignof' to an incomplete type 'S1'}}
41*67e74705SXin Li   auto test13() -> char(&)[__alignof__(s2.x)];
42*67e74705SXin Li };
43*67e74705SXin Li 
44*67e74705SXin Li // Same reasoning as S3.
45*67e74705SXin Li struct S4 {
46*67e74705SXin Li   union {
47*67e74705SXin Li     int x;
48*67e74705SXin Li   };
49*67e74705SXin Li   static const int test0 = __alignof__(x);
50*67e74705SXin Li   static const int test1 = __alignof__(S0::x);
51*67e74705SXin Li   auto test2() -> char(&)[__alignof__(x)];
52*67e74705SXin Li };
53*67e74705SXin Li 
54*67e74705SXin Li // Regression test for asking for the alignment of a field within an invalid
55*67e74705SXin Li // record.
56*67e74705SXin Li struct S5 {
57*67e74705SXin Li   S1 s;  // expected-error {{incomplete type}}
58*67e74705SXin Li   int x;
59*67e74705SXin Li };
60*67e74705SXin Li const int test8 = __alignof__(S5::x);
61*67e74705SXin Li 
62*67e74705SXin Li long long int test14[2];
63*67e74705SXin Li 
64*67e74705SXin Li static_assert(alignof(test14) == 8, "foo"); // expected-warning {{'alignof' applied to an expression is a GNU extension}}
65*67e74705SXin Li 
66*67e74705SXin Li // PR19992
67*67e74705SXin Li static_assert(alignof(int[]) == alignof(int), ""); // ok
68*67e74705SXin Li 
69*67e74705SXin Li namespace alignof_array_expr {
70*67e74705SXin Li   alignas(32) extern int n[];
71*67e74705SXin Li   static_assert(alignof(n) == 32, ""); // expected-warning {{GNU extension}}
72*67e74705SXin Li 
73*67e74705SXin Li   template<int> struct S {
74*67e74705SXin Li     static int a[];
75*67e74705SXin Li   };
76*67e74705SXin Li   template<int N> int S<N>::a[N];
77*67e74705SXin Li   // ok, does not complete type of S<-1>::a
78*67e74705SXin Li   static_assert(alignof(S<-1>::a) == alignof(int), ""); // expected-warning {{GNU extension}}
79*67e74705SXin Li }
80*67e74705SXin Li 
n(T)81*67e74705SXin Li template <typename T> void n(T) {
82*67e74705SXin Li   alignas(T) int T1;
83*67e74705SXin Li   char k[__alignof__(T1)];
84*67e74705SXin Li   static_assert(sizeof(k) == alignof(long long), "");
85*67e74705SXin Li }
86*67e74705SXin Li template void n(long long);
87*67e74705SXin Li 
88*67e74705SXin Li namespace PR22042 {
89*67e74705SXin Li template <typename T>
Fun(T A)90*67e74705SXin Li void Fun(T A) {
91*67e74705SXin Li   typedef int __attribute__((__aligned__(A))) T1; // expected-error {{requested alignment is dependent but declaration is not dependent}}
92*67e74705SXin Li   int k1[__alignof__(T1)];
93*67e74705SXin Li }
94*67e74705SXin Li 
95*67e74705SXin Li template <int N>
96*67e74705SXin Li struct S {
97*67e74705SXin Li   typedef __attribute__((aligned(N))) int Field[sizeof(N)]; // expected-error {{requested alignment is dependent but declaration is not dependent}}
98*67e74705SXin Li };
99*67e74705SXin Li }
100