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 | 3df61308ddfbdba0897b762a129b5a38750c87d0 (patch) | |
tree | 304aecb1ddc8469b0d97ff6bc45e2cad070635ab /lib/AST/ExprConstant.cpp | |
parent | d29975fd08713eb9d1777e60536addaa62df8995 (diff) |
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.
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@149448 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/AST/ExprConstant.cpp')
-rw-r--r-- | lib/AST/ExprConstant.cpp | 10 |
1 files changed, 4 insertions, 6 deletions
diff --git a/lib/AST/ExprConstant.cpp b/lib/AST/ExprConstant.cpp index 5a385e6eb4..15ab15ce3d 100644 --- a/lib/AST/ExprConstant.cpp +++ b/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. |