Hi Jordan, Thanks for reviewing this.
On Wed, 2014-03-05 at 14:38 -0800, Jordan Rose wrote: > I'm sorry, I managed to miss this one. Please feel free to include me > in the To or CC fields when you have analyzer patches. > I'm glad to get this check! It definitely seems useful for copy-paste > checking. Thanks for doing the timing checks in advance. > > Comments: > > + if (Stmt1 && Stmt2) { > + const Expr *Cond1 = I->getCond(); > + const Stmt *Else = Stmt2; > + while (const IfStmt *I2 = dyn_cast<IfStmt>(Else)) { > > If you use dyn_cast_or_null here, then you can drop the check for a > missing 'else' at the end of the loop (and at the beginning of the loop > too, though that's less interesting). I've kept the check at the beginning, mostly because I think it makes the code more readable. > + PathDiagnosticLocation ELoc = > PathDiagnosticLocation::createBegin(Cond2, > + BR.getSourceManager(), AC); > > Please use the regular Stmt-based constructor for > PathDiagnosticLocation. We want to consider the whole condition to be > the location, not just the beginning. > > + BR.EmitBasicReport(AC->getDecl(), Checker, > + "Identical conditions", > + categories::LogicError, > + "identical condition as a previous one", ELoc, > Sr); > > This isn't quite valid English: two things can "be identical", and one > thing can "be identical to" another thing, but one thing can't be > "identical as" another thing. The "one" also makes me > uncomfortable...it feels weird in a compiler tool. How about > "expression is identical to previous condition"? (I'm cheating by using > "expression" to mean "condition" in this case, but it sounds better to > not repeat "condition".) > > As far as test cases go, please include some cases where > - the duplicated condition is not last > - the duplicated condition is not first > - there are multiple pairs of duplicated conditions in the chain Valid points as usual. Attached is an updated version of the patch. Btw, who should I poke to get the list of potential checkers updated? The page still lists different.IdenticalExprBinOp, different.IdenticalStmtThenElse and different.CondOpIdenticalReturn as without progress. Cheers, Daniel Fahlgren
Index: lib/StaticAnalyzer/Checkers/IdenticalExprChecker.cpp =================================================================== --- lib/StaticAnalyzer/Checkers/IdenticalExprChecker.cpp (revision 203158) +++ lib/StaticAnalyzer/Checkers/IdenticalExprChecker.cpp (working copy) @@ -108,6 +108,30 @@ 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; Index: test/Analysis/identical-expressions.cpp =================================================================== --- test/Analysis/identical-expressions.cpp (revision 203158) +++ test/Analysis/identical-expressions.cpp (working copy) @@ -1406,3 +1406,108 @@ ; } #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 + ; +}
_______________________________________________ cfe-commits mailing list cfe-commits@cs.uiuc.edu http://lists.cs.uiuc.edu/mailman/listinfo/cfe-commits