forked from OSchip/llvm-project
[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:
parent
1df820ecd7
commit
17daedfd04
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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();
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue