[OPENMP] Fix PR38398: compiler crash on standalone pragma ordered with depend sink|source clause.

Patch fixes compiler crash on standalone #pragmas ordered with
depend(sink|source) clauses.

llvm-svn: 325302
This commit is contained in:
Alexey Bataev 2018-02-15 22:42:57 +00:00
parent 1df820ecd7
commit 17daedfd04
2 changed files with 121 additions and 122 deletions

View File

@ -11367,138 +11367,135 @@ Sema::ActOnOpenMPDependClause(OpenMPDependClauseKind DepKind,
TotalDepCount.setIsUnsigned(/*Val=*/true);
}
}
if ((DepKind != OMPC_DEPEND_sink && DepKind != OMPC_DEPEND_source) ||
DSAStack->getParentOrderedRegionParam()) {
for (auto &RefExpr : VarList) {
assert(RefExpr && "NULL expr in OpenMP shared clause.");
if (isa<DependentScopeDeclRefExpr>(RefExpr)) {
for (auto &RefExpr : VarList) {
assert(RefExpr && "NULL expr in OpenMP shared clause.");
if (isa<DependentScopeDeclRefExpr>(RefExpr)) {
// It will be analyzed later.
Vars.push_back(RefExpr);
continue;
}
SourceLocation ELoc = RefExpr->getExprLoc();
auto *SimpleExpr = RefExpr->IgnoreParenCasts();
if (DepKind == OMPC_DEPEND_sink) {
if (DSAStack->getParentOrderedRegionParam() &&
DepCounter >= TotalDepCount) {
Diag(ELoc, diag::err_omp_depend_sink_unexpected_expr);
continue;
}
++DepCounter;
// OpenMP [2.13.9, Summary]
// depend(dependence-type : vec), where dependence-type is:
// 'sink' and where vec is the iteration vector, which has the form:
// x1 [+- d1], x2 [+- d2 ], . . . , xn [+- dn]
// where n is the value specified by the ordered clause in the loop
// directive, xi denotes the loop iteration variable of the i-th nested
// loop associated with the loop directive, and di is a constant
// non-negative integer.
if (CurContext->isDependentContext()) {
// It will be analyzed later.
Vars.push_back(RefExpr);
continue;
}
SourceLocation ELoc = RefExpr->getExprLoc();
auto *SimpleExpr = RefExpr->IgnoreParenCasts();
if (DepKind == OMPC_DEPEND_sink) {
if (DepCounter >= TotalDepCount) {
Diag(ELoc, diag::err_omp_depend_sink_unexpected_expr);
continue;
}
++DepCounter;
// OpenMP [2.13.9, Summary]
// depend(dependence-type : vec), where dependence-type is:
// 'sink' and where vec is the iteration vector, which has the form:
// x1 [+- d1], x2 [+- d2 ], . . . , xn [+- dn]
// where n is the value specified by the ordered clause in the loop
// directive, xi denotes the loop iteration variable of the i-th nested
// loop associated with the loop directive, and di is a constant
// non-negative integer.
if (CurContext->isDependentContext()) {
// It will be analyzed later.
Vars.push_back(RefExpr);
continue;
}
SimpleExpr = SimpleExpr->IgnoreImplicit();
OverloadedOperatorKind OOK = OO_None;
SourceLocation OOLoc;
Expr *LHS = SimpleExpr;
Expr *RHS = nullptr;
if (auto *BO = dyn_cast<BinaryOperator>(SimpleExpr)) {
OOK = BinaryOperator::getOverloadedOperator(BO->getOpcode());
OOLoc = BO->getOperatorLoc();
LHS = BO->getLHS()->IgnoreParenImpCasts();
RHS = BO->getRHS()->IgnoreParenImpCasts();
} else if (auto *OCE = dyn_cast<CXXOperatorCallExpr>(SimpleExpr)) {
OOK = OCE->getOperator();
OOLoc = OCE->getOperatorLoc();
LHS = OCE->getArg(/*Arg=*/0)->IgnoreParenImpCasts();
RHS = OCE->getArg(/*Arg=*/1)->IgnoreParenImpCasts();
} else if (auto *MCE = dyn_cast<CXXMemberCallExpr>(SimpleExpr)) {
OOK = MCE->getMethodDecl()
->getNameInfo()
.getName()
.getCXXOverloadedOperator();
OOLoc = MCE->getCallee()->getExprLoc();
LHS = MCE->getImplicitObjectArgument()->IgnoreParenImpCasts();
RHS = MCE->getArg(/*Arg=*/0)->IgnoreParenImpCasts();
}
SourceLocation ELoc;
SourceRange ERange;
auto Res = getPrivateItem(*this, LHS, ELoc, ERange,
/*AllowArraySection=*/false);
if (Res.second) {
// It will be analyzed later.
Vars.push_back(RefExpr);
}
ValueDecl *D = Res.first;
if (!D)
continue;
if (OOK != OO_Plus && OOK != OO_Minus && (RHS || OOK != OO_None)) {
Diag(OOLoc, diag::err_omp_depend_sink_expected_plus_minus);
continue;
}
if (RHS) {
ExprResult RHSRes = VerifyPositiveIntegerConstantInClause(
RHS, OMPC_depend, /*StrictlyPositive=*/false);
if (RHSRes.isInvalid())
continue;
}
if (!CurContext->isDependentContext() &&
DSAStack->getParentOrderedRegionParam() &&
DepCounter != DSAStack->isParentLoopControlVariable(D).first) {
ValueDecl* VD = DSAStack->getParentLoopControlVariable(
DepCounter.getZExtValue());
if (VD) {
Diag(ELoc, diag::err_omp_depend_sink_expected_loop_iteration)
<< 1 << VD;
} else {
Diag(ELoc, diag::err_omp_depend_sink_expected_loop_iteration) << 0;
}
continue;
}
OpsOffs.push_back({RHS, OOK});
} else {
auto *ASE = dyn_cast<ArraySubscriptExpr>(SimpleExpr);
if (!RefExpr->IgnoreParenImpCasts()->isLValue() ||
(ASE &&
!ASE->getBase()
->getType()
.getNonReferenceType()
->isPointerType() &&
!ASE->getBase()->getType().getNonReferenceType()->isArrayType())) {
Diag(ELoc, diag::err_omp_expected_addressable_lvalue_or_array_item)
<< RefExpr->getSourceRange();
continue;
}
bool Suppress = getDiagnostics().getSuppressAllDiagnostics();
getDiagnostics().setSuppressAllDiagnostics(/*Val=*/true);
ExprResult Res = CreateBuiltinUnaryOp(ELoc, UO_AddrOf,
RefExpr->IgnoreParenImpCasts());
getDiagnostics().setSuppressAllDiagnostics(Suppress);
if (!Res.isUsable() && !isa<OMPArraySectionExpr>(SimpleExpr)) {
Diag(ELoc, diag::err_omp_expected_addressable_lvalue_or_array_item)
<< RefExpr->getSourceRange();
continue;
}
SimpleExpr = SimpleExpr->IgnoreImplicit();
OverloadedOperatorKind OOK = OO_None;
SourceLocation OOLoc;
Expr *LHS = SimpleExpr;
Expr *RHS = nullptr;
if (auto *BO = dyn_cast<BinaryOperator>(SimpleExpr)) {
OOK = BinaryOperator::getOverloadedOperator(BO->getOpcode());
OOLoc = BO->getOperatorLoc();
LHS = BO->getLHS()->IgnoreParenImpCasts();
RHS = BO->getRHS()->IgnoreParenImpCasts();
} else if (auto *OCE = dyn_cast<CXXOperatorCallExpr>(SimpleExpr)) {
OOK = OCE->getOperator();
OOLoc = OCE->getOperatorLoc();
LHS = OCE->getArg(/*Arg=*/0)->IgnoreParenImpCasts();
RHS = OCE->getArg(/*Arg=*/1)->IgnoreParenImpCasts();
} else if (auto *MCE = dyn_cast<CXXMemberCallExpr>(SimpleExpr)) {
OOK = MCE->getMethodDecl()
->getNameInfo()
.getName()
.getCXXOverloadedOperator();
OOLoc = MCE->getCallee()->getExprLoc();
LHS = MCE->getImplicitObjectArgument()->IgnoreParenImpCasts();
RHS = MCE->getArg(/*Arg=*/0)->IgnoreParenImpCasts();
}
Vars.push_back(RefExpr->IgnoreParenImpCasts());
}
SourceLocation ELoc;
SourceRange ERange;
auto Res = getPrivateItem(*this, LHS, ELoc, ERange,
/*AllowArraySection=*/false);
if (Res.second) {
// It will be analyzed later.
Vars.push_back(RefExpr);
}
ValueDecl *D = Res.first;
if (!D)
continue;
if (!CurContext->isDependentContext() && DepKind == OMPC_DEPEND_sink &&
TotalDepCount > VarList.size() &&
DSAStack->getParentOrderedRegionParam() &&
DSAStack->getParentLoopControlVariable(VarList.size() + 1)) {
Diag(EndLoc, diag::err_omp_depend_sink_expected_loop_iteration) << 1
<< DSAStack->getParentLoopControlVariable(VarList.size() + 1);
if (OOK != OO_Plus && OOK != OO_Minus && (RHS || OOK != OO_None)) {
Diag(OOLoc, diag::err_omp_depend_sink_expected_plus_minus);
continue;
}
if (RHS) {
ExprResult RHSRes = VerifyPositiveIntegerConstantInClause(
RHS, OMPC_depend, /*StrictlyPositive=*/false);
if (RHSRes.isInvalid())
continue;
}
if (!CurContext->isDependentContext() &&
DSAStack->getParentOrderedRegionParam() &&
DepCounter != DSAStack->isParentLoopControlVariable(D).first) {
ValueDecl *VD =
DSAStack->getParentLoopControlVariable(DepCounter.getZExtValue());
if (VD) {
Diag(ELoc, diag::err_omp_depend_sink_expected_loop_iteration)
<< 1 << VD;
} else {
Diag(ELoc, diag::err_omp_depend_sink_expected_loop_iteration) << 0;
}
continue;
}
OpsOffs.push_back({RHS, OOK});
} else {
auto *ASE = dyn_cast<ArraySubscriptExpr>(SimpleExpr);
if (!RefExpr->IgnoreParenImpCasts()->isLValue() ||
(ASE &&
!ASE->getBase()->getType().getNonReferenceType()->isPointerType() &&
!ASE->getBase()->getType().getNonReferenceType()->isArrayType())) {
Diag(ELoc, diag::err_omp_expected_addressable_lvalue_or_array_item)
<< RefExpr->getSourceRange();
continue;
}
bool Suppress = getDiagnostics().getSuppressAllDiagnostics();
getDiagnostics().setSuppressAllDiagnostics(/*Val=*/true);
ExprResult Res =
CreateBuiltinUnaryOp(ELoc, UO_AddrOf, RefExpr->IgnoreParenImpCasts());
getDiagnostics().setSuppressAllDiagnostics(Suppress);
if (!Res.isUsable() && !isa<OMPArraySectionExpr>(SimpleExpr)) {
Diag(ELoc, diag::err_omp_expected_addressable_lvalue_or_array_item)
<< RefExpr->getSourceRange();
continue;
}
}
if (DepKind != OMPC_DEPEND_source && DepKind != OMPC_DEPEND_sink &&
Vars.empty())
return nullptr;
Vars.push_back(RefExpr->IgnoreParenImpCasts());
}
if (!CurContext->isDependentContext() && DepKind == OMPC_DEPEND_sink &&
TotalDepCount > VarList.size() &&
DSAStack->getParentOrderedRegionParam() &&
DSAStack->getParentLoopControlVariable(VarList.size() + 1)) {
Diag(EndLoc, diag::err_omp_depend_sink_expected_loop_iteration)
<< 1 << DSAStack->getParentLoopControlVariable(VarList.size() + 1);
}
if (DepKind != OMPC_DEPEND_source && DepKind != OMPC_DEPEND_sink &&
Vars.empty())
return nullptr;
auto *C = OMPDependClause::Create(Context, StartLoc, LParenLoc, EndLoc,
DepKind, DepLoc, ColonLoc, Vars);
if (DepKind == OMPC_DEPEND_sink || DepKind == OMPC_DEPEND_source)
if ((DepKind == OMPC_DEPEND_sink || DepKind == OMPC_DEPEND_source) &&
DSAStack->isParentOrderedRegion())
DSAStack->addDoacrossDependClause(C, OpsOffs);
return C;
}

View File

@ -138,6 +138,8 @@ T foo() {
#pragma omp ordered depend(source) depend(sink : i-0, j+sizeof(T)) // expected-error {{'depend(sink:vec)' clauses cannot be mixed with 'depend(source)' clause}}
}
}
#pragma omp ordered depend(source) // expected-error {{'ordered' directive with 'depend' clause cannot be closely nested inside ordered region without specified parameter}}
#pragma omp ordered depend(sink:k) // expected-error {{'ordered' directive with 'depend' clause cannot be closely nested inside ordered region without specified parameter}}
return T();
}