diff options
author | Alexey Bataev <a.bataev@hotmail.com> | 2015-07-15 12:14:07 +0000 |
---|---|---|
committer | Alexey Bataev <a.bataev@hotmail.com> | 2015-07-15 12:14:07 +0000 |
commit | 3bed68cfc7c7f336e4ae1f48798ceb3e60e6c888 (patch) | |
tree | 0d16c26ea29da9ada4a55262a9b645fc0a699498 /clang/lib/Sema | |
parent | fcd93d539e4843cb5ba168e437a58498c6977a57 (diff) | |
download | bcm5719-llvm-3bed68cfc7c7f336e4ae1f48798ceb3e60e6c888.tar.gz bcm5719-llvm-3bed68cfc7c7f336e4ae1f48798ceb3e60e6c888.zip |
[OPENMP] http://llvm.org/PR24121: canonical loop rejected when comparison has implicit conversions or destruction
Allow to use complex iterators expressions in loops for C++.
llvm-svn: 242285
Diffstat (limited to 'clang/lib/Sema')
-rw-r--r-- | clang/lib/Sema/SemaOpenMP.cpp | 33 |
1 files changed, 30 insertions, 3 deletions
diff --git a/clang/lib/Sema/SemaOpenMP.cpp b/clang/lib/Sema/SemaOpenMP.cpp index 4030d9e66e0..239ede5bb65 100644 --- a/clang/lib/Sema/SemaOpenMP.cpp +++ b/clang/lib/Sema/SemaOpenMP.cpp @@ -2262,6 +2262,22 @@ bool OpenMPIterationSpaceChecker::Dependent() const { (UB && UB->isValueDependent()) || (Step && Step->isValueDependent()); } +template <typename T> +static T *getExprAsWritten(T *E) { + if (auto *ExprTemp = dyn_cast<ExprWithCleanups>(E)) + E = ExprTemp->getSubExpr(); + + if (auto *MTE = dyn_cast<MaterializeTemporaryExpr>(E)) + E = MTE->GetTemporaryExpr(); + + while (auto *Binder = dyn_cast<CXXBindTemporaryExpr>(E)) + E = Binder->getSubExpr(); + + if (auto *ICE = dyn_cast<ImplicitCastExpr>(E)) + E = ICE->getSubExprAsWritten(); + return E->IgnoreParens(); +} + bool OpenMPIterationSpaceChecker::SetVarAndLB(VarDecl *NewVar, DeclRefExpr *NewVarRefExpr, Expr *NewLB) { @@ -2272,6 +2288,11 @@ bool OpenMPIterationSpaceChecker::SetVarAndLB(VarDecl *NewVar, return true; Var = NewVar; VarRef = NewVarRefExpr; + if (auto *CE = dyn_cast_or_null<CXXConstructExpr>(NewLB)) + if (const CXXConstructorDecl *Ctor = CE->getConstructor()) + if (Ctor->isCopyConstructor() && CE->getNumArgs() == 1 && + CE->getArg(0) != nullptr) + NewLB = CE->getArg(0)->IgnoreParenImpCasts(); LB = NewLB; return false; } @@ -2402,7 +2423,7 @@ bool OpenMPIterationSpaceChecker::CheckInit(Stmt *S, bool EmitDiags) { static const VarDecl *GetInitVarDecl(const Expr *E) { if (!E) return nullptr; - E = E->IgnoreParenImpCasts(); + E = getExprAsWritten(E); if (auto *CE = dyn_cast_or_null<CXXConstructExpr>(E)) if (const CXXConstructorDecl *Ctor = CE->getConstructor()) if (Ctor->isCopyConstructor() && CE->getNumArgs() == 1 && @@ -2425,7 +2446,7 @@ bool OpenMPIterationSpaceChecker::CheckCond(Expr *S) { SemaRef.Diag(DefaultLoc, diag::err_omp_loop_not_canonical_cond) << Var; return true; } - S = S->IgnoreParenImpCasts(); + S = getExprAsWritten(S); SourceLocation CondLoc = S->getLocStart(); if (auto BO = dyn_cast<BinaryOperator>(S)) { if (BO->isRelationalOp()) { @@ -2646,6 +2667,11 @@ Expr *OpenMPIterationSpaceChecker::BuildPreCond(Scope *S, Expr *Cond) const { S, DefaultLoc, TestIsLessOp ? (TestIsStrictOp ? BO_LT : BO_LE) : (TestIsStrictOp ? BO_GT : BO_GE), LB, UB); + if (CondExpr.isUsable()) { + CondExpr = SemaRef.PerformImplicitConversion( + CondExpr.get(), SemaRef.Context.BoolTy, /*Action=*/Sema::AA_Casting, + /*AllowExplicit=*/true); + } SemaRef.getDiagnostics().setSuppressAllDiagnostics(Suppress); // Otherwise use original loop conditon and evaluate it in runtime. return CondExpr.isUsable() ? CondExpr.get() : Cond; @@ -3231,7 +3257,8 @@ CheckOpenMPLoop(OpenMPDirectiveKind DKind, Expr *NestedLoopCountExpr, Built.IterationVarRef = IV.get(); Built.LastIteration = LastIteration.get(); Built.NumIterations = NumIterations.get(); - Built.CalcLastIteration = CalcLastIteration.get(); + Built.CalcLastIteration = + SemaRef.ActOnFinishFullExpr(CalcLastIteration.get()).get(); Built.PreCond = PreCond.get(); Built.Cond = Cond.get(); Built.Init = Init.get(); |