diff options
author | Richard Smith <richard-llvm@metafoo.co.uk> | 2012-01-31 23:24:19 +0000 |
---|---|---|
committer | Richard Smith <richard-llvm@metafoo.co.uk> | 2012-01-31 23:24:19 +0000 |
commit | 000e9aa7ed9c5b1c59f78711235418a5a8a91750 (patch) | |
tree | e9670602abeee1f1ff415afff48d087e71856587 /clang/lib | |
parent | fbf1b6417314553d44ae16ab2d9eb1200d17316d (diff) | |
download | bcm5719-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.cpp | 10 |
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. |