forked from OSchip/llvm-project
[Diagnostics] Warn if '<<' in bool context with -Wint-in-bool-context (GCC compatibility)
Extracted from D63082, addressed review comments related to a warning message. llvm-svn: 372612
This commit is contained in:
parent
a957eaad00
commit
84ea41fd17
|
@ -499,6 +499,7 @@ def StringCompare : DiagGroup<"string-compare">;
|
|||
def StringPlusInt : DiagGroup<"string-plus-int">;
|
||||
def StringPlusChar : DiagGroup<"string-plus-char">;
|
||||
def StrncatSize : DiagGroup<"strncat-size">;
|
||||
def IntInBoolContext : DiagGroup<"int-in-bool-context">;
|
||||
def TautologicalTypeLimitCompare : DiagGroup<"tautological-type-limit-compare">;
|
||||
def TautologicalUnsignedZeroCompare : DiagGroup<"tautological-unsigned-zero-compare">;
|
||||
def TautologicalUnsignedEnumZeroCompare : DiagGroup<"tautological-unsigned-enum-zero-compare">;
|
||||
|
@ -821,6 +822,7 @@ def Most : DiagGroup<"most", [
|
|||
Format,
|
||||
Implicit,
|
||||
InfiniteRecursion,
|
||||
IntInBoolContext,
|
||||
MismatchedTags,
|
||||
MissingBraces,
|
||||
Move,
|
||||
|
|
|
@ -5720,6 +5720,9 @@ def warn_precedence_conditional : Warning<
|
|||
def note_precedence_conditional_first : Note<
|
||||
"place parentheses around the '?:' expression to evaluate it first">;
|
||||
|
||||
def warn_left_shift_in_bool_context : Warning<
|
||||
"converting the result of '<<' to a boolean; did you mean '(%0) != 0'?">,
|
||||
InGroup<IntInBoolContext>;
|
||||
def warn_logical_instead_of_bitwise : Warning<
|
||||
"use of logical '%0' with constant operand">,
|
||||
InGroup<DiagGroup<"constant-logical-operand">>;
|
||||
|
|
|
@ -11256,10 +11256,16 @@ static bool isSameWidthConstantConversion(Sema &S, Expr *E, QualType T,
|
|||
return true;
|
||||
}
|
||||
|
||||
static void DiagnoseIntInBoolContext(Sema &S, const Expr *E) {
|
||||
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)
|
||||
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) {
|
||||
|
@ -11585,6 +11591,9 @@ static void CheckImplicitConversion(Sema &S, Expr *E, QualType T,
|
|||
|
||||
S.DiscardMisalignedMemberAddress(Target, E);
|
||||
|
||||
if (Target->isBooleanType())
|
||||
DiagnoseIntInBoolContext(S, E);
|
||||
|
||||
if (!Source->isIntegerType() || !Target->isIntegerType())
|
||||
return;
|
||||
|
||||
|
|
|
@ -0,0 +1,31 @@
|
|||
// RUN: %clang_cc1 -x c -fsyntax-only -verify -Wint-in-bool-context %s
|
||||
// RUN: %clang_cc1 -x c -fsyntax-only -verify -Wall %s
|
||||
// RUN: %clang_cc1 -x c++ -fsyntax-only -verify -Wint-in-bool-context %s
|
||||
// RUN: %clang_cc1 -x c++ -fsyntax-only -verify -Wall %s
|
||||
|
||||
#define ONE 1
|
||||
#define TWO 2
|
||||
|
||||
#define SHIFT(l, r) l << r
|
||||
|
||||
#ifdef __cplusplus
|
||||
typedef bool boolean;
|
||||
#else
|
||||
typedef _Bool boolean;
|
||||
#endif
|
||||
|
||||
int test(int a) {
|
||||
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 << 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'?}}
|
||||
return a;
|
||||
|
||||
if (a << TWO) // expected-warning {{converting the result of '<<' to a boolean; did you mean '(a << 2) != 0'?}}
|
||||
return a;
|
||||
|
||||
// Don't warn in macros.
|
||||
return SHIFT(1, a);
|
||||
}
|
|
@ -20,7 +20,7 @@ namespace special_cases
|
|||
template<int a>
|
||||
struct A {
|
||||
// expected-note@-1+ {{candidate constructor}}
|
||||
explicit(1 << a)
|
||||
explicit(1 << a) // expected-warning {{converting the result of '<<' to a boolean; did you mean '(1 << -1) != 0'?}}
|
||||
// expected-note@-1 {{negative shift count -1}}
|
||||
// expected-error@-2 {{explicit specifier argument is not a constant expression}}
|
||||
A(int);
|
||||
|
|
Loading…
Reference in New Issue