]> granicus.if.org Git - clang/commitdiff
Avoid patching storage class for block scope thread_local variables.
authorEnea Zaffanella <zaffanella@cs.unipr.it>
Fri, 10 May 2013 20:34:44 +0000 (20:34 +0000)
committerEnea Zaffanella <zaffanella@cs.unipr.it>
Fri, 10 May 2013 20:34:44 +0000 (20:34 +0000)
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@181627 91177308-0d34-0410-b5e6-96231b3b80d8

include/clang/AST/Decl.h
lib/Sema/SemaDecl.cpp
test/SemaCXX/cxx11-thread-local-print.cpp

index a0c76c069b863cd2e1f65bc13837cf9e3200e322..d5e6ebee4a707a60c9e02143f2dff6ccdbdab0df 100644 (file)
@@ -797,7 +797,8 @@ public:
   ///  is a non-static local variable.
   bool hasLocalStorage() const {
     if (getStorageClass() == SC_None)
-      return !isFileVarDecl();
+      // Second check is for C++11 [dcl.stc]p4.
+      return !isFileVarDecl() && getTSCSpec() != TSCS_thread_local;
 
     // Return true for:  Auto, Register.
     // Return false for: Extern, Static, PrivateExtern, OpenCLWorkGroupLocal.
@@ -808,7 +809,10 @@ public:
   /// isStaticLocal - Returns true if a variable with function scope is a
   /// static local variable.
   bool isStaticLocal() const {
-    return getStorageClass() == SC_Static && !isFileVarDecl();
+    return (getStorageClass() == SC_Static ||
+            // C++11 [dcl.stc]p4
+            (getStorageClass() == SC_None && getTSCSpec() == TSCS_thread_local))
+      && !isFileVarDecl();
   }
 
   /// \brief Returns true if a variable has extern or __private_extern__
index d14b10559d9a4a12d6b08e68ca1675ab13033e8a..5d8839a65b2d96394e757ea63dbe5529115dbf32 100644 (file)
@@ -4718,16 +4718,6 @@ Sema::ActOnVariableDeclarator(Scope *S, Declarator &D, DeclContext *DC,
     SC = SC_None;
   }
 
-  // C++11 [dcl.stc]p4:
-  //   When thread_local is applied to a variable of block scope the
-  //   storage-class-specifier static is implied if it does not appear
-  //   explicitly.
-  // Core issue: 'static' is not implied if the variable is declared 'extern'.
-  if (SCSpec == DeclSpec::SCS_unspecified &&
-      D.getDeclSpec().getThreadStorageClassSpec() ==
-          DeclSpec::TSCS_thread_local && DC->isFunctionOrMethod())
-    SC = SC_Static;
-
   IdentifierInfo *II = Name.getAsIdentifierInfo();
   if (!II) {
     Diag(D.getIdentifierLoc(), diag::err_bad_variable_name)
@@ -4885,11 +4875,22 @@ Sema::ActOnVariableDeclarator(Scope *S, Declarator &D, DeclContext *DC,
   NewVD->setLexicalDeclContext(CurContext);
 
   if (DeclSpec::TSCS TSCS = D.getDeclSpec().getThreadStorageClassSpec()) {
-    if (NewVD->hasLocalStorage())
-      Diag(D.getDeclSpec().getThreadStorageClassSpecLoc(),
-           diag::err_thread_non_global)
-        << DeclSpec::getSpecifierName(TSCS);
-    else if (!Context.getTargetInfo().isTLSSupported())
+    if (NewVD->hasLocalStorage()) {
+      // C++11 [dcl.stc]p4:
+      //   When thread_local is applied to a variable of block scope the
+      //   storage-class-specifier static is implied if it does not appear
+      //   explicitly.
+      // Core issue: 'static' is not implied if the variable is declared
+      //   'extern'.
+      if (SCSpec == DeclSpec::SCS_unspecified &&
+          TSCS == DeclSpec::TSCS_thread_local &&
+          DC->isFunctionOrMethod())
+        NewVD->setTSCSpec(TSCS);
+      else
+        Diag(D.getDeclSpec().getThreadStorageClassSpecLoc(),
+             diag::err_thread_non_global)
+          << DeclSpec::getSpecifierName(TSCS);
+    } else if (!Context.getTargetInfo().isTLSSupported())
       Diag(D.getDeclSpec().getThreadStorageClassSpecLoc(),
            diag::err_thread_unsupported);
     else
@@ -5237,7 +5238,7 @@ void Sema::CheckVariableDeclarationType(VarDecl *NewVD) {
       if (NewVD->isFileVarDecl())
         Diag(NewVD->getLocation(), diag::err_vla_decl_in_file_scope)
         << SizeRange;
-      else if (NewVD->getStorageClass() == SC_Static)
+      else if (NewVD->isStaticLocal())
         Diag(NewVD->getLocation(), diag::err_vla_decl_has_static_storage)
         << SizeRange;
       else
index 9d9a82b7e6a49147e8cbc164aff8510803e2d5e5..1adafbda4905c340f77b137165809e1243ed4ed9 100644 (file)
@@ -7,3 +7,9 @@ __thread int gnu_tl;
 _Thread_local int c11_tl;
 thread_local int cxx11_tl;
 
+// CHECK: void foo() {
+// CHECK:     thread_local int cxx11_tl;
+// CHECK: }
+void foo() {
+    thread_local int cxx11_tl;
+}