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()56int 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()81int 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