diff options
author | Enea Zaffanella <zaffanella@cs.unipr.it> | 2013-05-10 20:34:44 +0000 |
---|---|---|
committer | Enea Zaffanella <zaffanella@cs.unipr.it> | 2013-05-10 20:34:44 +0000 |
commit | 28f36ba693841146514e7f4c11112827587f1952 (patch) | |
tree | 7e77546b31d3d74e3ef0d5c3b926f67c61687a80 | |
parent | b8a98241fce39b598799e4d2c79540e79e408b76 (diff) | |
download | bcm5719-llvm-28f36ba693841146514e7f4c11112827587f1952.tar.gz bcm5719-llvm-28f36ba693841146514e7f4c11112827587f1952.zip |
Avoid patching storage class for block scope thread_local variables.
llvm-svn: 181627
-rw-r--r-- | clang/include/clang/AST/Decl.h | 8 | ||||
-rw-r--r-- | clang/lib/Sema/SemaDecl.cpp | 33 | ||||
-rw-r--r-- | clang/test/SemaCXX/cxx11-thread-local-print.cpp | 6 |
3 files changed, 29 insertions, 18 deletions
diff --git a/clang/include/clang/AST/Decl.h b/clang/include/clang/AST/Decl.h index a0c76c069b8..d5e6ebee4a7 100644 --- a/clang/include/clang/AST/Decl.h +++ b/clang/include/clang/AST/Decl.h @@ -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__ diff --git a/clang/lib/Sema/SemaDecl.cpp b/clang/lib/Sema/SemaDecl.cpp index d14b10559d9..5d8839a65b2 100644 --- a/clang/lib/Sema/SemaDecl.cpp +++ b/clang/lib/Sema/SemaDecl.cpp @@ -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 diff --git a/clang/test/SemaCXX/cxx11-thread-local-print.cpp b/clang/test/SemaCXX/cxx11-thread-local-print.cpp index 9d9a82b7e6a..1adafbda490 100644 --- a/clang/test/SemaCXX/cxx11-thread-local-print.cpp +++ b/clang/test/SemaCXX/cxx11-thread-local-print.cpp @@ -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; +} |