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 |
| 6 | |
| 7 | #ifdef __cplusplus |
| 8 | // In C++, we define __private_extern__ to extern. |
| 9 | #undef __private_extern__ |
| 10 | #endif |
Eli Friedman | f22f77f | 2009-04-19 20:29:08 +0000 | [diff] [blame] | 11 | |
| 12 | __thread int t1; |
Richard Smith | ec64244 | 2013-04-12 22:46:28 +0000 | [diff] [blame] | 13 | __thread extern int t2; |
| 14 | __thread static int t3; |
| 15 | #ifdef GNU |
| 16 | // expected-warning@-3 {{'__thread' before 'extern'}} |
| 17 | // expected-warning@-3 {{'__thread' before 'static'}} |
| 18 | #endif |
Hans Wennborg | 3af16fd | 2012-06-04 10:19:34 +0000 | [diff] [blame] | 19 | |
Richard Smith | ec64244 | 2013-04-12 22:46:28 +0000 | [diff] [blame] | 20 | __thread __private_extern__ int t4; |
| 21 | struct t5 { __thread int x; }; |
| 22 | #ifdef __cplusplus |
| 23 | // expected-error-re@-2 {{'(__thread|_Thread_local|thread_local)' is only allowed on variable declarations}} |
| 24 | #else |
| 25 | // FIXME: The 'is only allowed on variable declarations' diagnostic is better here. |
| 26 | // expected-error@-5 {{type name does not allow storage class to be specified}} |
| 27 | #endif |
| 28 | |
| 29 | __thread int t6(); |
| 30 | #if defined(GNU) |
| 31 | // expected-error@-2 {{'__thread' is only allowed on variable declarations}} |
| 32 | #elif defined(C11) |
| 33 | // expected-error@-4 {{'_Thread_local' is only allowed on variable declarations}} |
| 34 | #else |
| 35 | // expected-error@-6 {{'thread_local' is only allowed on variable declarations}} |
| 36 | #endif |
| 37 | |
| 38 | int f(__thread int t7) { // expected-error {{' is only allowed on variable declarations}} |
| 39 | __thread int t8; |
| 40 | #if defined(GNU) |
| 41 | // expected-error@-2 {{'__thread' variables must have global storage}} |
| 42 | #elif defined(C11) |
| 43 | // expected-error@-4 {{'_Thread_local' variables must have global storage}} |
| 44 | #else |
| 45 | // expected-error@-6 {{'thread_local' variables must have global storage}} |
| 46 | #endif |
Hans Wennborg | 3af16fd | 2012-06-04 10:19:34 +0000 | [diff] [blame] | 47 | extern __thread int t9; |
| 48 | static __thread int t10; |
Eli Friedman | f22f77f | 2009-04-19 20:29:08 +0000 | [diff] [blame] | 49 | __thread __private_extern__ int t11; |
Richard Smith | ec64244 | 2013-04-12 22:46:28 +0000 | [diff] [blame] | 50 | #if __cplusplus < 201103L |
| 51 | __thread auto int t12a; // expected-error-re {{cannot combine with previous '(__thread|_Thread_local)' declaration specifier}} |
| 52 | auto __thread int t12b; // expected-error {{cannot combine with previous 'auto' declaration specifier}} |
| 53 | #else |
| 54 | __thread auto t12a = 0; // expected-error {{'thread_local' variables must have global storage}} |
| 55 | auto __thread t12b = 0; // expected-error {{'thread_local' variables must have global storage}} |
| 56 | #endif |
| 57 | __thread register int t13a; // expected-error-re {{cannot combine with previous '(__thread|_Thread_local|thread_local)' declaration specifier}} |
| 58 | 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] | 59 | } |
Hans Wennborg | 3af16fd | 2012-06-04 10:19:34 +0000 | [diff] [blame] | 60 | |
Richard Smith | ec64244 | 2013-04-12 22:46:28 +0000 | [diff] [blame] | 61 | __thread typedef int t14; // expected-error-re {{cannot combine with previous '(__thread|_Thread_local|thread_local)' declaration specifier}} |
Richard Trieu | 2fe9b7f | 2011-12-15 00:38:15 +0000 | [diff] [blame] | 62 | __thread int t15; // expected-note {{previous definition is here}} |
Richard Smith | ec64244 | 2013-04-12 22:46:28 +0000 | [diff] [blame] | 63 | extern int t15; // expected-error {{non-thread-local declaration of 't15' follows thread-local declaration}} |
| 64 | extern int t16; // expected-note {{previous definition is here}} |
Eli Friedman | f22f77f | 2009-04-19 20:29:08 +0000 | [diff] [blame] | 65 | __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] | 66 | |
| 67 | // PR13720 |
| 68 | __thread int thread_int; |
Richard Smith | ec64244 | 2013-04-12 22:46:28 +0000 | [diff] [blame] | 69 | int *thread_int_ptr = &thread_int; |
| 70 | #ifndef __cplusplus |
| 71 | // expected-error@-2 {{initializer element is not a compile-time constant}} |
| 72 | #endif |
Hans Wennborg | 0f87dd7 | 2012-08-29 09:04:10 +0000 | [diff] [blame] | 73 | void g() { |
| 74 | int *p = &thread_int; // This is perfectly fine, though. |
| 75 | } |
Richard Smith | ec64244 | 2013-04-12 22:46:28 +0000 | [diff] [blame] | 76 | #if __cplusplus >= 201103L |
| 77 | constexpr int *thread_int_ptr_2 = &thread_int; // expected-error {{must be initialized by a constant expression}} |
| 78 | #endif |