Skip to content
This repository has been archived by the owner on Apr 23, 2020. It is now read-only.

Commit

Permalink
[OPENMP] Additional checking for local vars in initial values for thr…
Browse files Browse the repository at this point in the history
…eadprivate vars

git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@209716 91177308-0d34-0410-b5e6-96231b3b80d8
  • Loading branch information
alexey-bataev committed May 28, 2014
1 parent bf9865f commit 9e6a299
Show file tree
Hide file tree
Showing 3 changed files with 41 additions and 1 deletion.
2 changes: 2 additions & 0 deletions include/clang/Basic/DiagnosticSemaKinds.td
Expand Up @@ -6956,6 +6956,8 @@ def err_omp_linear_expected_int_or_ptr : Error<
def warn_omp_linear_step_zero : Warning<
"zero linear step (%0 %select{|and other variables in clause }1should probably be const)">,
InGroup<OpenMPClauses>;
def err_omp_local_var_in_threadprivate_init : Error<
"variable with local storage in initial value of threadprivate variable">;
} // end of OpenMP category

let CategoryName = "Related Result Type Issue" in {
Expand Down
36 changes: 36 additions & 0 deletions lib/Sema/SemaOpenMP.cpp
Expand Up @@ -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;
Expand Down Expand Up @@ -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);
}
Expand Down
4 changes: 3 additions & 1 deletion test/OpenMP/threadprivate_messages.cpp
Expand Up @@ -108,10 +108,12 @@ int o; // expected-note {{candidate found by name lookup is '(anonymous namespac

int main(int argc, char **argv) { // expected-note {{'argc' defined here}}

int x, y = argc; // expected-note {{'y' defined here}}
int x, y = argc; // expected-note 2 {{'y' defined here}}
static double d1;
static double d2;
static double d3; // expected-note {{'d3' defined here}}
static Class LocalClass(y); // expected-error {{variable with local storage in initial value of threadprivate variable}}
#pragma omp threadprivate(LocalClass)

d.a = a;
d2++;
Expand Down

0 comments on commit 9e6a299

Please sign in to comment.