Permalink
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Browse files
[Diagnostics] Warn for enum constants in bool context (-Wint-in-bool-…
…context; GCC compatibility)
Extracted from D63082.
llvm-svn: 372664
- Loading branch information
|
|
@@ -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_enum_constant_in_bool_context : Warning< |
|
|
"converting the enum constant to a boolean">, |
|
|
InGroup<IntInBoolContext>; |
|
|
def warn_left_shift_in_bool_context : Warning< |
|
|
"converting the result of '<<' to a boolean; did you mean '(%0) != 0'?">, |
|
|
InGroup<IntInBoolContext>; |
|
|
@@ -6156,6 +6159,10 @@ def warn_comparison_of_mixed_enum_types : Warning< |
|
|
"comparison of two values with different enumeration types" |
|
|
"%diff{ ($ and $)|}0,1">, |
|
|
InGroup<EnumCompare>; |
|
|
def warn_conditional_mixed_enum_types : Warning< |
|
|
"enumeration type mismatch in conditional expression" |
|
|
"%diff{ ($ and $)|}0,1">, |
|
|
InGroup<EnumCompare>; |
|
|
def warn_comparison_of_mixed_enum_types_switch : Warning< |
|
|
"comparison of two values with different enumeration types in switch statement" |
|
|
"%diff{ ($ and $)|}0,1">, |
|
|
|
|
|
@@ -11297,10 +11297,22 @@ inline QualType Sema::CheckLogicalOperands(ExprResult &LHS, ExprResult &RHS, |
|
|
if (LHS.get()->getType()->isVectorType() || RHS.get()->getType()->isVectorType()) |
|
|
return CheckVectorLogicalOperands(LHS, RHS, Loc); |
|
|
|
|
|
bool EnumConstantInBoolContext = false; |
|
|
for (const ExprResult &HS : {LHS, RHS}) { |
|
|
if (const auto *DREHS = dyn_cast<DeclRefExpr>(HS.get())) { |
|
|
const auto *ECDHS = dyn_cast<EnumConstantDecl>(DREHS->getDecl()); |
|
|
if (ECDHS && ECDHS->getInitVal() != 0 && ECDHS->getInitVal() != 1) |
|
|
EnumConstantInBoolContext = true; |
|
|
} |
|
|
} |
|
|
|
|
|
if (EnumConstantInBoolContext) |
|
|
Diag(Loc, diag::warn_enum_constant_in_bool_context); |
|
|
|
|
|
// Diagnose cases where the user write a logical and/or but probably meant a |
|
|
// bitwise one. We do this when the LHS is a non-bool integer and the RHS |
|
|
// is a constant. |
|
|
if (LHS.get()->getType()->isIntegerType() && |
|
|
if (!EnumConstantInBoolContext && LHS.get()->getType()->isIntegerType() && |
|
|
!LHS.get()->getType()->isBooleanType() && |
|
|
RHS.get()->getType()->isIntegerType() && !RHS.get()->isValueDependent() && |
|
|
// Don't warn in macros or template instantiations. |
|
|
|
|
|
@@ -14,7 +14,13 @@ typedef bool boolean; |
|
|
typedef _Bool boolean; |
|
|
#endif |
|
|
|
|
|
int test(int a) { |
|
|
enum num { |
|
|
zero, |
|
|
one, |
|
|
two, |
|
|
}; |
|
|
|
|
|
int test(int a, 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'?}} |
|
|
@@ -26,6 +32,26 @@ int test(int a) { |
|
|
if (a << TWO) // expected-warning {{converting the result of '<<' to a boolean; did you mean '(a << 2) != 0'?}} |
|
|
return a; |
|
|
|
|
|
if (n || two) |
|
|
// expected-warning@-1 {{converting the enum constant to a boolean}} |
|
|
return a; |
|
|
|
|
|
if (n == one || two) |
|
|
// expected-warning@-1 {{converting the enum constant to a boolean}} |
|
|
return a; |
|
|
|
|
|
if (r && two) |
|
|
// expected-warning@-1 {{converting the enum constant to a boolean}} |
|
|
return a; |
|
|
|
|
|
if (two && r) |
|
|
// expected-warning@-1 {{converting the enum constant to a boolean}} |
|
|
return a; |
|
|
|
|
|
if (n == one && two) |
|
|
// expected-warning@-1 {{converting the enum constant to a boolean}} |
|
|
return a; |
|
|
|
|
|
// Don't warn in macros. |
|
|
return SHIFT(1, a); |
|
|
} |