diff options
author | Alexey Bataev <a.bataev@hotmail.com> | 2014-05-28 07:40:25 +0000 |
---|---|---|
committer | Alexey Bataev <a.bataev@hotmail.com> | 2014-05-28 07:40:25 +0000 |
commit | 18b92eeacb23d8845b0d0934de71ce4986d0c7f7 (patch) | |
tree | 8fead6e73b226b1a68f767461b86952e765f1b90 /clang/lib/Sema/SemaOpenMP.cpp | |
parent | 7c747fc7c62606f1736aa114328eaeec7981052b (diff) | |
download | bcm5719-llvm-18b92eeacb23d8845b0d0934de71ce4986d0c7f7.tar.gz bcm5719-llvm-18b92eeacb23d8845b0d0934de71ce4986d0c7f7.zip |
[OPENMP] Additional checking for local vars in initial values for threadprivate vars
llvm-svn: 209716
Diffstat (limited to 'clang/lib/Sema/SemaOpenMP.cpp')
-rw-r--r-- | clang/lib/Sema/SemaOpenMP.cpp | 36 |
1 files changed, 36 insertions, 0 deletions
diff --git a/clang/lib/Sema/SemaOpenMP.cpp b/clang/lib/Sema/SemaOpenMP.cpp index 603dd56c4fe..e616232540b 100644 --- a/clang/lib/Sema/SemaOpenMP.cpp +++ b/clang/lib/Sema/SemaOpenMP.cpp @@ -553,6 +553,35 @@ Sema::ActOnOpenMPThreadprivateDirective(SourceLocation Loc, return DeclGroupPtrTy(); } +namespace { +class LocalVarRefChecker : public ConstStmtVisitor<LocalVarRefChecker, bool> { + Sema &SemaRef; + +public: + bool VisitDeclRefExpr(const DeclRefExpr *E) { + if (auto VD = dyn_cast<VarDecl>(E->getDecl())) { + if (VD->hasLocalStorage()) { + SemaRef.Diag(E->getLocStart(), + diag::err_omp_local_var_in_threadprivate_init) + << E->getSourceRange(); + SemaRef.Diag(VD->getLocation(), diag::note_defined_here) + << VD << VD->getSourceRange(); + return true; + } + } + return false; + } + bool VisitStmt(const Stmt *S) { + for (auto Child : S->children()) { + if (Child && Visit(Child)) + return true; + } + return false; + } + LocalVarRefChecker(Sema &SemaRef) : SemaRef(SemaRef) {} +}; +} // namespace + OMPThreadPrivateDecl * Sema::CheckOMPThreadPrivateDecl(SourceLocation Loc, ArrayRef<Expr *> VarList) { SmallVector<Expr *, 8> Vars; @@ -592,6 +621,13 @@ Sema::CheckOMPThreadPrivateDecl(SourceLocation Loc, ArrayRef<Expr *> VarList) { continue; } + // Check if initial value of threadprivate variable reference variable with + // local storage (it is not supported by runtime). + if (auto Init = VD->getAnyInitializer()) { + LocalVarRefChecker Checker(*this); + if (Checker.Visit(Init)) continue; + } + Vars.push_back(RefExpr); DSAStack->addDSA(VD, DE, OMPC_threadprivate); } |