]> granicus.if.org Git - clang/commitdiff
[Static Analyzer] Warn when inner and outer conditions are identical. The inner condi...
authorDaniel Marjamaki <daniel.marjamaki@evidente.se>
Mon, 10 Aug 2015 07:18:29 +0000 (07:18 +0000)
committerDaniel Marjamaki <daniel.marjamaki@evidente.se>
Mon, 10 Aug 2015 07:18:29 +0000 (07:18 +0000)
Reviewed in http://reviews.llvm.org/D10892.

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

lib/StaticAnalyzer/Checkers/IdenticalExprChecker.cpp
test/Analysis/identical-expressions.cpp

index 58d0783f3974dd324d0285bbbc56a35d0b0cd330..23fa2d11a7e2388f9f9d07ea9ad896d6871a67b3 100644 (file)
@@ -108,6 +108,24 @@ bool FindIdenticalExprVisitor::VisitIfStmt(const IfStmt *I) {
   const Stmt *Stmt1 = I->getThen();
   const Stmt *Stmt2 = I->getElse();
 
+  // Check for identical inner condition:
+  //
+  // if (x<10) {
+  //   if (x<10) {
+  //   ..
+  if (const CompoundStmt *CS = dyn_cast<CompoundStmt>(Stmt1)) {
+    if (!CS->body_empty()) {
+      const IfStmt *InnerIf = dyn_cast<IfStmt>(*CS->body_begin());
+      if (InnerIf && isIdenticalStmt(AC->getASTContext(), I->getCond(), InnerIf->getCond(), /*ignoreSideEffects=*/ false)) {
+        PathDiagnosticLocation ELoc(InnerIf->getCond(), BR.getSourceManager(), AC);
+        BR.EmitBasicReport(AC->getDecl(), Checker, "Identical conditions",
+          categories::LogicError,
+          "conditions of the inner and outer statements are identical",
+          ELoc);
+      }
+    }
+  }
+
   // Check for identical conditions:
   //
   // if (b) {
index 46dd56289c4effc4ae8a8fe61b96ceacb99db1d5..138cd7ce9887cd7f02d72b62b8e8fd15f8027882 100644 (file)
@@ -1530,3 +1530,35 @@ void test_nowarn_long() {
     c = 0LL;
   }
 }
+
+// Identical inner conditions
+
+void test_warn_inner_if_1(int x) {
+  if (x == 1) {
+    if (x == 1) // expected-warning {{conditions of the inner and outer statements are identical}}
+      ;
+  }
+
+  // FIXME: Should warn here. The warning is currently not emitted because there
+  // is code between the conditions.
+  if (x == 1) {
+    int y = x;
+    if (x == 1)
+      ;
+  }
+}
+
+void test_nowarn_inner_if_1(int x) {
+  // Don't warn when condition has side effects.
+  if (x++ == 1) {
+    if (x++ == 1)
+      ;
+  }
+
+  // Don't warn when x is changed before inner condition.
+  if (x < 10) {
+    x++;
+    if (x < 10)
+      ;
+  }
+}