[Diagnostics] Do not diagnose unsigned shifts in boolean context (-Wint-in-bool-context)
I was looking at old GCC's patch. Current "trunk" version avoids warning for unsigned case, GCC warns only for signed shifts. llvm-svn: 372708
This commit is contained in:
parent
52c55d7fb5
commit
849fd28cf0
|
@ -5722,10 +5722,10 @@ def note_precedence_conditional_first : Note<
|
|||
|
||||
def warn_enum_constant_in_bool_context : Warning<
|
||||
"converting the enum constant to a boolean">,
|
||||
InGroup<IntInBoolContext>;
|
||||
InGroup<IntInBoolContext>, DefaultIgnore;
|
||||
def warn_left_shift_in_bool_context : Warning<
|
||||
"converting the result of '<<' to a boolean; did you mean '(%0) != 0'?">,
|
||||
InGroup<IntInBoolContext>;
|
||||
InGroup<IntInBoolContext>, DefaultIgnore;
|
||||
def warn_logical_instead_of_bitwise : Warning<
|
||||
"use of logical '%0' with constant operand">,
|
||||
InGroup<DiagGroup<"constant-logical-operand">>;
|
||||
|
|
|
@ -11296,44 +11296,39 @@ static bool isSameWidthConstantConversion(Sema &S, Expr *E, QualType T,
|
|||
return true;
|
||||
}
|
||||
|
||||
static const IntegerLiteral *getIntegerLiteral(Expr *E) {
|
||||
const auto *IL = dyn_cast<IntegerLiteral>(E);
|
||||
if (!IL) {
|
||||
if (auto *UO = dyn_cast<UnaryOperator>(E)) {
|
||||
if (UO->getOpcode() == UO_Minus)
|
||||
return dyn_cast<IntegerLiteral>(UO->getSubExpr());
|
||||
}
|
||||
}
|
||||
|
||||
return IL;
|
||||
}
|
||||
|
||||
static void DiagnoseIntInBoolContext(Sema &S, Expr *E) {
|
||||
E = E->IgnoreParenImpCasts();
|
||||
SourceLocation ExprLoc = E->getExprLoc();
|
||||
|
||||
if (const auto *BO = dyn_cast<BinaryOperator>(E)) {
|
||||
BinaryOperator::Opcode Opc = BO->getOpcode();
|
||||
if (Opc == BO_Shl)
|
||||
// Do not diagnose unsigned shifts.
|
||||
if (Opc == BO_Shl && 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 = dyn_cast<IntegerLiteral>(CO->getTrueExpr());
|
||||
if (!LHS) {
|
||||
if (auto *UO = dyn_cast<UnaryOperator>(CO->getTrueExpr())) {
|
||||
if (UO->getOpcode() == UO_Minus)
|
||||
LHS = dyn_cast<IntegerLiteral>(UO->getSubExpr());
|
||||
if (!LHS)
|
||||
return;
|
||||
} else {
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
const auto *RHS = dyn_cast<IntegerLiteral>(CO->getFalseExpr());
|
||||
if (!RHS) {
|
||||
if (auto *UO = dyn_cast<UnaryOperator>(CO->getFalseExpr())) {
|
||||
if (UO->getOpcode() == UO_Minus)
|
||||
RHS = dyn_cast<IntegerLiteral>(UO->getSubExpr());
|
||||
if (!RHS)
|
||||
return;
|
||||
} else {
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
const auto *LHS = getIntegerLiteral(CO->getTrueExpr());
|
||||
if (!LHS)
|
||||
return;
|
||||
const auto *RHS = getIntegerLiteral(CO->getFalseExpr());
|
||||
if (!RHS)
|
||||
return;
|
||||
if ((LHS->getValue() == 0 || LHS->getValue() == 1) &&
|
||||
(RHS->getValue() == 0 || RHS->getValue() == 1))
|
||||
// Do not diagnose common idioms
|
||||
// Do not diagnose common idioms.
|
||||
return;
|
||||
if (LHS->getValue() != 0 && LHS->getValue() != 0)
|
||||
S.Diag(ExprLoc, diag::warn_integer_constants_in_conditional_always_true);
|
||||
|
|
|
@ -7,6 +7,8 @@
|
|||
#define TWO 2
|
||||
|
||||
#define SHIFT(l, r) l << r
|
||||
#define MM a << a
|
||||
#define AF 1 << 7
|
||||
|
||||
#ifdef __cplusplus
|
||||
typedef bool boolean;
|
||||
|
@ -20,15 +22,25 @@ enum num {
|
|||
two,
|
||||
};
|
||||
|
||||
int test(int a, enum num n) {
|
||||
int test(int a, unsigned b, enum num n) {
|
||||
boolean r;
|
||||
r = (1 << 3); // expected-warning {{converting the result of '<<' to a boolean; did you mean '(1 << 3) != 0'?}}
|
||||
r = TWO << 7; // expected-warning {{converting the result of '<<' to a boolean; did you mean '(2 << 7) != 0'?}}
|
||||
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 = 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'?}}
|
||||
r = a << 7; // expected-warning {{converting the result of '<<' to a boolean; did you mean '(a << 7) != 0'?}}
|
||||
r = ONE << a; // expected-warning {{converting the result of '<<' to a boolean; did you mean '(1 << a) != 0'?}}
|
||||
if (TWO << 4) // expected-warning {{converting the result of '<<' to a boolean; did you mean '(2 << 4) != 0'?}}
|
||||
if (TWO << a) // expected-warning {{converting the result of '<<' to a boolean; did you mean '(2 << a) != 0'?}}
|
||||
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