]> granicus.if.org Git - clang/commitdiff
Extend -Wtautological-overlap-compare to more cases.
authorRichard Trieu <rtrieu@google.com>
Wed, 4 Jan 2017 00:46:30 +0000 (00:46 +0000)
committerRichard Trieu <rtrieu@google.com>
Wed, 4 Jan 2017 00:46:30 +0000 (00:46 +0000)
Previously, -Wtautological-overlap-compare did not warn on cases where the
boolean expression was in an assignment or return statement.  This patch
should cause all boolean statements to be passed to the tautological compare
checks in the CFG analysis.

This is one of the issues from PR13101

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

lib/Analysis/CFG.cpp
test/Sema/warn-overlap.c

index bf3cc05cdb6e84d00c0b3ea61f64d51928080cd7..a1a463f1d03763ecd0e7166a949c992f8cf0e8e0 100644 (file)
@@ -1690,15 +1690,19 @@ CFGBuilder::VisitLogicalOperator(BinaryOperator *B,
     // we have been provided.
     ExitBlock = RHSBlock = createBlock(false);
 
+    // Even though KnownVal is only used in the else branch of the next
+    // conditional, tryEvaluateBool performs additional checking on the
+    // Expr, so it should be called unconditionally.
+    TryResult KnownVal = tryEvaluateBool(RHS);
+    if (!KnownVal.isKnown())
+      KnownVal = tryEvaluateBool(B);
+
     if (!Term) {
       assert(TrueBlock == FalseBlock);
       addSuccessor(RHSBlock, TrueBlock);
     }
     else {
       RHSBlock->setTerminator(Term);
-      TryResult KnownVal = tryEvaluateBool(RHS);
-      if (!KnownVal.isKnown())
-        KnownVal = tryEvaluateBool(B);
       addSuccessor(RHSBlock, TrueBlock, !KnownVal.isFalse());
       addSuccessor(RHSBlock, FalseBlock, !KnownVal.isTrue());
     }
index 1e8a614d0ffc7b348a91afee2d726b844cbc849f..6299c511fe230bde00c9de4a4508a019b2efabaf 100644 (file)
@@ -96,3 +96,48 @@ void array_out_of_bounds() {
   int buffer[4];
   x = (-7 > 0) ? (buffer[-7]) : 0;
 }
+
+void bool_contexts(int x) {
+  if (x > 4 || x < 10) {}
+  // expected-warning@-1{{overlapping comparisons always evaluate to true}}
+  for (;x > 4 || x < 10;) {}
+  // expected-warning@-1{{overlapping comparisons always evaluate to true}}
+  while (x > 4 || x < 10) {}
+  // expected-warning@-1{{overlapping comparisons always evaluate to true}}
+  do {} while (x > 4 || x < 10);
+  // expected-warning@-1{{overlapping comparisons always evaluate to true}}
+  x = (x > 4 || x < 10) ? 1 : 2;
+  // expected-warning@-1{{overlapping comparisons always evaluate to true}}
+  if ((void)5, x > 4 || x < 10) {}
+  // expected-warning@-1{{overlapping comparisons always evaluate to true}}
+}
+
+void assignment(int x) {
+  int a = x > 4 || x < 10;
+  // expected-warning@-1{{overlapping comparisons always evaluate to true}}
+  int b = x < 2 && x > 5;
+  // expected-warning@-1{{overlapping comparisons always evaluate to false}}
+
+  int c = x != 1 || x != 3;
+  // expected-warning@-1{{overlapping comparisons always evaluate to true}}
+  int d = x == 1 && x == 2;
+  // expected-warning@-1{{overlapping comparisons always evaluate to false}}
+
+  int e = x < 1 || x != 0;
+  // expected-warning@-1{{overlapping comparisons always evaluate to true}}
+}
+
+int returns(int x) {
+  return x > 4 || x < 10;
+  // expected-warning@-1{{overlapping comparisons always evaluate to true}}
+  return x < 2 && x > 5;
+  // expected-warning@-1{{overlapping comparisons always evaluate to false}}
+
+  return x != 1 || x != 3;
+  // expected-warning@-1{{overlapping comparisons always evaluate to true}}
+  return x == 1 && x == 2;
+  // expected-warning@-1{{overlapping comparisons always evaluate to false}}
+
+  return x < 1 || x != 0;
+  // expected-warning@-1{{overlapping comparisons always evaluate to true}}
+}