Fix issue 8234: false negative: (warning) Opposite inner 'if' condition leads to a dead code block. (#2781)
This commit is contained in:
parent
136ac2c643
commit
a4f43fc2ad
|
@ -956,6 +956,17 @@ bool isOppositeCond(bool isNot, bool cpp, const Token * const cond1, const Token
|
|||
if (!cond1 || !cond2)
|
||||
return false;
|
||||
|
||||
if (cond1->str() == "&&" && cond2->str() == "&&") {
|
||||
for(const Token* tok1:{cond1->astOperand1(), cond1->astOperand2()}) {
|
||||
for(const Token* tok2:{cond2->astOperand1(), cond2->astOperand2()}) {
|
||||
if (isSameExpression(cpp, true, tok1, tok2, library, pure, followVar, errors)) {
|
||||
if (isOppositeCond(isNot, cpp, tok1->astSibling(), tok2->astSibling(), library, pure, followVar, errors))
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (cond1->str() == "!") {
|
||||
if (cond2->str() == "!=") {
|
||||
if (cond2->astOperand1() && cond2->astOperand1()->str() == "0")
|
||||
|
|
|
@ -701,8 +701,10 @@ void CheckCondition::multiCondition2()
|
|||
if (!firstCondition)
|
||||
return ChildrenToVisit::none;
|
||||
if (firstCondition->str() == "&&") {
|
||||
if (!isOppositeCond(false, mTokenizer->isCPP(), firstCondition, cond2, mSettings->library, true, true))
|
||||
return ChildrenToVisit::op1_and_op2;
|
||||
} else if (!firstCondition->hasKnownIntValue()) {
|
||||
}
|
||||
if (!firstCondition->hasKnownIntValue()) {
|
||||
if (!isReturnVar && isOppositeCond(false, mTokenizer->isCPP(), firstCondition, cond2, mSettings->library, true, true, &errorPath)) {
|
||||
if (!isAliased(vars))
|
||||
oppositeInnerConditionError(firstCondition, cond2, errorPath);
|
||||
|
|
20
lib/token.h
20
lib/token.h
|
@ -1263,6 +1263,26 @@ public:
|
|||
const Token * astParent() const {
|
||||
return mImpl->mAstParent;
|
||||
}
|
||||
Token * astSibling() {
|
||||
if (!astParent())
|
||||
return nullptr;
|
||||
if (this == astParent()->astOperand1())
|
||||
return astParent()->astOperand2();
|
||||
else if (this == astParent()->astOperand2())
|
||||
return astParent()->astOperand1();
|
||||
return nullptr;
|
||||
|
||||
}
|
||||
const Token * astSibling() const {
|
||||
if (!astParent())
|
||||
return nullptr;
|
||||
if (this == astParent()->astOperand1())
|
||||
return astParent()->astOperand2();
|
||||
else if (this == astParent()->astOperand2())
|
||||
return astParent()->astOperand1();
|
||||
return nullptr;
|
||||
|
||||
}
|
||||
Token *astTop() {
|
||||
Token *ret = this;
|
||||
while (ret->mImpl->mAstParent)
|
||||
|
|
|
@ -2310,6 +2310,12 @@ private:
|
|||
" }"
|
||||
"}");
|
||||
ASSERT_EQUALS("[test.cpp:2] -> [test.cpp:3]: (warning) Opposite inner 'if' condition leads to a dead code block.\n", errout.str());
|
||||
|
||||
check("void f(bool x, const int a, const int b) {\n"
|
||||
" if(x && a < b)\n"
|
||||
" if( x && a > b){}\n"
|
||||
"}\n");
|
||||
ASSERT_EQUALS("[test.cpp:2] -> [test.cpp:3]: (warning) Opposite inner 'if' condition leads to a dead code block.\n", errout.str());
|
||||
}
|
||||
|
||||
void oppositeInnerConditionEmpty() {
|
||||
|
|
|
@ -5310,7 +5310,7 @@ private:
|
|||
check("void f(int* x, bool b) {\n"
|
||||
" if ((!x && b) || (x != 0 && b)) {}\n"
|
||||
"}\n");
|
||||
ASSERT_EQUALS("", errout.str());
|
||||
ASSERT_EQUALS("[test.cpp:2]: (style) Opposite expression on both sides of '||'.\n", errout.str());
|
||||
}
|
||||
|
||||
void oppositeExpression() {
|
||||
|
|
Loading…
Reference in New Issue