summaryrefslogtreecommitdiff
path: root/clang/lib/Sema/SemaOpenMP.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'clang/lib/Sema/SemaOpenMP.cpp')
-rw-r--r--clang/lib/Sema/SemaOpenMP.cpp19
1 files changed, 14 insertions, 5 deletions
diff --git a/clang/lib/Sema/SemaOpenMP.cpp b/clang/lib/Sema/SemaOpenMP.cpp
index ae91a6470471..a500ad4f0220 100644
--- a/clang/lib/Sema/SemaOpenMP.cpp
+++ b/clang/lib/Sema/SemaOpenMP.cpp
@@ -5327,6 +5327,8 @@ static CapturedStmt *buildDistanceFunc(Sema &Actions, QualType LogicalTy,
IntegerLiteral *Zero = IntegerLiteral::Create(
Ctx, llvm::APInt(Ctx.getIntWidth(LogicalTy), 0), LogicalTy, {});
+ IntegerLiteral *One = IntegerLiteral::Create(
+ Ctx, llvm::APInt(Ctx.getIntWidth(LogicalTy), 1), LogicalTy, {});
Expr *Dist;
if (Rel == BO_NE) {
// When using a != comparison, the increment can be +1 or -1. This can be
@@ -5381,18 +5383,25 @@ static CapturedStmt *buildDistanceFunc(Sema &Actions, QualType LogicalTy,
if (Rel == BO_LE || Rel == BO_GE) {
// Add one to the range if the relational operator is inclusive.
- Range = AssertSuccess(Actions.BuildBinOp(
- nullptr, {}, BO_Add, Range,
- Actions.ActOnIntegerConstant(SourceLocation(), 1).get()));
+ Range =
+ AssertSuccess(Actions.BuildBinOp(nullptr, {}, BO_Add, Range, One));
}
- // Divide by the absolute step amount.
+ // Divide by the absolute step amount. If the range is not a multiple of
+ // the step size, rounding-up the effective upper bound ensures that the
+ // last iteration is included.
+ // Note that the rounding-up may cause an overflow in a temporry that
+ // could be avoided, but would have occured in a C-style for-loop as well.
Expr *Divisor = BuildVarRef(NewStep);
if (Rel == BO_GE || Rel == BO_GT)
Divisor =
AssertSuccess(Actions.BuildUnaryOp(nullptr, {}, UO_Minus, Divisor));
+ Expr *DivisorMinusOne =
+ AssertSuccess(Actions.BuildBinOp(nullptr, {}, BO_Sub, Divisor, One));
+ Expr *RangeRoundUp = AssertSuccess(
+ Actions.BuildBinOp(nullptr, {}, BO_Add, Range, DivisorMinusOne));
Dist = AssertSuccess(
- Actions.BuildBinOp(nullptr, {}, BO_Div, Range, Divisor));
+ Actions.BuildBinOp(nullptr, {}, BO_Div, RangeRoundUp, Divisor));
// If there is not at least one iteration, the range contains garbage. Fix
// to zero in this case.