xref: /llvm-project/clang/test/Sema/tls_alignment.cpp (revision 3b639d7d1d9b9f352c57460deaf70aaad238f8d9)
1 // TLS variable cannot be aligned to more than 32 bytes on PS4.
2 
3 // RUN: %clang_cc1 -triple x86_64-scei-ps4 -std=c++17 -fsyntax-only -verify %s
4 
5 
6 // A non-aligned type.
7 struct non_aligned_struct {
8     int some_data[16]; // 64 bytes of stuff, non aligned.
9 };
10 
11 // An aligned type.
12 struct __attribute__(( aligned(64) )) aligned_struct {
13     int some_data[12]; // 48 bytes of stuff, aligned to 64.
14 };
15 
16 // A type with an aligned field.
17 struct  struct_with_aligned_field {
18     int some_aligned_data[12] __attribute__(( aligned(64) )); // 48 bytes of stuff, aligned to 64.
19 };
20 
21 // A templated type
22 template <typename>
23 struct templated_struct {};
24 // expected-note@-1{{candidate template ignored: couldn't infer template argument ''}}
25 // expected-note@-2{{implicit deduction guide declared as 'template <typename> templated_struct() -> templated_struct<type-parameter-0-0>'}}
26 // expected-note@-3{{candidate function template not viable: requires 1 argument, but 0 were provided}}
27 // expected-note@-4{{implicit deduction guide declared as 'template <typename> templated_struct(templated_struct<type-parameter-0-0>) -> templated_struct<type-parameter-0-0>'}}
28 
29 // A typedef of the aligned struct.
30 typedef aligned_struct another_aligned_struct;
31 
32 // A typedef to redefine a non-aligned struct as aligned.
33 typedef __attribute__(( aligned(64) )) non_aligned_struct yet_another_aligned_struct;
34 
35 // Non aligned variable doesn't cause an error.
36 __thread non_aligned_struct foo;
37 
38 // Variable aligned because of its type should cause an error.
39 __thread aligned_struct                    bar; // expected-error{{alignment (64) of thread-local variable}}
40 
41 // Variable explicitly aligned in the declaration should cause an error.
42 __thread non_aligned_struct                bar2 __attribute__(( aligned(64) )); // expected-error{{alignment (64) of thread-local variable}}
43 
44 // Variable aligned because of one of its fields should cause an error.
45 __thread struct_with_aligned_field         bar3; // expected-error{{alignment (64) of thread-local variable}}
46 
47 // Variable aligned because of typedef, first case.
48 __thread another_aligned_struct            bar4; // expected-error{{alignment (64) of thread-local variable}}
49 
50 // Variable aligned because of typedef, second case.
51 __thread yet_another_aligned_struct        bar5; // expected-error{{alignment (64) of thread-local variable}}
52 
53 // No crash for undeduced type.
54 __thread templated_struct                  bar6; // expected-error{{no viable constructor or deduction guide for deduction of template arguments of 'templated_struct'}}
55 
baz()56 int baz ()
57 {
58     return foo.some_data[0] + bar.some_data[1] + bar2.some_data[2] +
59            bar3.some_aligned_data[3] + bar4.some_data[4] +
60            bar5.some_data[5];
61 }
62 
63 template<class T> struct templated_tls {
64     static __thread T t;
65     T other_t __attribute__(( aligned(64) ));
66 };
67  __thread templated_tls<int> blah; // expected-error{{alignment (64) of thread-local variable}}
68 
69 template <int N>
70 struct S {
71   struct alignas(64) B {};
72   struct alignas(N) C {};
fS73   static inline void f() {
74     thread_local B b; // expected-error{{alignment (64) of thread-local variable}}
75     thread_local C c; // expected-error{{alignment (64) of thread-local variable}}
76   }
77   template<int J> static inline thread_local int b alignas(J) = J; // expected-error{{alignment (64) of thread-local variable}}
78   static int __thread __attribute__((aligned(N))) x; // expected-error{{alignment (64) of thread-local variable}}
79 };
80 
blag()81 int blag() {
82     // Verify alignment check where the alignment is a template parameter.
83     // The check is only performed during instantiation.
84     S<64> s_instance; // expected-note{{in instantiation of template class 'S<64>' requested here}}
85 
86     // Verify alignment for dependent local variables.
87     S<64>::f(); // expected-note{{in instantiation of member function 'S<64>::f' requested here}}
88 
89     // Verify alignment check where a dependent type is involved.
90     // The check is (correctly) not performed on "t", but the check still is
91     // performed on the structure as a whole once it has been instantiated.
92     return blah.other_t * 2 + S<64>::b<64>; // expected-note{{in instantiation of static data member 'S<64>::b' requested here}}
93 }
94