reference, declarationdefinition
definition → references, declarations, derived classes, virtual overrides
reference to multiple definitions → definitions
unreferenced
    1
    2
    3
    4
    5
    6
    7
    8
    9
   10
   11
   12
   13
   14
   15
   16
   17
   18
   19
   20
   21
   22
   23
   24
   25
   26
   27
   28
   29
   30
   31
   32
   33
   34
   35
   36
   37
   38
   39
   40
   41
   42
   43
   44
   45
   46
   47
   48
   49
   50
   51
   52
   53
   54
   55
   56
   57
   58
   59
   60
   61
   62
   63
   64
   65
   66
   67
   68
   69
   70
   71
   72
   73
   74
   75
   76
   77
   78
   79
   80
   81
   82
   83
   84
   85
   86
   87
   88
   89
   90
   91
   92
   93
   94
   95
   96
   97
   98
   99
  100
  101
  102
  103
  104
  105
  106
  107
  108
  109
  110
  111
  112
  113
  114
  115
  116
  117
  118
  119
  120
  121
  122
  123
  124
  125
  126
  127
  128
  129
  130
  131
  132
  133
  134
  135
  136
// RUN: %clang_cc1 -triple i686-pc-linux-gnu -fsyntax-only -Wno-private-extern -verify -pedantic %s -DGNU
// RUN: %clang_cc1 -triple i686-pc-linux-gnu -fsyntax-only -Wno-private-extern -verify -pedantic -x c++ %s -DGNU -std=c++98
// RUN: %clang_cc1 -triple i686-pc-linux-gnu -fsyntax-only -Wno-private-extern -verify -pedantic %s -std=c11 -DC11 -D__thread=_Thread_local
// RUN: %clang_cc1 -triple i686-pc-linux-gnu -fsyntax-only -Wno-private-extern -verify=expected,thread-local -pedantic -x c++ %s -DC11 -D__thread=_Thread_local -std=c++98
// 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
// RUN: %clang_cc1 -triple i686-pc-linux-gnu -fsyntax-only -Wno-private-extern -verify=expected,thread-local -pedantic -x c++ %s -DC11 -D__thread=_Thread_local -std=c++11 -Wno-deprecated
// RUN: %clang_cc1 -triple i686-pc-linux-gnu -fsyntax-only -Wno-private-extern -verify=expected,thread-local -pedantic %s -std=c99 -D__thread=_Thread_local -DC99

#ifdef __cplusplus
// In C++, we define __private_extern__ to extern.
#undef __private_extern__
#endif

__thread int t1; // thread-local-warning {{'_Thread_local' is a C11 extension}}
__thread extern int t2; // thread-local-warning {{'_Thread_local' is a C11 extension}}
__thread static int t3; // thread-local-warning {{'_Thread_local' is a C11 extension}}
#ifdef GNU
// expected-warning@-3 {{'__thread' before 'extern'}}
// expected-warning@-3 {{'__thread' before 'static'}}
#endif

__thread __private_extern__ int t4; // thread-local-warning {{'_Thread_local' is a C11 extension}}
struct t5 { __thread int x; }; // thread-local-warning {{'_Thread_local' is a C11 extension}}
#ifdef __cplusplus
// expected-error-re@-2 {{'{{__thread|_Thread_local|thread_local}}' is only allowed on variable declarations}}
#else
// FIXME: The 'is only allowed on variable declarations' diagnostic is better here.
// expected-error@-5 {{type name does not allow storage class to be specified}}
#endif

__thread int t6(); // thread-local-warning {{'_Thread_local' is a C11 extension}}
#if defined(GNU)
// expected-error@-2 {{'__thread' is only allowed on variable declarations}}
#elif defined(C11) || defined(C99)
// expected-error@-4 {{'_Thread_local' is only allowed on variable declarations}}
#else
// expected-error@-6 {{'thread_local' is only allowed on variable declarations}}
#endif

int f(__thread int t7) { // expected-error {{' is only allowed on variable declarations}} \
                         // thread-local-warning {{'_Thread_local' is a C11 extension}}
  __thread int t8; // thread-local-warning {{'_Thread_local' is a C11 extension}}
#if defined(GNU)
  // expected-error@-2 {{'__thread' variables must have global storage}}
#elif defined(C11) || defined(C99)
  // expected-error@-4 {{'_Thread_local' variables must have global storage}}
#endif
  extern __thread int t9; // thread-local-warning {{'_Thread_local' is a C11 extension}}
  static __thread int t10; // thread-local-warning {{'_Thread_local' is a C11 extension}}
  __thread __private_extern__ int t11; // thread-local-warning {{'_Thread_local' is a C11 extension}}
#if __cplusplus < 201103L
  __thread auto int t12a; // expected-error-re {{cannot combine with previous '{{__thread|_Thread_local}}' declaration specifier}} \
                          // thread-local-warning {{'_Thread_local' is a C11 extension}}
  auto __thread int t12b; // expected-error {{cannot combine with previous 'auto' declaration specifier}} \
                          // thread-local-warning {{'_Thread_local' is a C11 extension}}
#elif !defined(CXX11)
  __thread auto t12a = 0; // expected-error {{'_Thread_local' variables must have global storage}} \
                          // thread-local-warning {{'_Thread_local' is a C11 extension}}
  auto __thread t12b = 0; // expected-error {{'_Thread_local' variables must have global storage}} \
                          // thread-local-warning {{'_Thread_local' is a C11 extension}}
#endif
  __thread register int t13a; // expected-error-re {{cannot combine with previous '{{__thread|_Thread_local|thread_local}}' declaration specifier}} \
                              // thread-local-warning {{'_Thread_local' is a C11 extension}}
  register __thread int t13b; // expected-error {{cannot combine with previous 'register' declaration specifier}} \
                              // thread-local-warning {{'_Thread_local' is a C11 extension}}
}

__thread typedef int t14; // expected-error-re {{cannot combine with previous '{{__thread|_Thread_local|thread_local}}' declaration specifier}} \
                          // thread-local-warning {{'_Thread_local' is a C11 extension}}
__thread int t15; // expected-note {{previous definition is here}} \
                  // thread-local-warning {{'_Thread_local' is a C11 extension}}
extern int t15; // expected-error {{non-thread-local declaration of 't15' follows thread-local declaration}}
extern int t16; // expected-note {{previous declaration is here}}
__thread int t16; // expected-error {{thread-local declaration of 't16' follows non-thread-local declaration}} \
                  // thread-local-warning {{'_Thread_local' is a C11 extension}}

#ifdef CXX11
extern thread_local int t17; // expected-note {{previous declaration is here}}
_Thread_local int t17; // expected-error {{thread-local declaration of 't17' with static initialization follows declaration with dynamic initialization}} \
                       // expected-warning {{'_Thread_local' is a C11 extension}}
extern _Thread_local int t18; // expected-note {{previous declaration is here}} \
                              // expected-warning {{'_Thread_local' is a C11 extension}}
thread_local int t18; // expected-error {{thread-local declaration of 't18' with dynamic initialization follows declaration with static initialization}}
#endif

// PR13720
__thread int thread_int; // thread-local-warning {{'_Thread_local' is a C11 extension}}
int *thread_int_ptr = &thread_int;
#ifndef __cplusplus
// expected-error@-2 {{initializer element is not a compile-time constant}}
#endif
void g() {
  int *p = &thread_int; // This is perfectly fine, though.
}
#if __cplusplus >= 201103L
constexpr int *thread_int_ptr_2 = &thread_int; // expected-error {{must be initialized by a constant expression}}
#endif

int non_const();
__thread int non_const_init = non_const(); // thread-local-warning {{'_Thread_local' is a C11 extension}}
#if !defined(__cplusplus)
// expected-error@-2 {{initializer element is not a compile-time constant}}
#elif !defined(CXX11)
// expected-error@-4 {{initializer for thread-local variable must be a constant expression}}
#if __cplusplus >= 201103L
// expected-note@-6 {{use 'thread_local' to allow this}}
#endif
#endif

#ifdef __cplusplus
struct S {
  ~S();
};
__thread S s; // thread-local-warning {{'_Thread_local' is a C11 extension}}
#if !defined(CXX11)
// expected-error@-2 {{type of thread-local variable has non-trivial destruction}}
#if __cplusplus >= 201103L
// expected-note@-4 {{use 'thread_local' to allow this}}
#endif
#endif
#endif

#ifdef __cplusplus
struct HasCtor {
  HasCtor();
};
__thread HasCtor var_with_ctor; // thread-local-warning {{'_Thread_local' is a C11 extension}}
#if !defined(CXX11)
// expected-error@-2 {{initializer for thread-local variable must be a constant expression}}
#if __cplusplus >= 201103L
// expected-note@-4 {{use 'thread_local' to allow this}}
#endif
#endif
#endif

__thread int aggregate[10] = {0}; // thread-local-warning {{'_Thread_local' is a C11 extension}}