xbolva00 updated this revision to Diff 206075.

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D63082/new/

https://reviews.llvm.org/D63082

Files:
  include/clang/Basic/DiagnosticGroups.td
  include/clang/Basic/DiagnosticSemaKinds.td
  lib/Sema/SemaChecking.cpp
  test/Analysis/misc-ps.c
  test/Sema/integer-overflow.c
  test/Sema/parentheses.c
  test/Sema/parentheses.cpp
  test/Sema/warn-int-in-bool-context.c
  test/Sema/warn-unreachable.c
  test/SemaCXX/constexpr-printing.cpp
  test/SemaCXX/integer-overflow.cpp
  test/SemaCXX/nested-name-spec.cpp
  test/SemaCXX/warn-int-in-bool-context.cpp

Index: test/SemaCXX/warn-int-in-bool-context.cpp
===================================================================
--- test/SemaCXX/warn-int-in-bool-context.cpp
+++ test/SemaCXX/warn-int-in-bool-context.cpp
@@ -0,0 +1,170 @@
+// RUN: %clang_cc1 -x c++ -fsyntax-only -verify -Wint-in-bool-context %s
+// RUN: %clang_cc1 -x c++ -fsyntax-only -verify %s
+
+#define ONE 1
+#define TWO 2
+
+enum answer {
+  foo,
+  bar,
+  yes,
+  no,
+  unknown,
+};
+
+enum fruit {
+  orange = -3,
+  lemon,
+  banana,
+  apple,
+};
+
+void g(bool b);
+
+template <bool>
+void h() {}
+template <int>
+void h() {}
+
+bool test(int a, int b, enum answer ans, enum fruit f) {
+  bool r = TWO * 7; // expected-warning {{'*' in boolean context}}
+  r = 3 * 7;        // expected-warning {{'*' in boolean context}}
+  r = a * 7;        // expected-warning {{'*' in boolean context}}
+  r = a * b;        // expected-warning {{'*' in boolean context}}
+  g(3 * 9);         // expected-warning {{'*' in boolean context}}
+  h<3 * 9>();
+
+  r = TWO << 7; // expected-warning {{'<<' in boolean context; did you mean '<'?}}
+  r = a << 7;   // expected-warning {{'<<' in boolean context; did you mean '<'?}}
+  r = ONE << b; // expected-warning {{'<<' in boolean context; did you mean '<'?}}
+
+  r = a ? ONE : TWO; // expected-warning {{'?:' with integer constants in boolean context, the expression will always evaluate to 'true'}}
+  r = a ? (1) : TWO;
+  r = a ? 3 : TWO; // expected-warning {{'?:' with integer constants in boolean context, the expression will always evaluate to 'true'}}
+  r = a ? -2 : 0;
+  r = a ? 3 : -2;
+  r = a ? 0 : TWO; // expected-warning {{'?:' with integer constants in boolean context}}
+  r = a ? 3 : ONE; // expected-warning {{'?:' with integer constants in boolean context, the expression will always evaluate to 'true'}}
+  r = a ? ONE : 0;
+  r = a ? 0 : 0;
+  r = a ? ONE : 0;
+  r = a ? ONE : ONE;
+  g(a ? 3 : 9); // expected-warning {{'?:' with integer constants in boolean context, the expression will always evaluate to 'true'}}
+
+  r = a ? yes           // expected-warning {{enum constant in boolean context}}
+        : no;           // expected-warning {{enum constant in boolean context}}
+  r = ans == yes || no; // expected-warning {{enum constant in boolean context}}
+  r = yes || ans == no; // expected-warning {{enum constant in boolean context}}
+  r = ans == yes || ans == no;
+  r = !foo;
+  r = !bar;
+  r = !yes;            // expected-warning {{enum constant in boolean context}}
+  g(ans == yes || no); // expected-warning {{enum constant in boolean context}}
+
+  if (8 * 4) // expected-warning {{'*' in boolean context}}
+    return a;
+
+  if (a * 4) // expected-warning {{'*' in boolean context}}
+    return a;
+
+  if (-TWO * b) // expected-warning {{'*' in boolean context}}
+    return a;
+
+  if (TWO << 4) // expected-warning {{'<<' in boolean context; did you mean '<'?}}
+    return a;
+
+  if (a << TWO) // expected-warning {{'<<' in boolean context; did you mean '<'?}}
+    return a;
+
+  if (ONE << b) // expected-warning {{'<<' in boolean context; did you mean '<'?}}
+    return a;
+
+  if (a ? ONE : TWO) // expected-warning {{'?:' with integer constants in boolean context, the expression will always evaluate to 'true'}}
+    return a;
+
+  if (a ? 32 : TWO) // expected-warning {{'?:' with integer constants in boolean context, the expression will always evaluate to 'true'}}
+    return a;
+
+  if (a ? 7 : TWO) // expected-warning {{'?:' with integer constants in boolean context, the expression will always evaluate to 'true'}}
+    return a;
+
+  if (ans == yes || foo)
+    return a;
+
+  if (f == apple || orange) // expected-warning {{enum constant in boolean context}}
+    return a;
+
+  if (ans == yes || no) // expected-warning {{enum constant in boolean context}}
+    return a;
+
+  if (yes || ans == no) // expected-warning {{enum constant in boolean context}}
+    return a;
+
+  if (r || a ? 7 : TWO) // expected-warning {{'?:' with integer constants in boolean context, the expression will always evaluate to 'true'}}
+    return a;
+
+  if (b && a ? 7 : TWO) // expected-warning {{'?:' with integer constants in boolean context, the expression will always evaluate to 'true'}}
+    return a;
+
+  if ((a ? 7 : TWO) && b == 32) // expected-warning {{'?:' with integer constants in boolean context, the expression will always evaluate to 'true'}}
+    return a;
+
+  if (a ? 0 : 1)
+    return a;
+
+  if (a ? 0 : 2) // expected-warning {{'?:' with integer constants in boolean context}}
+    return a;
+
+  if (a ? ONE : 0)
+    return a;
+
+  for (; 1 * 7;) // expected-warning {{'*' in boolean context}}
+    ;
+
+  for (; a ? 7 : TWO;) // expected-warning {{'?:' with integer constants in boolean context, the expression will always evaluate to 'true'}}
+    a--;
+
+  for (; a ? 0 : ONE;)
+    a--;
+
+  for (; 1 << 7;) // expected-warning {{'<<' in boolean context; did you mean '<'?}}
+    ;
+
+  for (; ans == yes || no;) // expected-warning {{enum constant in boolean context}}
+    ;
+
+  for (; ans == yes || ans == no;)
+    ;
+
+  while (a * b) // expected-warning {{'*' in boolean context}}
+    ;
+
+  while (a ? 7 : TWO) // expected-warning {{'?:' with integer constants in boolean context, the expression will always evaluate to 'true'}}
+    ;
+
+  while (a ? 0 : ONE)
+    ;
+
+  while (a << b) // expected-warning {{'<<' in boolean context; did you mean '<'?}}
+    ;
+
+  while (ans == yes || no) // expected-warning {{enum constant in boolean context}}
+    ;
+
+  while (ans == yes || ans == no)
+    ;
+
+  if (ONE)
+    return 5 * b; // expected-warning {{'*' in boolean context}}
+
+  if (ONE)
+    return ONE << a; // expected-warning {{'<<' in boolean context; did you mean '<'?}}
+
+  if (ONE)
+    return ans == yes || no; // expected-warning {{enum constant in boolean context}}
+
+  if (ONE)
+    return b ? 8 : 64; // expected-warning {{'?:' with integer constants in boolean context, the expression will always evaluate to 'true'}}
+
+  return a << b; // expected-warning {{'<<' in boolean context; did you mean '<'?}}
+}
Index: test/SemaCXX/nested-name-spec.cpp
===================================================================
--- test/SemaCXX/nested-name-spec.cpp
+++ test/SemaCXX/nested-name-spec.cpp
@@ -402,9 +402,9 @@
 T1<C2::N1> var_1a;
 T1<C2:N1> var_1b;  // expected-error{{unexpected ':' in nested name specifier; did you mean '::'?}}
 template<int N> int F() {}
-int (*X1)() = (B1::B2 ? F<1> : F<2>);
+int (*X1)() = (B1::B2 ? F<1> : F<2>); // expected-warning {{enum constant in boolean context}}
 int (*X2)() = (B1:B2 ? F<1> : F<2>);  // expected-error{{unexpected ':' in nested name specifier; did you mean '::'?}}
-
+// expected-warning@-1 {{enum constant in boolean context}}
 // Bit fields + templates
 struct S7a {
   T1<B1::B2>::C1 m1 : T1<B1::B2>::N1;
Index: test/SemaCXX/integer-overflow.cpp
===================================================================
--- test/SemaCXX/integer-overflow.cpp
+++ test/SemaCXX/integer-overflow.cpp
@@ -41,13 +41,13 @@
   uint64_t not_overflow2 = (1ULL * ((uint64_t)(4608) * (1024 * 1024)) + 2ULL);
 
 // expected-warning@+1 2{{overflow in expression; result is 536870912 with type 'int'}}
-  overflow = 4608 * 1024 * 1024 ?  4608 * 1024 * 1024 : 0;
+  overflow = 4608 * 1024 * 1024 ?  4608 * 1024 * 1024 : 0; // expected-warning {{'*' in boolean context}}
 
 // expected-warning@+1 {{overflow in expression; result is 536870912 with type 'int'}}
   overflow =  0 ? 0 : 4608 * 1024 * 1024;
 
 // expected-warning@+1 {{overflow in expression; result is 536870912 with type 'int'}}
-  if (4608 * 1024 * 1024)
+  if (4608 * 1024 * 1024) // expected-warning {{'*' in boolean context}}
     return 0;
 
 // expected-warning@+1 {{overflow in expression; result is 536870912 with type 'int'}}
@@ -100,7 +100,7 @@
 #endif
 
 // expected-warning@+1 {{overflow in expression; result is 536870912 with type 'int'}}
-  while (4608 * 1024 * 1024);
+  while (4608 * 1024 * 1024); // expected-warning {{'*' in boolean context}}
 
 // expected-warning@+1 {{overflow in expression; result is 536870912 with type 'int'}}
   while ((uint64_t)(4608 * 1024 * 1024));
@@ -121,7 +121,7 @@
   while ((uint64_t)((uint64_t)(4608 * 1024 * 1024) * (uint64_t)(4608 * 1024 * 1024)));
 
 // expected-warning@+1 {{overflow in expression; result is 536870912 with type 'int'}}
-  do { } while (4608 * 1024 * 1024);
+  do { } while (4608 * 1024 * 1024); // expected-warning {{'*' in boolean context}}
 
 // expected-warning@+1 {{overflow in expression; result is 536870912 with type 'int'}}
   do { } while ((uint64_t)(4608 * 1024 * 1024));
Index: test/SemaCXX/constexpr-printing.cpp
===================================================================
--- test/SemaCXX/constexpr-printing.cpp
+++ test/SemaCXX/constexpr-printing.cpp
@@ -99,6 +99,7 @@
   a:b:return;
 }
 
+// expected-warning@+1 {{'*' in boolean context}}
 constexpr bool test_bool_printing(bool b) { return 1 / !(2*b | !(2*b)); } // expected-note 2{{division by zero}}
 constexpr bool test_bool_0 = test_bool_printing(false); // expected-error {{constant expr}} expected-note {{in call to 'test_bool_printing(false)'}}
 constexpr bool test_bool_1 = test_bool_printing(true); // expected-error {{constant expr}} expected-note {{in call to 'test_bool_printing(true)'}}
Index: test/Sema/warn-unreachable.c
===================================================================
--- test/Sema/warn-unreachable.c
+++ test/Sema/warn-unreachable.c
@@ -141,7 +141,9 @@
 void test_mul_and_zero(int x) {
   if (x & 0) calledFun(); // expected-warning {{will never be executed}}
   if (0 & x) calledFun(); // expected-warning {{will never be executed}}
+  // expected-warning@+1 {{'*' in boolean context}}
   if (x * 0) calledFun(); // expected-warning {{will never be executed}}
+  // expected-warning@+1 {{'*' in boolean context}}
   if (0 * x) calledFun(); // expected-warning {{will never be executed}}
 }
 
Index: test/Sema/warn-int-in-bool-context.c
===================================================================
--- test/Sema/warn-int-in-bool-context.c
+++ test/Sema/warn-int-in-bool-context.c
@@ -0,0 +1,149 @@
+// RUN: %clang_cc1 -x c -fsyntax-only -verify -Wint-in-bool-context %s
+// RUN: %clang_cc1 -x c -fsyntax-only -verify %s
+
+#define ONE 1
+#define TWO 2
+
+enum answer {
+  yes,
+  no,
+  unknown,
+};
+
+void g(_Bool b);
+
+_Bool test(int a, int b, enum answer ans) {
+  _Bool r = TWO * 7; // expected-warning {{'*' in boolean context}}
+  r = 3 * 7;        // expected-warning {{'*' in boolean context}}
+  r = a * 7;        // expected-warning {{'*' in boolean context}}
+  r = a * b;        // expected-warning {{'*' in boolean context}}
+  g(3 * 9);         // expected-warning {{'*' in boolean context}}
+
+  r = TWO << 7; // expected-warning {{'<<' in boolean context; did you mean '<'?}}
+  r = a << 7;   // expected-warning {{'<<' in boolean context; did you mean '<'?}}
+  r = ONE << b; // expected-warning {{'<<' in boolean context; did you mean '<'?}}
+
+  r = a ? ONE : TWO; // expected-warning {{'?:' with integer constants in boolean context, the expression will always evaluate to 'true'}}
+  r = a ? (1) : TWO;
+  r = a ? 3 : TWO; // expected-warning {{'?:' with integer constants in boolean context, the expression will always evaluate to 'true'}}
+  r = a ? -2 : 0;
+  r = a ? 3 : -2;
+  r = a ? 0 : TWO; // expected-warning {{'?:' with integer constants in boolean context}}
+  r = a ? 3 : ONE; // expected-warning {{'?:' with integer constants in boolean context, the expression will always evaluate to 'true'}}
+  r = a ? ONE : 0;
+  r = a ? 0 : 0;
+  r = a ? ONE : 0;
+  r = a ? ONE : ONE;
+  g(a ? 3 : 9); // expected-warning {{'?:' with integer constants in boolean context, the expression will always evaluate to 'true'}}
+
+  r = a ? yes          
+        : no;          
+  r = ans == yes || no;
+  r = yes || ans == no;
+  r = ans == yes || ans == no;
+  r = !yes;
+  r = !no;
+  r = !unknown;
+  g(ans == yes || no);
+
+  if (8 * 4) // expected-warning {{'*' in boolean context}}
+    return a;
+
+  if (a * 4) // expected-warning {{'*' in boolean context}}
+    return a;
+
+  if (-TWO * b) // expected-warning {{'*' in boolean context}}
+    return a;
+
+  if (TWO << 4) // expected-warning {{'<<' in boolean context; did you mean '<'?}}
+    return a;
+
+  if (a << TWO) // expected-warning {{'<<' in boolean context; did you mean '<'?}}
+    return a;
+
+  if (ONE << b) // expected-warning {{'<<' in boolean context; did you mean '<'?}}
+    return a;
+
+  if (a ? ONE : TWO) // expected-warning {{'?:' with integer constants in boolean context, the expression will always evaluate to 'true'}}
+    return a;
+
+  if (a ? 32 : TWO) // expected-warning {{'?:' with integer constants in boolean context, the expression will always evaluate to 'true'}}
+    return a;
+
+  if (a ? 7 : TWO) // expected-warning {{'?:' with integer constants in boolean context, the expression will always evaluate to 'true'}}
+    return a;
+
+  if (ans == yes || no)
+    return a;
+
+  if (yes || ans == no)
+    return a;
+
+  if (r || a ? 7 : TWO) // expected-warning {{'?:' with integer constants in boolean context, the expression will always evaluate to 'true'}}
+    return a;
+
+  if (b && a ? 7 : TWO) // expected-warning {{'?:' with integer constants in boolean context, the expression will always evaluate to 'true'}}
+    return a;
+
+  if ((a ? 7 : TWO) && b == 32) // expected-warning {{'?:' with integer constants in boolean context, the expression will always evaluate to 'true'}}
+    return a;
+
+  if (a ? 0 : 1)
+    return a;
+
+  if (a ? 0 : 2) // expected-warning {{'?:' with integer constants in boolean context}}
+    return a;
+
+  if (a ? ONE : 0)
+    return a;
+
+  for (; 1 * 7;) // expected-warning {{'*' in boolean context}}
+    ;
+
+  for (; a ? 7 : TWO;) // expected-warning {{'?:' with integer constants in boolean context, the expression will always evaluate to 'true'}}
+    a--;
+
+  for (; a ? 0 : ONE;)
+    a--;
+
+  for (; 1 << 7;) // expected-warning {{'<<' in boolean context; did you mean '<'?}}
+    ;
+
+  for (; ans == yes || no;)
+    ;
+
+  for (; ans == yes || ans == no;)
+    ;
+
+  while (a * b) // expected-warning {{'*' in boolean context}}
+    ;
+
+  while (a ? 7 : TWO) // expected-warning {{'?:' with integer constants in boolean context, the expression will always evaluate to 'true'}}
+    ;
+
+  while (a ? 0 : ONE)
+    ;
+
+  while (a << b) // expected-warning {{'<<' in boolean context; did you mean '<'?}}
+    ;
+
+  while (ans == yes || no)
+    ;
+
+  while (ans == yes || ans == no)
+    ;
+
+  if (ONE)
+    return 5 * b; // expected-warning {{'*' in boolean context}}
+
+  if (ONE)
+    return ONE << a; // expected-warning {{'<<' in boolean context; did you mean '<'?}}
+
+  if (ONE)
+    return ans == yes || no;
+
+  if (ONE)
+    return b ? 8 : 64; // expected-warning {{'?:' with integer constants in boolean context, the expression will always evaluate to 'true'}}
+
+  return a << b; // expected-warning {{'<<' in boolean context; did you mean '<'?}}
+}
Index: test/Sema/parentheses.cpp
===================================================================
--- test/Sema/parentheses.cpp
+++ test/Sema/parentheses.cpp
@@ -20,6 +20,7 @@
   // CHECK: fix-it:"{{.*}}":{[[@LINE-5]]:14-[[@LINE-5]]:14}:"("
   // CHECK: fix-it:"{{.*}}":{[[@LINE-6]]:23-[[@LINE-6]]:23}:")"
 
+  // expected-warning@+1 {{'*' in boolean context}}
   (void)(x * (x == y) ? 1 : 2); // expected-warning {{operator '?:' has lower precedence than '*'}} \
                                 // expected-note {{place parentheses around the '*' expression to silence this warning}} \
                                 // expected-note {{place parentheses around the '?:' expression to evaluate it first}}
Index: test/Sema/parentheses.c
===================================================================
--- test/Sema/parentheses.c
+++ test/Sema/parentheses.c
@@ -119,6 +119,7 @@
   // CHECK: fix-it:"{{.*}}":{[[@LINE-5]]:14-[[@LINE-5]]:14}:"("
   // CHECK: fix-it:"{{.*}}":{[[@LINE-6]]:23-[[@LINE-6]]:23}:")"
 
+  // expected-warning@+1 {{'*' in boolean context}}
   (void)(x * (x == y) ? 1 : 2); // expected-warning {{operator '?:' has lower precedence than '*'}} \
                                 // expected-note {{place parentheses around the '*' expression to silence this warning}} \
                                 // expected-note {{place parentheses around the '?:' expression to evaluate it first}}
Index: test/Sema/integer-overflow.c
===================================================================
--- test/Sema/integer-overflow.c
+++ test/Sema/integer-overflow.c
@@ -34,13 +34,13 @@
   uint64_t not_overflow2 = (1ULL * ((uint64_t)(4608) * (1024 * 1024)) + 2ULL);
 
 // expected-warning@+1 2{{overflow in expression; result is 536870912 with type 'int'}}
-  overflow = 4608 * 1024 * 1024 ?  4608 * 1024 * 1024 : 0;
+  overflow = 4608 * 1024 * 1024 ?  4608 * 1024 * 1024 : 0; // expected-warning {{'*' in boolean context}}
 
 // expected-warning@+1 {{overflow in expression; result is 536870912 with type 'int'}}
   overflow =  0 ? 0 : 4608 * 1024 * 1024;
 
 // expected-warning@+1 {{overflow in expression; result is 536870912 with type 'int'}}
-  if (4608 * 1024 * 1024)
+  if (4608 * 1024 * 1024) // expected-warning {{'*' in boolean context}}
     return 0;
 
 // expected-warning@+1 {{overflow in expression; result is 536870912 with type 'int'}}
@@ -83,7 +83,7 @@
   }
 
 // expected-warning@+1 {{overflow in expression; result is 536870912 with type 'int'}}
-  while (4608 * 1024 * 1024);
+  while (4608 * 1024 * 1024); // expected-warning {{'*' in boolean context}}
 
 // expected-warning@+1 {{overflow in expression; result is 536870912 with type 'int'}}
   while ((uint64_t)(4608 * 1024 * 1024));
@@ -101,7 +101,7 @@
   while ((uint64_t)((uint64_t)(4608 * 1024 * 1024) * (uint64_t)(4608 * 1024 * 1024)));
 
 // expected-warning@+1 {{overflow in expression; result is 536870912 with type 'int'}}
-  do { } while (4608 * 1024 * 1024);
+  do { } while (4608 * 1024 * 1024); // expected-warning {{'*' in boolean context}}
 
 // expected-warning@+1 {{overflow in expression; result is 536870912 with type 'int'}}
   do { } while ((uint64_t)(4608 * 1024 * 1024));
Index: test/Analysis/misc-ps.c
===================================================================
--- test/Analysis/misc-ps.c
+++ test/Analysis/misc-ps.c
@@ -96,7 +96,7 @@
 extern int nR10376675;
 void barR10376675(int *x) {
   int *pm;
-  if (nR10376675 * 2) {
+  if (nR10376675 * 2) { // expected-warning {{'*' in boolean context}}
     int *pk  = bazR10376675();
     pm = pk; //expected-warning {{never read}}
   }
Index: lib/Sema/SemaChecking.cpp
===================================================================
--- lib/Sema/SemaChecking.cpp
+++ lib/Sema/SemaChecking.cpp
@@ -11116,6 +11116,42 @@
   return true;
 }
 
+static void DiagnoseIntInBoolContext(Sema &S, const 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_Mul)
+      S.Diag(ExprLoc, diag::warn_mul_in_bool_context);
+    if (Opc == BO_Shl)
+      S.Diag(ExprLoc, diag::warn_left_shift_in_bool_context);
+  }
+
+  const auto *DRE = dyn_cast<DeclRefExpr>(E);
+  if (DRE && S.getLangOpts().CPlusPlus) {
+    const auto *ECD = dyn_cast<EnumConstantDecl>(DRE->getDecl());
+    if (ECD && ECD->getInitVal() != 0 && ECD->getInitVal() != 1)
+      S.Diag(ExprLoc, diag::warn_enum_constant_in_bool_context);
+  }
+
+  if (const auto *CO = dyn_cast<ConditionalOperator>(E)) {
+    const auto *LHS = dyn_cast<IntegerLiteral>(CO->getTrueExpr());
+    const auto *RHS = dyn_cast<IntegerLiteral>(CO->getFalseExpr());
+    if (LHS && RHS) {
+      if ((LHS->getValue() == 0 || LHS->getValue() == 1) &&
+          (RHS->getValue() == 0 || RHS->getValue() == 1))
+        // Do not diagnose common idioms
+        return;
+      if (LHS->getValue() != 0 && LHS->getValue() != 0)
+        S.Diag(ExprLoc,
+               diag::warn_integer_constants_in_conditional_always_true);
+      else
+        S.Diag(ExprLoc, diag::warn_integer_constants_in_conditional);
+    }
+  }
+}
+
 static void
 CheckImplicitConversion(Sema &S, Expr *E, QualType T, SourceLocation CC,
                         bool *ICContext = nullptr) {
@@ -11341,6 +11377,9 @@
 
   S.DiscardMisalignedMemberAddress(Target, E);
 
+  if (Target->isBooleanType())
+    DiagnoseIntInBoolContext(S, E);
+
   if (!Source->isIntegerType() || !Target->isIntegerType())
     return;
 
@@ -11540,6 +11579,8 @@
   if (isa<ConditionalOperator>(E)) {
     ConditionalOperator *CO = cast<ConditionalOperator>(E);
     CheckConditionalOperator(S, CO, CC, T);
+    if (T->isBooleanType())
+      DiagnoseIntInBoolContext(S, E);
     return;
   }
 
Index: include/clang/Basic/DiagnosticSemaKinds.td
===================================================================
--- include/clang/Basic/DiagnosticSemaKinds.td
+++ include/clang/Basic/DiagnosticSemaKinds.td
@@ -5620,6 +5620,24 @@
 def note_precedence_conditional_first : Note<
   "place parentheses around the '?:' expression to evaluate it first">;
 
+def warn_mul_in_bool_context : Warning<
+  "'*' in boolean context">,
+  InGroup<IntInBoolContext>;
+def warn_left_shift_in_bool_context : Warning<
+  "'<<' in boolean context; did you mean '<'?">,
+  InGroup<IntInBoolContext>;
+def warn_enum_constant_in_bool_context : Warning<
+  "enum constant in boolean context">,
+  InGroup<IntInBoolContext>;
+
+def warn_integer_constants_in_conditional : Warning<
+  "'?:' with integer constants in boolean context">,
+  InGroup<IntInBoolContext>;
+def warn_integer_constants_in_conditional_always_true : Warning<
+  "'?:' with integer constants in boolean context, the expression will always "
+  "evaluate to 'true'">,
+  InGroup<IntInBoolContext>;
+
 def warn_logical_instead_of_bitwise : Warning<
   "use of logical '%0' with constant operand">,
   InGroup<DiagGroup<"constant-logical-operand">>;
Index: include/clang/Basic/DiagnosticGroups.td
===================================================================
--- include/clang/Basic/DiagnosticGroups.td
+++ include/clang/Basic/DiagnosticGroups.td
@@ -479,6 +479,7 @@
 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">;
@@ -498,7 +499,8 @@
                                     [TautologicalConstantCompare,
                                      TautologicalPointerCompare,
                                      TautologicalOverlapCompare,
-                                     TautologicalUndefinedCompare]>;
+                                     TautologicalUndefinedCompare,
+                                     IntInBoolContext]>;
 def HeaderHygiene : DiagGroup<"header-hygiene">;
 def DuplicateDeclSpecifier : DiagGroup<"duplicate-decl-specifier">;
 def CompareDistinctPointerType : DiagGroup<"compare-distinct-pointer-types">;
@@ -764,7 +766,6 @@
 def TypeSafety : DiagGroup<"type-safety">;
 
 def IncompatibleExceptionSpec : DiagGroup<"incompatible-exception-spec">;
-
 def IntToVoidPointerCast : DiagGroup<"int-to-void-pointer-cast">;
 def IntToPointerCast : DiagGroup<"int-to-pointer-cast",
                                  [IntToVoidPointerCast]>;
_______________________________________________
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to