diff options
Diffstat (limited to 'clang/lib/Sema')
-rw-r--r-- | clang/lib/Sema/SemaDecl.cpp | 30 | ||||
-rw-r--r-- | clang/lib/Sema/SemaDeclAttr.cpp | 4 | ||||
-rw-r--r-- | clang/lib/Sema/SemaOpenMP.cpp | 4 | ||||
-rw-r--r-- | clang/lib/Sema/SemaTemplate.cpp | 3 | ||||
-rw-r--r-- | clang/lib/Sema/SemaTemplateInstantiateDecl.cpp | 2 |
5 files changed, 26 insertions, 17 deletions
diff --git a/clang/lib/Sema/SemaDecl.cpp b/clang/lib/Sema/SemaDecl.cpp index a2c3c2e1472..b3cbbf203e2 100644 --- a/clang/lib/Sema/SemaDecl.cpp +++ b/clang/lib/Sema/SemaDecl.cpp @@ -2953,12 +2953,22 @@ void Sema::MergeVarDecl(VarDecl *New, LookupResult &Previous, return New->setInvalidDecl(); } - if (New->isThreadSpecified() && !Old->isThreadSpecified()) { - Diag(New->getLocation(), diag::err_thread_non_thread) << New->getDeclName(); - Diag(Old->getLocation(), diag::note_previous_definition); - } else if (!New->isThreadSpecified() && Old->isThreadSpecified()) { - Diag(New->getLocation(), diag::err_non_thread_thread) << New->getDeclName(); - Diag(Old->getLocation(), diag::note_previous_definition); + if (New->getTLSKind() != Old->getTLSKind()) { + if (!Old->getTLSKind()) { + Diag(New->getLocation(), diag::err_thread_non_thread) << New->getDeclName(); + Diag(Old->getLocation(), diag::note_previous_declaration); + } else if (!New->getTLSKind()) { + Diag(New->getLocation(), diag::err_non_thread_thread) << New->getDeclName(); + Diag(Old->getLocation(), diag::note_previous_declaration); + } else { + // Do not allow redeclaration to change the variable between requiring + // static and dynamic initialization. + // FIXME: GCC allows this, but uses the TLS keyword on the first + // declaration to determine the kind. Do we need to be compatible here? + Diag(New->getLocation(), diag::err_thread_thread_different_kind) + << New->getDeclName() << (New->getTLSKind() == VarDecl::TLS_Dynamic); + Diag(Old->getLocation(), diag::note_previous_declaration); + } } // C++ doesn't have tentative definitions, so go right ahead and check here. @@ -4577,7 +4587,7 @@ bool Sema::inferObjCARCLifetime(ValueDecl *decl) { if (VarDecl *var = dyn_cast<VarDecl>(decl)) { // Thread-local variables cannot have lifetime. if (lifetime && lifetime != Qualifiers::OCL_ExplicitNone && - var->isThreadSpecified()) { + var->getTLSKind()) { Diag(var->getLocation(), diag::err_arc_thread_ownership) << var->getType(); return true; @@ -4851,9 +4861,9 @@ Sema::ActOnVariableDeclarator(Scope *S, Declarator &D, DeclContext *DC, Diag(D.getDeclSpec().getThreadStorageClassSpecLoc(), diag::err_thread_unsupported); else - // FIXME: Track which thread specifier was used; they have different - // semantics. - NewVD->setThreadSpecified(true); + NewVD->setTLSKind(TSCS == DeclSpec::TSCS_thread_local + ? VarDecl::TLS_Dynamic + : VarDecl::TLS_Static); } // C99 6.7.4p3 diff --git a/clang/lib/Sema/SemaDeclAttr.cpp b/clang/lib/Sema/SemaDeclAttr.cpp index f832809b2df..1fc1a7cc488 100644 --- a/clang/lib/Sema/SemaDeclAttr.cpp +++ b/clang/lib/Sema/SemaDeclAttr.cpp @@ -284,7 +284,7 @@ static bool mayBeSharedVariable(const Decl *D) { if (isa<FieldDecl>(D)) return true; if (const VarDecl *vd = dyn_cast<VarDecl>(D)) - return (vd->hasGlobalStorage() && !(vd->isThreadSpecified())); + return vd->hasGlobalStorage() && !vd->getTLSKind(); return false; } @@ -1656,7 +1656,7 @@ static void handleTLSModelAttr(Sema &S, Decl *D, return; } - if (!isa<VarDecl>(D) || !cast<VarDecl>(D)->isThreadSpecified()) { + if (!isa<VarDecl>(D) || !cast<VarDecl>(D)->getTLSKind()) { S.Diag(Attr.getLoc(), diag::err_attribute_wrong_decl_type) << Attr.getName() << ExpectedTLSVar; return; diff --git a/clang/lib/Sema/SemaOpenMP.cpp b/clang/lib/Sema/SemaOpenMP.cpp index b8acb2d7310..c815d4f9abc 100644 --- a/clang/lib/Sema/SemaOpenMP.cpp +++ b/clang/lib/Sema/SemaOpenMP.cpp @@ -165,8 +165,8 @@ OMPThreadPrivateDecl *Sema::CheckOMPThreadPrivateDecl( continue; } - // Check if threadspecified is set. - if (VD->isThreadSpecified()) { + // Check if this is a TLS variable. + if (VD->getTLSKind()) { Diag(ILoc, diag::err_omp_var_thread_local) << VD; Diag(VD->getLocation(), diag::note_forward_declaration) << VD; continue; diff --git a/clang/lib/Sema/SemaTemplate.cpp b/clang/lib/Sema/SemaTemplate.cpp index 990626189e1..ae091e3da34 100644 --- a/clang/lib/Sema/SemaTemplate.cpp +++ b/clang/lib/Sema/SemaTemplate.cpp @@ -3842,8 +3842,7 @@ CheckTemplateArgumentAddressOfObjectOrFunction(Sema &S, } // A template argument must have static storage duration. - // FIXME: Ensure this works for thread_local as well as __thread. - if (Var->isThreadSpecified()) { + if (Var->getTLSKind()) { S.Diag(Arg->getLocStart(), diag::err_template_arg_thread_local) << Arg->getSourceRange(); S.Diag(Var->getLocation(), diag::note_template_arg_refers_here); diff --git a/clang/lib/Sema/SemaTemplateInstantiateDecl.cpp b/clang/lib/Sema/SemaTemplateInstantiateDecl.cpp index 17e3218bffc..868369e87cd 100644 --- a/clang/lib/Sema/SemaTemplateInstantiateDecl.cpp +++ b/clang/lib/Sema/SemaTemplateInstantiateDecl.cpp @@ -339,7 +339,7 @@ Decl *TemplateDeclInstantiator::VisitVarDecl(VarDecl *D) { D->getLocation(), D->getIdentifier(), DI->getType(), DI, D->getStorageClass()); - Var->setThreadSpecified(D->isThreadSpecified()); + Var->setTLSKind(D->getTLSKind()); Var->setInitStyle(D->getInitStyle()); Var->setCXXForRangeDecl(D->isCXXForRangeDecl()); Var->setConstexpr(D->isConstexpr()); |