Skip to content
Snippets Groups Projects
Commit 9e6a2994 authored by Alexey Bataev's avatar Alexey Bataev
Browse files

[OPENMP] Additional checking for local vars in initial values for threadprivate vars

git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@209716 91177308-0d34-0410-b5e6-96231b3b80d8
parent bf9865fc
No related branches found
No related tags found
No related merge requests found
......@@ -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 {
......
......@@ -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);
}
......
......@@ -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++;
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment