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 | 6a570f610c101054e79af2fcdb73a10f8e3f337d (patch) | |
tree | 2c427c76ef97f343ba265d9904ec0f1e23111b67 /lib/Sema/SemaDecl.cpp | |
parent | 1ac39c2599b52acbf08e30c93ad358caced9deb5 (diff) |
Diagnose if a __thread or _Thread_local variable has a non-constant initializer
or non-trivial destructor.
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@179491 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/Sema/SemaDecl.cpp')
-rw-r--r-- | lib/Sema/SemaDecl.cpp | 22 |
1 files changed, 22 insertions, 0 deletions
diff --git a/lib/Sema/SemaDecl.cpp b/lib/Sema/SemaDecl.cpp index 52d39d323f..99702bed1c 100644 --- a/lib/Sema/SemaDecl.cpp +++ b/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; |