forked from OSchip/llvm-project
[OPENMP] Additional checking for local vars in initial values for threadprivate vars
llvm-svn: 209716
This commit is contained in:
parent
7c747fc7c6
commit
18b92eeacb
|
@ -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++;
|
||||
|
|
Loading…
Reference in New Issue