diff options
author | Richard Smith <richard-llvm@metafoo.co.uk> | 2013-04-14 20:11:31 +0000 |
---|---|---|
committer | Richard Smith <richard-llvm@metafoo.co.uk> | 2013-04-14 20:11:31 +0000 |
commit | 6ea1a4d1dcd6fbde9e002ff19723b0ae5f3e9a0f (patch) | |
tree | 7b88c24157f7b65187b1008c6a1bc7515a8552b2 /clang/lib | |
parent | 1ebded0a119e7c453f3fdfeb57b26cc00d4653ad (diff) | |
download | bcm5719-llvm-6ea1a4d1dcd6fbde9e002ff19723b0ae5f3e9a0f.tar.gz bcm5719-llvm-6ea1a4d1dcd6fbde9e002ff19723b0ae5f3e9a0f.zip |
Diagnose if a __thread or _Thread_local variable has a non-constant initializer
or non-trivial destructor.
llvm-svn: 179491
Diffstat (limited to 'clang/lib')
-rw-r--r-- | clang/lib/Sema/SemaDecl.cpp | 22 |
1 files changed, 22 insertions, 0 deletions
diff --git a/clang/lib/Sema/SemaDecl.cpp b/clang/lib/Sema/SemaDecl.cpp index 52d39d323fe..99702bed1cc 100644 --- a/clang/lib/Sema/SemaDecl.cpp +++ b/clang/lib/Sema/SemaDecl.cpp @@ -7627,6 +7627,18 @@ void Sema::AddInitializerToDecl(Decl *RealDecl, Expr *Init, // C99 6.7.8p4. All file scoped initializers need to be constant. if (!getLangOpts().CPlusPlus && !VDecl->isInvalidDecl()) CheckForConstantInitializer(Init, DclT); + else if (VDecl->getTLSKind() == VarDecl::TLS_Static && + !VDecl->isInvalidDecl() && !DclT->isDependentType() && + !Init->isValueDependent() && !VDecl->isConstexpr() && + !Init->isEvaluatable(Context)) { + // GNU C++98 edits for __thread, [basic.start.init]p4: + // An object of thread storage duration shall not require dynamic + // initialization. + // FIXME: Need strict checking here. + Diag(VDecl->getLocation(), diag::err_thread_dynamic_init); + if (getLangOpts().CPlusPlus11) + Diag(VDecl->getLocation(), diag::note_use_thread_local); + } } // We will represent direct-initialization similarly to copy-initialization: @@ -7972,6 +7984,16 @@ void Sema::CheckCompleteVariableDeclaration(VarDecl *var) { Diag(var->getLocation(), diag::warn_missing_variable_declarations) << var; } + if (var->getTLSKind() == VarDecl::TLS_Static && + var->getType().isDestructedType()) { + // GNU C++98 edits for __thread, [basic.start.term]p3: + // The type of an object with thread storage duration shall not + // have a non-trivial destructor. + Diag(var->getLocation(), diag::err_thread_nontrivial_dtor); + if (getLangOpts().CPlusPlus11) + Diag(var->getLocation(), diag::note_use_thread_local); + } + // All the following checks are C++ only. if (!getLangOpts().CPlusPlus) return; |