r372664 - [Diagnostics] Warn for enum constants in bool context (-Wint-in-bool-context; GCC compatibility)

David Bolvansky via cfe-commits cfe-commits at lists.llvm.org
Mon Sep 23 15:09:49 PDT 2019


Author: xbolva00
Date: Mon Sep 23 15:09:49 2019
New Revision: 372664

URL: http://llvm.org/viewvc/llvm-project?rev=372664&view=rev
Log:
[Diagnostics] Warn for enum constants in bool context (-Wint-in-bool-context; GCC compatibility)

Extracted from D63082.


Modified:
    cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td
    cfe/trunk/lib/Sema/SemaExpr.cpp
    cfe/trunk/test/Sema/warn-int-in-bool-context.c

Modified: cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td?rev=372664&r1=372663&r2=372664&view=diff
==============================================================================
--- cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td (original)
+++ cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td Mon Sep 23 15:09:49 2019
@@ -5720,6 +5720,9 @@ def warn_precedence_conditional : Warnin
 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
   "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">,

Modified: cfe/trunk/lib/Sema/SemaExpr.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaExpr.cpp?rev=372664&r1=372663&r2=372664&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/SemaExpr.cpp (original)
+++ cfe/trunk/lib/Sema/SemaExpr.cpp Mon Sep 23 15:09:49 2019
@@ -11297,10 +11297,22 @@ inline QualType Sema::CheckLogicalOperan
   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.

Modified: cfe/trunk/test/Sema/warn-int-in-bool-context.c
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Sema/warn-int-in-bool-context.c?rev=372664&r1=372663&r2=372664&view=diff
==============================================================================
--- cfe/trunk/test/Sema/warn-int-in-bool-context.c (original)
+++ cfe/trunk/test/Sema/warn-int-in-bool-context.c Mon Sep 23 15:09:49 2019
@@ -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 at -1 {{converting the enum constant to a boolean}}
+    return a;
+
+  if (n == one || two)
+    // expected-warning at -1 {{converting the enum constant to a boolean}}
+    return a;
+
+  if (r && two)
+    // expected-warning at -1 {{converting the enum constant to a boolean}}
+    return a;
+
+  if (two && r)
+    // expected-warning at -1 {{converting the enum constant to a boolean}}
+    return a;
+
+  if (n == one && two)
+    // expected-warning at -1 {{converting the enum constant to a boolean}}
+    return a;
+
   // Don't warn in macros.
   return SHIFT(1, a);
 }




More information about the cfe-commits mailing list