Improve 'opposite inner condition' check

This commit is contained in:
Daniel Marjamäki 2017-09-22 14:01:20 +02:00
parent 5e618418d5
commit 5993c40d5b
2 changed files with 45 additions and 14 deletions

View File

@ -276,21 +276,45 @@ bool isOppositeCond(bool isNot, bool cpp, const Token * const cond1, const Token
}
if (!isNot && comp2.empty()) {
if (isSameExpression(cpp, true, cond1->astOperand1(), cond2->astOperand1(), library, pure) &&
cond1->astOperand2() && cond1->astOperand2()->hasKnownIntValue() &&
cond2->astOperand2() && cond2->astOperand2()->hasKnownIntValue()) {
const ValueFlow::Value &rhsValue1 = cond1->astOperand2()->values().front();
const ValueFlow::Value &rhsValue2 = cond2->astOperand2()->values().front();
bool secondAlwaysFalse = false;
if (comp1 == "<" || comp1 == "<=")
secondAlwaysFalse = Token::Match(cond2, "==|>|>=") && (rhsValue1.intvalue < rhsValue2.intvalue);
else if (comp1 == ">=" || comp1 == ">")
secondAlwaysFalse = Token::Match(cond2, "==|<|<=") && (rhsValue1.intvalue > rhsValue2.intvalue);
if (secondAlwaysFalse)
return true;
const Token *expr1 = nullptr, *value1 = nullptr, *expr2 = nullptr, *value2 = nullptr;
std::string op1 = cond1->str(), op2 = cond2->str();
if (cond1->astOperand2()->hasKnownIntValue()) {
expr1 = cond1->astOperand1();
value1 = cond1->astOperand2();
} else if (cond1->astOperand1()->hasKnownIntValue()) {
expr1 = cond1->astOperand2();
value1 = cond1->astOperand1();
if (op1[0] == '>')
op1[0] = '<';
else if (op1[0] == '<')
op1[0] = '>';
}
if (cond2->astOperand2()->hasKnownIntValue()) {
expr2 = cond2->astOperand1();
value2 = cond2->astOperand2();
} else if (cond2->astOperand1()->hasKnownIntValue()) {
expr2 = cond2->astOperand2();
value2 = cond2->astOperand1();
if (op2[0] == '>')
op2[0] = '<';
else if (op2[0] == '<')
op2[0] = '>';
}
if (!expr1 || !value1 || !expr2 || !value2) {
return false;
}
if (!isSameExpression(cpp, true, expr1, expr2, library, pure))
return false;
const ValueFlow::Value &rhsValue1 = value1->values().front();
const ValueFlow::Value &rhsValue2 = value2->values().front();
if (op1 == "<" || op1 == "<=")
return (op2 == "==" || op2 == ">" || op2 == ">=") && (rhsValue1.intvalue < rhsValue2.intvalue);
else if (op1 == ">=" || op1 == ">")
return (op2 == "==" || op2 == "<" || op2 == "<=") && (rhsValue1.intvalue > rhsValue2.intvalue);
return false;
}
// is condition opposite?

View File

@ -1764,6 +1764,13 @@ private:
"[test.cpp:15] -> [test.cpp:16]: (warning) Opposite inner 'if' condition leads to a dead code block.\n"
"[test.cpp:19] -> [test.cpp:20]: (warning) Opposite inner 'if' condition leads to a dead code block.\n"
, errout.str());
check("void f(int x) {\n"
" if (x < 4) {\n"
" if (10 < x) {}\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 oppositeInnerConditionAnd() {