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