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;
;
}
#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
+ ;
+}