From 30e2a44a06a4bd61f9c607e0d7e2447e0dc488db Mon Sep 17 00:00:00 2001 From: Daniel Marjamaki Date: Mon, 10 Aug 2015 07:18:29 +0000 Subject: [PATCH] [Static Analyzer] Warn when inner and outer conditions are identical. The inner condition is always true. Reviewed in http://reviews.llvm.org/D10892. llvm-svn: 244435 --- .../Checkers/IdenticalExprChecker.cpp | 18 ++++++++++++ clang/test/Analysis/identical-expressions.cpp | 32 ++++++++++++++++++++++ 2 files changed, 50 insertions(+) diff --git a/clang/lib/StaticAnalyzer/Checkers/IdenticalExprChecker.cpp b/clang/lib/StaticAnalyzer/Checkers/IdenticalExprChecker.cpp index 58d0783..23fa2d1 100644 --- a/clang/lib/StaticAnalyzer/Checkers/IdenticalExprChecker.cpp +++ b/clang/lib/StaticAnalyzer/Checkers/IdenticalExprChecker.cpp @@ -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(Stmt1)) { + if (!CS->body_empty()) { + const IfStmt *InnerIf = dyn_cast(*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) { diff --git a/clang/test/Analysis/identical-expressions.cpp b/clang/test/Analysis/identical-expressions.cpp index 46dd562..138cd7c 100644 --- a/clang/test/Analysis/identical-expressions.cpp +++ b/clang/test/Analysis/identical-expressions.cpp @@ -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) + ; + } +} -- 2.7.4