From 1ed95d8460beb3c74b5c1d0ae1ee4da47ee00164 Mon Sep 17 00:00:00 2001 From: Alexey Bataev Date: Thu, 15 Feb 2018 22:42:57 +0000 Subject: [PATCH] [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. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@325302 91177308-0d34-0410-b5e6-96231b3b80d8 --- lib/Sema/SemaOpenMP.cpp | 235 +++++++++++++++---------------- test/OpenMP/ordered_messages.cpp | 2 + 2 files changed, 118 insertions(+), 119 deletions(-) diff --git a/lib/Sema/SemaOpenMP.cpp b/lib/Sema/SemaOpenMP.cpp index 14bf828c9c..7015b0119e 100644 --- a/lib/Sema/SemaOpenMP.cpp +++ b/lib/Sema/SemaOpenMP.cpp @@ -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(RefExpr)) { + for (auto &RefExpr : VarList) { + assert(RefExpr && "NULL expr in OpenMP shared clause."); + if (isa(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; } + SimpleExpr = SimpleExpr->IgnoreImplicit(); + OverloadedOperatorKind OOK = OO_None; + SourceLocation OOLoc; + Expr *LHS = SimpleExpr; + Expr *RHS = nullptr; + if (auto *BO = dyn_cast(SimpleExpr)) { + OOK = BinaryOperator::getOverloadedOperator(BO->getOpcode()); + OOLoc = BO->getOperatorLoc(); + LHS = BO->getLHS()->IgnoreParenImpCasts(); + RHS = BO->getRHS()->IgnoreParenImpCasts(); + } else if (auto *OCE = dyn_cast(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(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; - 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(SimpleExpr)) { - OOK = BinaryOperator::getOverloadedOperator(BO->getOpcode()); - OOLoc = BO->getOperatorLoc(); - LHS = BO->getLHS()->IgnoreParenImpCasts(); - RHS = BO->getRHS()->IgnoreParenImpCasts(); - } else if (auto *OCE = dyn_cast(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(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(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(SimpleExpr)) { - Diag(ELoc, diag::err_omp_expected_addressable_lvalue_or_array_item) - << RefExpr->getSourceRange(); + 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(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(SimpleExpr)) { + Diag(ELoc, diag::err_omp_expected_addressable_lvalue_or_array_item) + << RefExpr->getSourceRange(); + continue; } - Vars.push_back(RefExpr->IgnoreParenImpCasts()); } + 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; + 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; } diff --git a/test/OpenMP/ordered_messages.cpp b/test/OpenMP/ordered_messages.cpp index d2945dd123..43ac40efe6 100644 --- a/test/OpenMP/ordered_messages.cpp +++ b/test/OpenMP/ordered_messages.cpp @@ -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(); } -- 2.40.0