summaryrefslogtreecommitdiffstats
path: root/clang/lib
diff options
context:
space:
mode:
authorRichard Smith <richard-llvm@metafoo.co.uk>2012-01-31 23:24:19 +0000
committerRichard Smith <richard-llvm@metafoo.co.uk>2012-01-31 23:24:19 +0000
commit000e9aa7ed9c5b1c59f78711235418a5a8a91750 (patch)
treee9670602abeee1f1ff415afff48d087e71856587 /clang/lib
parentfbf1b6417314553d44ae16ab2d9eb1200d17316d (diff)
downloadbcm5719-llvm-000e9aa7ed9c5b1c59f78711235418a5a8a91750.tar.gz
bcm5719-llvm-000e9aa7ed9c5b1c59f78711235418a5a8a91750.zip
constexpr: Treat INT_MIN % -1 as undefined behavior in C++11. Technically, it
isn't, but this is just a (reported) defect in the wording. llvm-svn: 149448
Diffstat (limited to 'clang/lib')
-rw-r--r--clang/lib/AST/ExprConstant.cpp10
1 files changed, 4 insertions, 6 deletions
diff --git a/clang/lib/AST/ExprConstant.cpp b/clang/lib/AST/ExprConstant.cpp
index 5a385e6eb47..15ab15ce3d6 100644
--- a/clang/lib/AST/ExprConstant.cpp
+++ b/clang/lib/AST/ExprConstant.cpp
@@ -4431,17 +4431,15 @@ bool IntExprEvaluator::VisitBinaryOperator(const BinaryOperator *E) {
case BO_Xor: return Success(LHS ^ RHS, E);
case BO_Or: return Success(LHS | RHS, E);
case BO_Div:
+ case BO_Rem:
if (RHS == 0)
return Error(E, diag::note_expr_divide_by_zero);
- // Check for overflow case: INT_MIN / -1.
+ // Check for overflow case: INT_MIN / -1 or INT_MIN % -1. The latter is not
+ // actually undefined behavior in C++11 due to a language defect.
if (RHS.isNegative() && RHS.isAllOnesValue() &&
LHS.isSigned() && LHS.isMinSignedValue())
HandleOverflow(Info, E, -LHS.extend(LHS.getBitWidth() + 1), E->getType());
- return Success(LHS / RHS, E);
- case BO_Rem:
- if (RHS == 0)
- return Error(E, diag::note_expr_divide_by_zero);
- return Success(LHS % RHS, E);
+ return Success(E->getOpcode() == BO_Rem ? LHS % RHS : LHS / RHS, E);
case BO_Shl: {
// During constant-folding, a negative shift is an opposite shift. Such a
// shift is not a constant expression.
OpenPOWER on IntegriCloud