forked from OSchip/llvm-project
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
This commit is contained in:
parent
fbf1b64173
commit
000e9aa7ed
|
@ -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:
|
||||
if (RHS == 0)
|
||||
return Error(E, diag::note_expr_divide_by_zero);
|
||||
// Check for overflow case: INT_MIN / -1.
|
||||
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);
|
||||
// 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(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.
|
||||
|
|
|
@ -134,6 +134,7 @@ namespace UndefinedBehavior {
|
|||
constexpr int div0 = 3 / 0; // expected-error {{constant expression}} expected-note {{division by zero}} expected-warning {{undefined}}
|
||||
constexpr int mod0 = 3 % 0; // expected-error {{constant expression}} expected-note {{division by zero}} expected-warning {{undefined}}
|
||||
constexpr int int_min_div_minus_1 = int_min / -1; // expected-error {{constant expression}} expected-note {{value 2147483648 is outside the range}}
|
||||
constexpr int int_min_mod_minus_1 = int_min % -1; // expected-error {{constant expression}} expected-note {{value 2147483648 is outside the range}}
|
||||
|
||||
constexpr int shl_m1 = 0 << -1; // expected-error {{constant expression}} expected-note {{negative shift count -1}} expected-warning {{negative}}
|
||||
constexpr int shl_0 = 0 << 0; // ok
|
||||
|
|
Loading…
Reference in New Issue