1 | // RUN: %clang_cc1 -triple i686-pc-linux-gnu -fsyntax-only -Wno-private-extern -verify -pedantic %s -DGNU |
2 | // RUN: %clang_cc1 -triple i686-pc-linux-gnu -fsyntax-only -Wno-private-extern -verify -pedantic -x c++ %s -DGNU -std=c++98 |
3 | // RUN: %clang_cc1 -triple i686-pc-linux-gnu -fsyntax-only -Wno-private-extern -verify -pedantic %s -DC11 -D__thread=_Thread_local |
4 | // RUN: %clang_cc1 -triple i686-pc-linux-gnu -fsyntax-only -Wno-private-extern -verify -pedantic -x c++ %s -DC11 -D__thread=_Thread_local -std=c++98 |
5 | // RUN: %clang_cc1 -triple i686-pc-linux-gnu -fsyntax-only -Wno-private-extern -verify -pedantic -x c++ %s -DCXX11 -D__thread=thread_local -std=c++11 -Wno-deprecated |
6 | // RUN: %clang_cc1 -triple i686-pc-linux-gnu -fsyntax-only -Wno-private-extern -verify -pedantic -x c++ %s -DC11 -D__thread=_Thread_local -std=c++11 -Wno-deprecated |
7 | |
8 | #ifdef __cplusplus |
9 | // In C++, we define __private_extern__ to extern. |
10 | #undef __private_extern__ |
11 | #endif |
12 | |
13 | __thread int t1; |
14 | __thread extern int t2; |
15 | __thread static int t3; |
16 | #ifdef GNU |
17 | // expected-warning@-3 {{'__thread' before 'extern'}} |
18 | // expected-warning@-3 {{'__thread' before 'static'}} |
19 | #endif |
20 | |
21 | __thread __private_extern__ int t4; |
22 | struct t5 { __thread int x; }; |
23 | #ifdef __cplusplus |
24 | // expected-error-re@-2 {{'{{__thread|_Thread_local|thread_local}}' is only allowed on variable declarations}} |
25 | #else |
26 | // FIXME: The 'is only allowed on variable declarations' diagnostic is better here. |
27 | // expected-error@-5 {{type name does not allow storage class to be specified}} |
28 | #endif |
29 | |
30 | __thread int t6(); |
31 | #if defined(GNU) |
32 | // expected-error@-2 {{'__thread' is only allowed on variable declarations}} |
33 | #elif defined(C11) |
34 | // expected-error@-4 {{'_Thread_local' is only allowed on variable declarations}} |
35 | #else |
36 | // expected-error@-6 {{'thread_local' is only allowed on variable declarations}} |
37 | #endif |
38 | |
39 | int f(__thread int t7) { // expected-error {{' is only allowed on variable declarations}} |
40 | __thread int t8; |
41 | #if defined(GNU) |
42 | // expected-error@-2 {{'__thread' variables must have global storage}} |
43 | #elif defined(C11) |
44 | // expected-error@-4 {{'_Thread_local' variables must have global storage}} |
45 | #endif |
46 | extern __thread int t9; |
47 | static __thread int t10; |
48 | __thread __private_extern__ int t11; |
49 | #if __cplusplus < 201103L |
50 | __thread auto int t12a; // expected-error-re {{cannot combine with previous '{{__thread|_Thread_local}}' declaration specifier}} |
51 | auto __thread int t12b; // expected-error {{cannot combine with previous 'auto' declaration specifier}} |
52 | #elif !defined(CXX11) |
53 | __thread auto t12a = 0; // expected-error {{'_Thread_local' variables must have global storage}} |
54 | auto __thread t12b = 0; // expected-error {{'_Thread_local' variables must have global storage}} |
55 | #endif |
56 | __thread register int t13a; // expected-error-re {{cannot combine with previous '{{__thread|_Thread_local|thread_local}}' declaration specifier}} |
57 | register __thread int t13b; // expected-error {{cannot combine with previous 'register' declaration specifier}} |
58 | } |
59 | |
60 | __thread typedef int t14; // expected-error-re {{cannot combine with previous '{{__thread|_Thread_local|thread_local}}' declaration specifier}} |
61 | __thread int t15; // expected-note {{previous definition is here}} |
62 | extern int t15; // expected-error {{non-thread-local declaration of 't15' follows thread-local declaration}} |
63 | extern int t16; // expected-note {{previous declaration is here}} |
64 | __thread int t16; // expected-error {{thread-local declaration of 't16' follows non-thread-local declaration}} |
65 | |
66 | #ifdef CXX11 |
67 | extern thread_local int t17; // expected-note {{previous declaration is here}} |
68 | _Thread_local int t17; // expected-error {{thread-local declaration of 't17' with static initialization follows declaration with dynamic initialization}} |
69 | extern _Thread_local int t18; // expected-note {{previous declaration is here}} |
70 | thread_local int t18; // expected-error {{thread-local declaration of 't18' with dynamic initialization follows declaration with static initialization}} |
71 | #endif |
72 | |
73 | // PR13720 |
74 | __thread int thread_int; |
75 | int *thread_int_ptr = &thread_int; |
76 | #ifndef __cplusplus |
77 | // expected-error@-2 {{initializer element is not a compile-time constant}} |
78 | #endif |
79 | void g() { |
80 | int *p = &thread_int; // This is perfectly fine, though. |
81 | } |
82 | #if __cplusplus >= 201103L |
83 | constexpr int *thread_int_ptr_2 = &thread_int; // expected-error {{must be initialized by a constant expression}} |
84 | #endif |
85 | |
86 | int non_const(); |
87 | __thread int non_const_init = non_const(); |
88 | #if !defined(__cplusplus) |
89 | // expected-error@-2 {{initializer element is not a compile-time constant}} |
90 | #elif !defined(CXX11) |
91 | // expected-error@-4 {{initializer for thread-local variable must be a constant expression}} |
92 | #if __cplusplus >= 201103L |
93 | // expected-note@-6 {{use 'thread_local' to allow this}} |
94 | #endif |
95 | #endif |
96 | |
97 | #ifdef __cplusplus |
98 | struct S { |
99 | ~S(); |
100 | }; |
101 | __thread S s; |
102 | #if !defined(CXX11) |
103 | // expected-error@-2 {{type of thread-local variable has non-trivial destruction}} |
104 | #if __cplusplus >= 201103L |
105 | // expected-note@-4 {{use 'thread_local' to allow this}} |
106 | #endif |
107 | #endif |
108 | #endif |
109 | |
110 | #ifdef __cplusplus |
111 | struct HasCtor { |
112 | HasCtor(); |
113 | }; |
114 | __thread HasCtor var_with_ctor; |
115 | #if !defined(CXX11) |
116 | // expected-error@-2 {{initializer for thread-local variable must be a constant expression}} |
117 | #if __cplusplus >= 201103L |
118 | // expected-note@-4 {{use 'thread_local' to allow this}} |
119 | #endif |
120 | #endif |
121 | #endif |
122 | |
123 | __thread int aggregate[10] = {0}; |
124 | |