diff options
Diffstat (limited to 'clang/lib/CodeGen/CGExprScalar.cpp')
-rw-r--r-- | clang/lib/CodeGen/CGExprScalar.cpp | 48 |
1 files changed, 23 insertions, 25 deletions
diff --git a/clang/lib/CodeGen/CGExprScalar.cpp b/clang/lib/CodeGen/CGExprScalar.cpp index c46215067a6..668c572942f 100644 --- a/clang/lib/CodeGen/CGExprScalar.cpp +++ b/clang/lib/CodeGen/CGExprScalar.cpp @@ -162,13 +162,13 @@ static bool CanElideOverflowCheck(const ASTContext &Ctx, const BinOpInfo &Op) { // we can elide the overflow check. if (!Op.mayHaveIntegerOverflow()) return true; - - // If a unary op has a widened operand, the op cannot overflow. - if (const auto *UO = dyn_cast<UnaryOperator>(Op.E)) - return IsWidenedIntegerOp(Ctx, UO->getSubExpr()); - - // We usually don't need overflow checks for binops with widened operands. - // Multiplication with promoted unsigned operands is a special case. +
+ // If a unary op has a widened operand, the op cannot overflow.
+ if (const auto *UO = dyn_cast<UnaryOperator>(Op.E))
+ return !UO->canOverflow();
+
+ // We usually don't need overflow checks for binops with widened operands.
+ // Multiplication with promoted unsigned operands is a special case.
const auto *BO = cast<BinaryOperator>(Op.E); auto OptionalLHSTy = getUnwidenedIntegerType(Ctx, BO->getLHS()); if (!OptionalLHSTy) @@ -1870,13 +1870,13 @@ llvm::Value *ScalarExprEmitter::EmitIncDecConsiderOverflowBehavior( return Builder.CreateAdd(InVal, Amount, Name); case LangOptions::SOB_Undefined: if (!CGF.SanOpts.has(SanitizerKind::SignedIntegerOverflow)) - return Builder.CreateNSWAdd(InVal, Amount, Name); - // Fall through. - case LangOptions::SOB_Trapping: - if (IsWidenedIntegerOp(CGF.getContext(), E->getSubExpr())) - return Builder.CreateNSWAdd(InVal, Amount, Name); - return EmitOverflowCheckedBinOp(createBinOpInfoFromIncDec(E, InVal, IsInc)); - } + return Builder.CreateNSWAdd(InVal, Amount, Name);
+ // Fall through.
+ case LangOptions::SOB_Trapping:
+ if (!E->canOverflow())
+ return Builder.CreateNSWAdd(InVal, Amount, Name);
+ return EmitOverflowCheckedBinOp(createBinOpInfoFromIncDec(E, InVal, IsInc));
+ }
llvm_unreachable("Unknown SignedOverflowBehaviorTy"); } @@ -1952,17 +1952,15 @@ ScalarExprEmitter::EmitScalarPrePostIncDec(const UnaryOperator *E, LValue LV, value = Builder.getTrue(); // Most common case by far: integer increment. - } else if (type->isIntegerType()) { - // Note that signed integer inc/dec with width less than int can't - // overflow because of promotion rules; we're just eliding a few steps here. - bool CanOverflow = value->getType()->getIntegerBitWidth() >= - CGF.IntTy->getIntegerBitWidth(); - if (CanOverflow && type->isSignedIntegerOrEnumerationType()) { - value = EmitIncDecConsiderOverflowBehavior(E, value, isInc); - } else if (CanOverflow && type->isUnsignedIntegerType() && - CGF.SanOpts.has(SanitizerKind::UnsignedIntegerOverflow)) { - value = - EmitOverflowCheckedBinOp(createBinOpInfoFromIncDec(E, value, isInc)); + } else if (type->isIntegerType()) {
+ // Note that signed integer inc/dec with width less than int can't
+ // overflow because of promotion rules; we're just eliding a few steps here.
+ if (E->canOverflow() && type->isSignedIntegerOrEnumerationType()) {
+ value = EmitIncDecConsiderOverflowBehavior(E, value, isInc);
+ } else if (E->canOverflow() && type->isUnsignedIntegerType() &&
+ CGF.SanOpts.has(SanitizerKind::UnsignedIntegerOverflow)) {
+ value =
+ EmitOverflowCheckedBinOp(createBinOpInfoFromIncDec(E, value, isInc));
} else { llvm::Value *amt = llvm::ConstantInt::get(value->getType(), amount, true); value = Builder.CreateAdd(value, amt, isInc ? "inc" : "dec"); |