]> granicus.if.org Git - clang/commitdiff
turn down the logical bitwise confusion warning to not warn
authorChris Lattner <sabre@nondot.org>
Sat, 24 Jul 2010 01:10:11 +0000 (01:10 +0000)
committerChris Lattner <sabre@nondot.org>
Sat, 24 Jul 2010 01:10:11 +0000 (01:10 +0000)
when the RHS of the ||/&& is ever 0 or 1.  This handles a variety of
creative idioms for "true" used in C programs and fixes many false
positives at the expense of a few false negatives.  This fixes
rdar://8230351.

git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@109314 91177308-0d34-0410-b5e6-96231b3b80d8

lib/Sema/SemaExpr.cpp
test/CodeGenCXX/static-init-2.cpp
test/Sema/exprs.c
test/Sema/switch.c
test/SemaCXX/switch.cpp

index 8b2e0203b38e2b90bf9075bde7291d908fc09a89..5281f3ff7931914fa87022ed1cf541edef657caa 100644 (file)
@@ -5819,18 +5819,21 @@ inline QualType Sema::CheckLogicalOperands( // C99 6.5.[13,14]
   // bitwise one.  We do this when the LHS is a non-bool integer and the RHS
   // is a constant.
   if (lex->getType()->isIntegerType() && !lex->getType()->isBooleanType() &&
-      rex->getType()->isIntegerType() && rex->isEvaluatable(Context) &&
-      // Don't warn if the RHS is a (constant folded) boolean expression like
-      // "sizeof(int) == 4".
-      !rex->isKnownToHaveBooleanValue() &&
+      rex->getType()->isIntegerType() &&
       // Don't warn in macros.
-      !Loc.isMacroID())
-    Diag(Loc, diag::warn_logical_instead_of_bitwise)
-     << rex->getSourceRange()
-      << (Opc == BinaryOperator::LAnd ? "&&" : "||")
-      << (Opc == BinaryOperator::LAnd ? "&" : "|");
-  
-  
+      !Loc.isMacroID()) {
+    // If the RHS can be constant folded, and if it constant folds to something
+    // that isn't 0 or 1 (which indicate a potential logical operation that
+    // happened to fold to true/false) then warn.
+    Expr::EvalResult Result;
+    if (rex->Evaluate(Result, Context) && !Result.HasSideEffects &&
+        Result.Val.getInt() != 0 && Result.Val.getInt() != 1) {
+      Diag(Loc, diag::warn_logical_instead_of_bitwise)
+       << rex->getSourceRange()
+        << (Opc == BinaryOperator::LAnd ? "&&" : "||")
+        << (Opc == BinaryOperator::LAnd ? "&" : "|");
+    }
+  }
   
   if (!Context.getLangOptions().CPlusPlus) {
     UsualUnaryConversions(lex);
index 7eb4a7d5aa79345f54c89d9310982512c3741c89..65ab3bb1262df5fb7a3768a42fd24b4497eb2db6 100644 (file)
@@ -3,4 +3,4 @@
 // Make sure we don't crash generating y; its value is constant, but the
 // initializer has side effects, so EmitConstantExpr should fail.
 int x();
-int y = x() && 0;   // expected-warning {{use of logical && with constant operand}}
+int y = x() && 0;
index 9d3da908549faa869ac402f5f9ba220be75b8a8e..56a52bed1bc364b3bb696a1fdbac28171040b8ca 100644 (file)
@@ -145,5 +145,8 @@ void test19() {
 int test20(int x) {
   return x && 4; // expected-warning {{use of logical && with constant operand; switch to bitwise & or remove constant}}
 
-  return x && sizeof(int) == 4;  // no warning.
+  return x && sizeof(int) == 4;  // no warning, RHS is logical op.
+  
+  // no warning, this is an idiom for "true" in old C style.
+  return x && (signed char)1;
 }
index 4e39e0f0c2d5d527eaca226c9da696da2745109f..bb4822916cc72ecc5f117ad8a50331f8a79af672 100644 (file)
@@ -50,14 +50,12 @@ void test4()
   }
   
   switch (cond) {
-  case g() && 0: // expected-error {{expression is not an integer constant expression}} // expected-note {{subexpression not valid in an integer constant expression}} \
-                    expected-warning {{use of logical && with constant operand}}
+  case g() && 0: // expected-error {{expression is not an integer constant expression}} // expected-note {{subexpression not valid in an integer constant expression}}
     break;
   }
   
   switch (cond) {
-  case 0 ... g() || 1: // expected-error {{expression is not an integer constant expression}} // expected-note {{subexpression not valid in an integer constant expression}} \\
-                          expected-warning {{use of logical || with constant operand}}
+  case 0 ... g() || 1: // expected-error {{expression is not an integer constant expression}} // expected-note {{subexpression not valid in an integer constant expression}}
     break;
   }
 }
index 54240dcc305f619fe976e47aab44caaf95314a59..fc13630bbf12f457b840fbc91336a6564655d8f7 100644 (file)
@@ -8,8 +8,7 @@ void test() {
   }
 
   int n = 3;
-  switch (n && 1) { // expected-warning {{bool}} \
-                    // expected-warning {{use of logical && with constant operand}}
+  switch (n && 1) { // expected-warning {{bool}}
     case 1:
       break;
   }