Skip to content

Commit a4f43fc

Browse files
authored
Fix issue 8234: false negative: (warning) Opposite inner 'if' condition leads to a dead code block. (cppcheck-opensource#2781)
1 parent 136ac2c commit a4f43fc

5 files changed

Lines changed: 42 additions & 3 deletions

File tree

lib/astutils.cpp

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -956,6 +956,17 @@ bool isOppositeCond(bool isNot, bool cpp, const Token * const cond1, const Token
956956
if (!cond1 || !cond2)
957957
return false;
958958

959+
if (cond1->str() == "&&" && cond2->str() == "&&") {
960+
for(const Token* tok1:{cond1->astOperand1(), cond1->astOperand2()}) {
961+
for(const Token* tok2:{cond2->astOperand1(), cond2->astOperand2()}) {
962+
if (isSameExpression(cpp, true, tok1, tok2, library, pure, followVar, errors)) {
963+
if (isOppositeCond(isNot, cpp, tok1->astSibling(), tok2->astSibling(), library, pure, followVar, errors))
964+
return true;
965+
}
966+
}
967+
}
968+
}
969+
959970
if (cond1->str() == "!") {
960971
if (cond2->str() == "!=") {
961972
if (cond2->astOperand1() && cond2->astOperand1()->str() == "0")

lib/checkcondition.cpp

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -701,8 +701,10 @@ void CheckCondition::multiCondition2()
701701
if (!firstCondition)
702702
return ChildrenToVisit::none;
703703
if (firstCondition->str() == "&&") {
704-
return ChildrenToVisit::op1_and_op2;
705-
} else if (!firstCondition->hasKnownIntValue()) {
704+
if (!isOppositeCond(false, mTokenizer->isCPP(), firstCondition, cond2, mSettings->library, true, true))
705+
return ChildrenToVisit::op1_and_op2;
706+
}
707+
if (!firstCondition->hasKnownIntValue()) {
706708
if (!isReturnVar && isOppositeCond(false, mTokenizer->isCPP(), firstCondition, cond2, mSettings->library, true, true, &errorPath)) {
707709
if (!isAliased(vars))
708710
oppositeInnerConditionError(firstCondition, cond2, errorPath);

lib/token.h

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1263,6 +1263,26 @@ class CPPCHECKLIB Token {
12631263
const Token * astParent() const {
12641264
return mImpl->mAstParent;
12651265
}
1266+
Token * astSibling() {
1267+
if (!astParent())
1268+
return nullptr;
1269+
if (this == astParent()->astOperand1())
1270+
return astParent()->astOperand2();
1271+
else if (this == astParent()->astOperand2())
1272+
return astParent()->astOperand1();
1273+
return nullptr;
1274+
1275+
}
1276+
const Token * astSibling() const {
1277+
if (!astParent())
1278+
return nullptr;
1279+
if (this == astParent()->astOperand1())
1280+
return astParent()->astOperand2();
1281+
else if (this == astParent()->astOperand2())
1282+
return astParent()->astOperand1();
1283+
return nullptr;
1284+
1285+
}
12661286
Token *astTop() {
12671287
Token *ret = this;
12681288
while (ret->mImpl->mAstParent)

test/testcondition.cpp

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2310,6 +2310,12 @@ class TestCondition : public TestFixture {
23102310
" }"
23112311
"}");
23122312
ASSERT_EQUALS("[test.cpp:2] -> [test.cpp:3]: (warning) Opposite inner 'if' condition leads to a dead code block.\n", errout.str());
2313+
2314+
check("void f(bool x, const int a, const int b) {\n"
2315+
" if(x && a < b)\n"
2316+
" if( x && a > b){}\n"
2317+
"}\n");
2318+
ASSERT_EQUALS("[test.cpp:2] -> [test.cpp:3]: (warning) Opposite inner 'if' condition leads to a dead code block.\n", errout.str());
23132319
}
23142320

23152321
void oppositeInnerConditionEmpty() {

test/testother.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5310,7 +5310,7 @@ class TestOther : public TestFixture {
53105310
check("void f(int* x, bool b) {\n"
53115311
" if ((!x && b) || (x != 0 && b)) {}\n"
53125312
"}\n");
5313-
ASSERT_EQUALS("", errout.str());
5313+
ASSERT_EQUALS("[test.cpp:2]: (style) Opposite expression on both sides of '||'.\n", errout.str());
53145314
}
53155315

53165316
void oppositeExpression() {

0 commit comments

Comments
 (0)