]> granicus.if.org Git - clang/commitdiff
Expand the coverage of the warning for constants on the RHS of logical operands:
authorChandler Carruth <chandlerc@gmail.com>
Tue, 31 May 2011 05:41:42 +0000 (05:41 +0000)
committerChandler Carruth <chandlerc@gmail.com>
Tue, 31 May 2011 05:41:42 +0000 (05:41 +0000)
  return f() || -1;

where the user meant to write '|'.

This bootstraps without any additional warnings.

Patch by Richard Trieu.

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

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

index 0a74daa008d94747915838f86b098e8b23e1bf0f..e75af910bdaa11be62179fd56a734c9594b6d001 100644 (file)
@@ -7797,13 +7797,15 @@ inline QualType Sema::CheckLogicalOperands( // C99 6.5.[13,14]
     // 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.
+    // Parens on the RHS are ignored.
     Expr::EvalResult Result;
-    if (rex.get()->Evaluate(Result, Context) && !Result.HasSideEffects &&
-        Result.Val.getInt() != 0 && Result.Val.getInt() != 1) {
-      Diag(Loc, diag::warn_logical_instead_of_bitwise)
-       << rex.get()->getSourceRange()
-        << (Opc == BO_LAnd ? "&&" : "||")
-        << (Opc == BO_LAnd ? "&" : "|");
+    if (rex.get()->Evaluate(Result, Context) && !Result.HasSideEffects)
+      if ((getLangOptions().Bool && !rex.get()->getType()->isBooleanType()) ||
+          (Result.Val.getInt() != 0 && Result.Val.getInt() != 1)) {
+        Diag(Loc, diag::warn_logical_instead_of_bitwise)
+          << rex.get()->getSourceRange()
+          << (Opc == BO_LAnd ? "&&" : "||")
+          << (Opc == BO_LAnd ? "&" : "|");
     }
   }
   
index 65ab3bb1262df5fb7a3768a42fd24b4497eb2db6..768e6de92c0f033104cb9b3d704722b7ad0a055c 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;
+int y = x() & 0;
index e4eeaec05d97db51474a51c1fcf8d01535c0d07f..9ce1481f16c50cc381d434b42513a3723e1444d6 100644 (file)
@@ -189,6 +189,24 @@ int test20(int x) {
   
   // no warning, this is an idiom for "true" in old C style.
   return x && (signed char)1;
+
+  return x || 0;
+  return x || 1;
+  return x || -1; // expected-warning {{use of logical || with constant operand; switch to bitwise | or remove constant}}
+  return x || 5; // expected-warning {{use of logical || with constant operand; switch to bitwise | or remove constant}}
+  return x && 0;
+  return x && 1;
+  return x && -1; // expected-warning {{use of logical && with constant operand; switch to bitwise & or remove constant}}
+  return x && 5; // expected-warning {{use of logical && with constant operand; switch to bitwise & or remove constant}}
+  return x || (0);
+  return x || (1);
+  return x || (-1); // expected-warning {{use of logical || with constant operand; switch to bitwise | or remove constant}}
+  return x || (5); // expected-warning {{use of logical || with constant operand; switch to bitwise | or remove constant}}
+  return x && (0);
+  return x && (1);
+  return x && (-1); // expected-warning {{use of logical && with constant operand; switch to bitwise & or remove constant}}
+  return x && (5); // expected-warning {{use of logical && with constant operand; switch to bitwise & or remove constant}}
+
 }
 
 struct Test21; // expected-note 2 {{forward declaration}}
index c4e9dccbf62161a672a61aeca582b44897554384..95ece48e51feb2dd15115b649440a0417dd276f9 100644 (file)
@@ -32,3 +32,34 @@ namespace test1 {
     bar(x += E_zero); // expected-error {{incompatible type}}
   }
 }
+
+int test2(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, RHS is logical op.
+  return x && true;
+  return x && false;
+  return x || true;
+  return x || false;
+
+  return x && (unsigned)0; // expected-warning {{use of logical && with constant operand; switch to bitwise & or remove constant}}
+
+  return x || (unsigned)1; // expected-warning {{use of logical || with constant operand; switch to bitwise | or remove constant}}
+
+  return x || 0; // expected-warning {{use of logical || with constant operand; switch to bitwise | or remove constant}}
+  return x || 1; // expected-warning {{use of logical || with constant operand; switch to bitwise | or remove constant}}
+  return x || -1; // expected-warning {{use of logical || with constant operand; switch to bitwise | or remove constant}}
+  return x || 5; // expected-warning {{use of logical || with constant operand; switch to bitwise | or remove constant}}
+  return x && 0; // expected-warning {{use of logical && with constant operand; switch to bitwise & or remove constant}}
+  return x && 1; // expected-warning {{use of logical && with constant operand; switch to bitwise & or remove constant}}
+  return x && -1; // expected-warning {{use of logical && with constant operand; switch to bitwise & or remove constant}}
+  return x && 5; // expected-warning {{use of logical && with constant operand; switch to bitwise & or remove constant}}
+  return x || (0); // expected-warning {{use of logical || with constant operand; switch to bitwise | or remove constant}}
+  return x || (1); // expected-warning {{use of logical || with constant operand; switch to bitwise | or remove constant}}
+  return x || (-1); // expected-warning {{use of logical || with constant operand; switch to bitwise | or remove constant}}
+  return x || (5); // expected-warning {{use of logical || with constant operand; switch to bitwise | or remove constant}}
+  return x && (0); // expected-warning {{use of logical && with constant operand; switch to bitwise & or remove constant}}
+  return x && (1); // expected-warning {{use of logical && with constant operand; switch to bitwise & or remove constant}}
+  return x && (-1); // expected-warning {{use of logical && with constant operand; switch to bitwise & or remove constant}}
+  return x && (5); // expected-warning {{use of logical && with constant operand; switch to bitwise & or remove constant}}
+}
index 3882a1f952ca7a076528f214ba4c2d483c7b4b80..8a8cf33049d7da0491b2ea3b4b9d77f835324b95 100644 (file)
@@ -8,7 +8,7 @@ void test() {
   }
 
   int n = 3;
-  switch (n && 1) { // expected-warning {{bool}}
+  switch (n && true) { // expected-warning {{bool}}
     case 1:
       break;
   }