forked from OSchip/llvm-project
[Diagnostics] Handle tautological left shifts in boolean context
llvm-svn: 372749
This commit is contained in:
parent
355764e388
commit
275e4df115
|
@ -6155,6 +6155,10 @@ def warn_integer_constants_in_conditional_always_true : Warning<
|
|||
"converting the result of '?:' with integer constants to a boolean always "
|
||||
"evaluates to 'true'">,
|
||||
InGroup<TautologicalConstantCompare>;
|
||||
def warn_left_shift_always : Warning<
|
||||
"converting the result of '<<' to a boolean always evaluates "
|
||||
"to %select{false|true}0">,
|
||||
InGroup<TautologicalConstantCompare>;
|
||||
def warn_comparison_of_mixed_enum_types : Warning<
|
||||
"comparison of two values with different enumeration types"
|
||||
"%diff{ ($ and $)|}0,1">,
|
||||
|
|
|
@ -11314,17 +11314,26 @@ static void DiagnoseIntInBoolContext(Sema &S, Expr *E) {
|
|||
|
||||
if (const auto *BO = dyn_cast<BinaryOperator>(E)) {
|
||||
BinaryOperator::Opcode Opc = BO->getOpcode();
|
||||
Expr::EvalResult Result;
|
||||
// Do not diagnose unsigned shifts.
|
||||
if (Opc == BO_Shl && E->getType()->isSignedIntegerType())
|
||||
S.Diag(ExprLoc, diag::warn_left_shift_in_bool_context) << E;
|
||||
if (Opc == BO_Shl) {
|
||||
const auto *LHS = getIntegerLiteral(BO->getLHS());
|
||||
const auto *RHS = getIntegerLiteral(BO->getRHS());
|
||||
if (LHS && LHS->getValue() == 0)
|
||||
S.Diag(ExprLoc, diag::warn_left_shift_always) << 0;
|
||||
else if (RHS && RHS->getValue().isNonNegative() &&
|
||||
E->EvaluateAsInt(Result, S.Context, Expr::SE_AllowSideEffects))
|
||||
S.Diag(ExprLoc, diag::warn_left_shift_always)
|
||||
<< (Result.Val.getInt() != 0);
|
||||
else if (E->getType()->isSignedIntegerType())
|
||||
S.Diag(ExprLoc, diag::warn_left_shift_in_bool_context) << E;
|
||||
}
|
||||
}
|
||||
|
||||
if (const auto *CO = dyn_cast<ConditionalOperator>(E)) {
|
||||
const auto *LHS = getIntegerLiteral(CO->getTrueExpr());
|
||||
if (!LHS)
|
||||
return;
|
||||
const auto *RHS = getIntegerLiteral(CO->getFalseExpr());
|
||||
if (!RHS)
|
||||
if (!LHS || !RHS)
|
||||
return;
|
||||
if ((LHS->getValue() == 0 || LHS->getValue() == 1) &&
|
||||
(RHS->getValue() == 0 || RHS->getValue() == 1))
|
||||
|
|
|
@ -24,12 +24,17 @@ enum num {
|
|||
|
||||
int test(int a, unsigned b, enum num n) {
|
||||
boolean r;
|
||||
r = a << a; // expected-warning {{converting the result of '<<' to a boolean; did you mean '(a << a) != 0'?}}
|
||||
r = MM; // expected-warning {{converting the result of '<<' to a boolean; did you mean '(a << a) != 0'?}}
|
||||
r = (1 << 7); // expected-warning {{converting the result of '<<' to a boolean; did you mean '(1 << 7) != 0'?}}
|
||||
r = 2UL << 2;
|
||||
r = 2 << b; // expected-warning {{converting the result of '<<' to a boolean; did you mean '(2 << b) != 0'?}}
|
||||
r = (unsigned)(2 << b);
|
||||
r = a << a; // expected-warning {{converting the result of '<<' to a boolean; did you mean '(a << a) != 0'?}}
|
||||
r = MM; // expected-warning {{converting the result of '<<' to a boolean; did you mean '(a << a) != 0'?}}
|
||||
r = (1 << 7); // expected-warning {{converting the result of '<<' to a boolean always evaluates to true}}
|
||||
r = 2UL << 2; // expected-warning {{converting the result of '<<' to a boolean always evaluates to true}}
|
||||
r = 0 << a; // expected-warning {{converting the result of '<<' to a boolean always evaluates to false}}
|
||||
r = 0 << 2; // expected-warning {{converting the result of '<<' to a boolean always evaluates to false}}
|
||||
r = 1 << 0; // expected-warning {{converting the result of '<<' to a boolean always evaluates to true}}
|
||||
r = 1 << 2; // expected-warning {{converting the result of '<<' to a boolean always evaluates to true}}
|
||||
r = 1ULL << 2; // expected-warning {{converting the result of '<<' to a boolean always evaluates to true}}
|
||||
r = 2 << b; // expected-warning {{converting the result of '<<' to a boolean; did you mean '(2 << b) != 0'?}}
|
||||
r = (unsigned)(2 << b);
|
||||
r = b << 7;
|
||||
r = (1 << a); // expected-warning {{converting the result of '<<' to a boolean; did you mean '(1 << a) != 0'?}}
|
||||
r = TWO << a; // expected-warning {{converting the result of '<<' to a boolean; did you mean '(2 << a) != 0'?}}
|
||||
|
@ -39,7 +44,7 @@ int test(int a, unsigned b, enum num n) {
|
|||
return a;
|
||||
|
||||
for (a = 0; 1 << a; a++) // expected-warning {{converting the result of '<<' to a boolean; did you mean '(1 << a) != 0'?}}
|
||||
;
|
||||
;
|
||||
|
||||
if (a << TWO) // expected-warning {{converting the result of '<<' to a boolean; did you mean '(a << 2) != 0'?}}
|
||||
return a;
|
||||
|
|
Loading…
Reference in New Issue