r203585 - [analyzer] Check all conditions in a chained if against each other.
Jordan Rose
jordan_rose at apple.com
Tue Mar 11 09:52:29 PDT 2014
Author: jrose
Date: Tue Mar 11 11:52:29 2014
New Revision: 203585
URL: http://llvm.org/viewvc/llvm-project?rev=203585&view=rev
Log:
[analyzer] Check all conditions in a chained if against each other.
Like the binary operator check of r201702, this actually checks the
condition of every if in a chain against every other condition, an
O(N^2) operation. In most cases N should be small enough to make this
practical, and checking all cases like this makes it much more likely
to catch a copy-paste error within the same series of branches.
Part of IdenticalExprChecker; patch by Daniel Fahlgren!
Modified:
cfe/trunk/lib/StaticAnalyzer/Checkers/IdenticalExprChecker.cpp
cfe/trunk/test/Analysis/identical-expressions.cpp
Modified: cfe/trunk/lib/StaticAnalyzer/Checkers/IdenticalExprChecker.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/StaticAnalyzer/Checkers/IdenticalExprChecker.cpp?rev=203585&r1=203584&r2=203585&view=diff
==============================================================================
--- cfe/trunk/lib/StaticAnalyzer/Checkers/IdenticalExprChecker.cpp (original)
+++ cfe/trunk/lib/StaticAnalyzer/Checkers/IdenticalExprChecker.cpp Tue Mar 11 11:52:29 2014
@@ -108,6 +108,30 @@ bool FindIdenticalExprVisitor::VisitIfSt
const Stmt *Stmt1 = I->getThen();
const Stmt *Stmt2 = I->getElse();
+ // Check for identical conditions:
+ //
+ // if (b) {
+ // foo1();
+ // } else if (b) {
+ // foo2();
+ // }
+ if (Stmt1 && Stmt2) {
+ const Expr *Cond1 = I->getCond();
+ const Stmt *Else = Stmt2;
+ while (const IfStmt *I2 = dyn_cast_or_null<IfStmt>(Else)) {
+ const Expr *Cond2 = I2->getCond();
+ if (isIdenticalStmt(AC->getASTContext(), Cond1, Cond2, false)) {
+ SourceRange Sr = Cond1->getSourceRange();
+ PathDiagnosticLocation ELoc(Cond2, BR.getSourceManager(), AC);
+ BR.EmitBasicReport(AC->getDecl(), Checker, "Identical conditions",
+ categories::LogicError,
+ "expression is identical to previous condition",
+ ELoc, Sr);
+ }
+ Else = I2->getElse();
+ }
+ }
+
if (!Stmt1 || !Stmt2)
return true;
Modified: cfe/trunk/test/Analysis/identical-expressions.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Analysis/identical-expressions.cpp?rev=203585&r1=203584&r2=203585&view=diff
==============================================================================
--- cfe/trunk/test/Analysis/identical-expressions.cpp (original)
+++ cfe/trunk/test/Analysis/identical-expressions.cpp Tue Mar 11 11:52:29 2014
@@ -1406,3 +1406,108 @@ void test_identical_logical9(int x, int
;
}
#pragma clang diagnostic pop
+
+void test_warn_chained_if_stmts_1(int x) {
+ if (x == 1)
+ ;
+ else if (x == 1) // expected-warning {{expression is identical to previous condition}}
+ ;
+}
+
+void test_warn_chained_if_stmts_2(int x) {
+ if (x == 1)
+ ;
+ else if (x == 1) // expected-warning {{expression is identical to previous condition}}
+ ;
+ else if (x == 1) // expected-warning {{expression is identical to previous condition}}
+ ;
+}
+
+void test_warn_chained_if_stmts_3(int x) {
+ if (x == 1)
+ ;
+ else if (x == 2)
+ ;
+ else if (x == 1) // expected-warning {{expression is identical to previous condition}}
+ ;
+}
+
+void test_warn_chained_if_stmts_4(int x) {
+ if (x == 1)
+ ;
+ else if (func())
+ ;
+ else if (x == 1) // expected-warning {{expression is identical to previous condition}}
+ ;
+}
+
+void test_warn_chained_if_stmts_5(int x) {
+ if (x & 1)
+ ;
+ else if (x & 1) // expected-warning {{expression is identical to previous condition}}
+ ;
+}
+
+void test_warn_chained_if_stmts_6(int x) {
+ if (x == 1)
+ ;
+ else if (x == 2)
+ ;
+ else if (x == 2) // expected-warning {{expression is identical to previous condition}}
+ ;
+ else if (x == 3)
+ ;
+}
+
+void test_warn_chained_if_stmts_7(int x) {
+ if (x == 1)
+ ;
+ else if (x == 2)
+ ;
+ else if (x == 3)
+ ;
+ else if (x == 2) // expected-warning {{expression is identical to previous condition}}
+ ;
+ else if (x == 5)
+ ;
+}
+
+void test_warn_chained_if_stmts_8(int x) {
+ if (x == 1)
+ ;
+ else if (x == 2)
+ ;
+ else if (x == 3)
+ ;
+ else if (x == 2) // expected-warning {{expression is identical to previous condition}}
+ ;
+ else if (x == 5)
+ ;
+ else if (x == 3) // expected-warning {{expression is identical to previous condition}}
+ ;
+ else if (x == 7)
+ ;
+}
+
+void test_nowarn_chained_if_stmts_1(int x) {
+ if (func())
+ ;
+ else if (func()) // no-warning
+ ;
+}
+
+void test_nowarn_chained_if_stmts_2(int x) {
+ if (func())
+ ;
+ else if (x == 1)
+ ;
+ else if (func()) // no-warning
+ ;
+}
+
+void test_nowarn_chained_if_stmts_3(int x) {
+ if (x++)
+ ;
+ else if (x++) // no-warning
+ ;
+}
More information about the cfe-commits
mailing list