Richard Smith | ec64244 | 2013-04-12 22:46:28 +0000 | [diff] [blame] | 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 |
| 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 |
| 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 |
Richard Smith | 6a570f6 | 2013-04-14 20:11:31 +0000 | [diff] [blame] | 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 |
Richard Smith | ec64244 | 2013-04-12 22:46:28 +0000 | [diff] [blame] | 7 | |
| 8 | #ifdef __cplusplus |
| 9 | // In C++, we define __private_extern__ to extern. |
| 10 | #undef __private_extern__ |
| 11 | #endif |
Eli Friedman | f22f77f | 2009-04-19 20:29:08 +0000 | [diff] [blame] | 12 | |
| 13 | __thread int t1; |
Richard Smith | ec64244 | 2013-04-12 22:46:28 +0000 | [diff] [blame] | 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 |
Hans Wennborg | 3af16fd | 2012-06-04 10:19:34 +0000 | [diff] [blame] | 20 | |
Richard Smith | ec64244 | 2013-04-12 22:46:28 +0000 | [diff] [blame] | 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 | #else |
| 46 | // expected-error@-6 {{'thread_local' variables must have global storage}} |
| 47 | #endif |
Hans Wennborg | 3af16fd | 2012-06-04 10:19:34 +0000 | [diff] [blame] | 48 | extern __thread int t9; |
| 49 | static __thread int t10; |
Eli Friedman | f22f77f | 2009-04-19 20:29:08 +0000 | [diff] [blame] | 50 | __thread __private_extern__ int t11; |
Richard Smith | ec64244 | 2013-04-12 22:46:28 +0000 | [diff] [blame] | 51 | #if __cplusplus < 201103L |
| 52 | __thread auto int t12a; // expected-error-re {{cannot combine with previous '(__thread|_Thread_local)' declaration specifier}} |
| 53 | auto __thread int t12b; // expected-error {{cannot combine with previous 'auto' declaration specifier}} |
| 54 | #else |
Richard Smith | 6a570f6 | 2013-04-14 20:11:31 +0000 | [diff] [blame] | 55 | __thread auto t12a = 0; // expected-error-re {{'(t|_T)hread_local' variables must have global storage}} |
| 56 | auto __thread t12b = 0; // expected-error-re {{'(t|_T)hread_local' variables must have global storage}} |
Richard Smith | ec64244 | 2013-04-12 22:46:28 +0000 | [diff] [blame] | 57 | #endif |
| 58 | __thread register int t13a; // expected-error-re {{cannot combine with previous '(__thread|_Thread_local|thread_local)' declaration specifier}} |
| 59 | register __thread int t13b; // expected-error {{cannot combine with previous 'register' declaration specifier}} |
Eli Friedman | f22f77f | 2009-04-19 20:29:08 +0000 | [diff] [blame] | 60 | } |
Hans Wennborg | 3af16fd | 2012-06-04 10:19:34 +0000 | [diff] [blame] | 61 | |
Richard Smith | ec64244 | 2013-04-12 22:46:28 +0000 | [diff] [blame] | 62 | __thread typedef int t14; // expected-error-re {{cannot combine with previous '(__thread|_Thread_local|thread_local)' declaration specifier}} |
Richard Smith | 38afbc7 | 2013-04-13 02:43:54 +0000 | [diff] [blame] | 63 | __thread int t15; // expected-note {{previous declaration is here}} |
Richard Smith | ec64244 | 2013-04-12 22:46:28 +0000 | [diff] [blame] | 64 | extern int t15; // expected-error {{non-thread-local declaration of 't15' follows thread-local declaration}} |
Richard Smith | 38afbc7 | 2013-04-13 02:43:54 +0000 | [diff] [blame] | 65 | extern int t16; // expected-note {{previous declaration is here}} |
Eli Friedman | f22f77f | 2009-04-19 20:29:08 +0000 | [diff] [blame] | 66 | __thread int t16; // expected-error {{thread-local declaration of 't16' follows non-thread-local declaration}} |
Hans Wennborg | 0f87dd7 | 2012-08-29 09:04:10 +0000 | [diff] [blame] | 67 | |
Richard Smith | 38afbc7 | 2013-04-13 02:43:54 +0000 | [diff] [blame] | 68 | #ifdef CXX11 |
| 69 | extern thread_local int t17; // expected-note {{previous declaration is here}} |
| 70 | _Thread_local int t17; // expected-error {{thread-local declaration of 't17' with static initialization follows declaration with dynamic initialization}} |
| 71 | extern _Thread_local int t18; // expected-note {{previous declaration is here}} |
| 72 | thread_local int t18; // expected-error {{thread-local declaration of 't18' with dynamic initialization follows declaration with static initialization}} |
| 73 | #endif |
| 74 | |
Hans Wennborg | 0f87dd7 | 2012-08-29 09:04:10 +0000 | [diff] [blame] | 75 | // PR13720 |
| 76 | __thread int thread_int; |
Richard Smith | ec64244 | 2013-04-12 22:46:28 +0000 | [diff] [blame] | 77 | int *thread_int_ptr = &thread_int; |
| 78 | #ifndef __cplusplus |
| 79 | // expected-error@-2 {{initializer element is not a compile-time constant}} |
| 80 | #endif |
Hans Wennborg | 0f87dd7 | 2012-08-29 09:04:10 +0000 | [diff] [blame] | 81 | void g() { |
| 82 | int *p = &thread_int; // This is perfectly fine, though. |
| 83 | } |
Richard Smith | ec64244 | 2013-04-12 22:46:28 +0000 | [diff] [blame] | 84 | #if __cplusplus >= 201103L |
| 85 | constexpr int *thread_int_ptr_2 = &thread_int; // expected-error {{must be initialized by a constant expression}} |
| 86 | #endif |
Richard Smith | 6a570f6 | 2013-04-14 20:11:31 +0000 | [diff] [blame] | 87 | |
| 88 | int non_const(); |
| 89 | __thread int non_const_init = non_const(); |
| 90 | #if !defined(__cplusplus) |
| 91 | // expected-error@-2 {{initializer element is not a compile-time constant}} |
| 92 | #elif !defined(CXX11) |
| 93 | // expected-error@-4 {{initializer for thread-local variable must be a constant expression}} |
| 94 | #if __cplusplus >= 201103L |
| 95 | // expected-note@-6 {{use 'thread_local' to allow this}} |
| 96 | #endif |
| 97 | #endif |
| 98 | |
| 99 | #ifdef __cplusplus |
| 100 | struct S { |
| 101 | ~S(); |
| 102 | }; |
| 103 | __thread S s; |
| 104 | #if !defined(CXX11) |
| 105 | // expected-error@-2 {{type of thread-local variable has non-trivial destruction}} |
| 106 | #if __cplusplus >= 201103L |
| 107 | // expected-note@-4 {{use 'thread_local' to allow this}} |
| 108 | #endif |
| 109 | #endif |
| 110 | #endif |
Richard Smith | b6b127f | 2013-04-15 08:07:34 +0000 | [diff] [blame^] | 111 | |
| 112 | __thread int aggregate[10] = {0}; |