xref: /aosp_15_r20/external/clang/test/Sema/tls_alignment.cpp (revision 67e74705e28f6214e480b399dd47ea732279e315)
1*67e74705SXin Li // TLS variable cannot be aligned to more than 32 bytes on PS4.
2*67e74705SXin Li 
3*67e74705SXin Li // RUN: %clang_cc1 -triple x86_64-scei-ps4 -fsyntax-only -verify %s
4*67e74705SXin Li 
5*67e74705SXin Li 
6*67e74705SXin Li // A non-aligned type.
7*67e74705SXin Li struct non_aligned_struct {
8*67e74705SXin Li     int some_data[16]; // 64 bytes of stuff, non aligned.
9*67e74705SXin Li };
10*67e74705SXin Li 
11*67e74705SXin Li // An aligned type.
12*67e74705SXin Li struct __attribute__(( aligned(64) )) aligned_struct {
13*67e74705SXin Li     int some_data[12]; // 48 bytes of stuff, aligned to 64.
14*67e74705SXin Li };
15*67e74705SXin Li 
16*67e74705SXin Li // A type with an aligned field.
17*67e74705SXin Li struct  struct_with_aligned_field {
18*67e74705SXin Li     int some_aligned_data[12] __attribute__(( aligned(64) )); // 48 bytes of stuff, aligned to 64.
19*67e74705SXin Li };
20*67e74705SXin Li 
21*67e74705SXin Li // A typedef of the aligned struct.
22*67e74705SXin Li typedef aligned_struct another_aligned_struct;
23*67e74705SXin Li 
24*67e74705SXin Li // A typedef to redefine a non-aligned struct as aligned.
25*67e74705SXin Li typedef __attribute__(( aligned(64) )) non_aligned_struct yet_another_aligned_struct;
26*67e74705SXin Li 
27*67e74705SXin Li // Non aligned variable doesn't cause an error.
28*67e74705SXin Li __thread non_aligned_struct foo;
29*67e74705SXin Li 
30*67e74705SXin Li // Variable aligned because of its type should cause an error.
31*67e74705SXin Li __thread aligned_struct                    bar; // expected-error{{alignment (64) of thread-local variable}}
32*67e74705SXin Li 
33*67e74705SXin Li // Variable explicitly aligned in the declaration should cause an error.
34*67e74705SXin Li __thread non_aligned_struct                bar2 __attribute__(( aligned(64) )); // expected-error{{alignment (64) of thread-local variable}}
35*67e74705SXin Li 
36*67e74705SXin Li // Variable aligned because of one of its fields should cause an error.
37*67e74705SXin Li __thread struct_with_aligned_field         bar3; // expected-error{{alignment (64) of thread-local variable}}
38*67e74705SXin Li 
39*67e74705SXin Li // Variable aligned because of typedef, first case.
40*67e74705SXin Li __thread another_aligned_struct            bar4; // expected-error{{alignment (64) of thread-local variable}}
41*67e74705SXin Li 
42*67e74705SXin Li // Variable aligned because of typedef, second case.
43*67e74705SXin Li __thread yet_another_aligned_struct        bar5; // expected-error{{alignment (64) of thread-local variable}}
44*67e74705SXin Li 
baz()45*67e74705SXin Li int baz ()
46*67e74705SXin Li {
47*67e74705SXin Li     return foo.some_data[0] + bar.some_data[1] + bar2.some_data[2] +
48*67e74705SXin Li            bar3.some_aligned_data[3] + bar4.some_data[4] +
49*67e74705SXin Li            bar5.some_data[5];
50*67e74705SXin Li }
51*67e74705SXin Li 
52*67e74705SXin Li 
53*67e74705SXin Li // Verify alignment check where a dependent type is involved.
54*67e74705SXin Li // The check is (correctly) not performed on "t", but the check still is
55*67e74705SXin Li // performed on the structure as a whole once it has been instantiated.
56*67e74705SXin Li 
57*67e74705SXin Li template<class T> struct templated_tls {
58*67e74705SXin Li     static __thread T t;
59*67e74705SXin Li     T other_t __attribute__(( aligned(64) ));
60*67e74705SXin Li };
61*67e74705SXin Li __thread templated_tls<int> blah; // expected-error{{alignment (64) of thread-local variable}}
62*67e74705SXin Li 
blag()63*67e74705SXin Li int blag() {
64*67e74705SXin Li     return blah.other_t * 2;
65*67e74705SXin Li }
66*67e74705SXin Li 
67*67e74705SXin Li 
68*67e74705SXin Li // Verify alignment check where the alignment is a template parameter.
69*67e74705SXin Li // The check is only performed during instantiation.
70*67e74705SXin Li template <int N>
71*67e74705SXin Li struct S {
72*67e74705SXin Li   static int __thread __attribute__((aligned(N))) x; // expected-error{{alignment (64) of thread-local variable}}
73*67e74705SXin Li };
74*67e74705SXin Li 
75*67e74705SXin Li S<64> s_instance; // expected-note{{in instantiation of template class 'S<64>' requested here}}
76