mirror of
https://github.com/capstone-engine/llvm-capstone.git
synced 2025-01-10 18:11:19 +00:00
Avoid patching storage class for block scope thread_local variables.
llvm-svn: 181627
This commit is contained in:
parent
b8a98241fc
commit
28f36ba693
@ -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__
|
||||
|
@ -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
|
||||
|
@ -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;
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user