aboutsummaryrefslogtreecommitdiff
path: root/lib/Sema/SemaDecl.cpp
diff options
context:
space:
mode:
authorRichard Smith <richard-llvm@metafoo.co.uk>2013-04-14 20:11:31 +0000
committerRichard Smith <richard-llvm@metafoo.co.uk>2013-04-14 20:11:31 +0000
commit6a570f610c101054e79af2fcdb73a10f8e3f337d (patch)
tree2c427c76ef97f343ba265d9904ec0f1e23111b67 /lib/Sema/SemaDecl.cpp
parent1ac39c2599b52acbf08e30c93ad358caced9deb5 (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.cpp22
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;