[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
This commit is contained in:
Daniel Marjamaki 2015-08-10 07:18:29 +00:00
parent 001e2e4228
commit 30e2a44a06
2 changed files with 50 additions and 0 deletions

View File

@ -108,6 +108,24 @@ bool FindIdenticalExprVisitor::VisitIfStmt(const IfStmt *I) {
const Stmt *Stmt1 = I->getThen(); const Stmt *Stmt1 = I->getThen();
const Stmt *Stmt2 = I->getElse(); 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: // Check for identical conditions:
// //
// if (b) { // if (b) {

View File

@ -1530,3 +1530,35 @@ void test_nowarn_long() {
c = 0LL; 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)
;
}
}