Improve checking of size condition against empty to avoid FPs (#1213)
* Improve checking of size condition against empty to avoid FPs * Add const and todo for reverse conditions
This commit is contained in:
parent
1e7c1841f7
commit
c520735009
|
@ -248,6 +248,24 @@ bool isDifferentKnownValues(const Token * const tok1, const Token * const tok2)
|
|||
return tok1->hasKnownValue() && tok2->hasKnownValue() && tok1->values() != tok2->values();
|
||||
}
|
||||
|
||||
static bool isZeroBoundCond(const Token * const cond)
|
||||
{
|
||||
if(cond == nullptr)
|
||||
return false;
|
||||
// Assume unsigned
|
||||
// TODO: Handle reverse conditions
|
||||
const bool isZero = cond->astOperand2()->getValue(0);
|
||||
if (cond->str() == "==" || cond->str() == ">=")
|
||||
return isZero;
|
||||
if (cond->str() == "<=")
|
||||
return true;
|
||||
if (cond->str() == "<")
|
||||
return !isZero;
|
||||
if (cond->str() == ">")
|
||||
return false;
|
||||
return false;
|
||||
}
|
||||
|
||||
bool isOppositeCond(bool isNot, bool cpp, const Token * const cond1, const Token * const cond2, const Library& library, bool pure)
|
||||
{
|
||||
if (!cond1 || !cond2)
|
||||
|
@ -273,16 +291,17 @@ bool isOppositeCond(bool isNot, bool cpp, const Token * const cond1, const Token
|
|||
if (isSameExpression(cpp, true, cond1->astOperand2(), cond2->astOperand2(), library, pure))
|
||||
return isDifferentKnownValues(cond1->astOperand1(), cond2->astOperand1());
|
||||
}
|
||||
// TODO: Handle reverse conditions
|
||||
if (Library::isContainerYield(cond1, Library::Container::EMPTY, "empty") &&
|
||||
Library::isContainerYield(cond2->astOperand1(), Library::Container::SIZE, "size") &&
|
||||
cond1->astOperand1()->astOperand1()->varId() == cond2->astOperand1()->astOperand1()->astOperand1()->varId()) {
|
||||
return !(cond2->str() == "==" && cond2->astOperand2()->getValue(0));
|
||||
return !isZeroBoundCond(cond2);
|
||||
}
|
||||
|
||||
if (Library::isContainerYield(cond2, Library::Container::EMPTY, "empty") &&
|
||||
Library::isContainerYield(cond1->astOperand1(), Library::Container::SIZE, "size") &&
|
||||
cond2->astOperand1()->astOperand1()->varId() == cond1->astOperand1()->astOperand1()->astOperand1()->varId()) {
|
||||
return !(cond1->str() == "==" && cond1->astOperand2()->getValue(0));
|
||||
return !isZeroBoundCond(cond1);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -1851,6 +1851,12 @@ private:
|
|||
check("void f1(const std::string &s) { if(s.size() > 42) if(s.empty()) {}} ");
|
||||
ASSERT_EQUALS("[test.cpp:1] -> [test.cpp:1]: (warning) Opposite inner 'if' condition leads to a dead code block.\n", errout.str());
|
||||
|
||||
check("void f1(const std::string &s) { if(s.size() > 0) if(s.empty()) {}} ");
|
||||
ASSERT_EQUALS("[test.cpp:1] -> [test.cpp:1]: (warning) Opposite inner 'if' condition leads to a dead code block.\n", errout.str());
|
||||
|
||||
check("void f1(const std::string &s) { if(s.size() < 0) if(s.empty()) {}} ");
|
||||
ASSERT_EQUALS("[test.cpp:1] -> [test.cpp:1]: (warning) Opposite inner 'if' condition leads to a dead code block.\n", errout.str());
|
||||
|
||||
check("void f1(const std::string &s) { if(s.empty()) if(s.size() > 42) {}} ");
|
||||
ASSERT_EQUALS("[test.cpp:1] -> [test.cpp:1]: (warning) Opposite inner 'if' condition leads to a dead code block.\n", errout.str());
|
||||
|
||||
|
@ -1877,6 +1883,26 @@ private:
|
|||
|
||||
check("void f1(const std::string v[10]) { if(v[0].size() > 42) if(v[1].empty()) {}} ");
|
||||
ASSERT_EQUALS("", errout.str());
|
||||
|
||||
check("void f1(const std::string &s) { if(s.size() <= 1) if(s.empty()) {}} ");
|
||||
ASSERT_EQUALS("", errout.str());
|
||||
|
||||
check("void f1(const std::string &s) { if(s.size() <= 2) if(s.empty()) {}} ");
|
||||
ASSERT_EQUALS("", errout.str());
|
||||
|
||||
check("void f1(const std::string &s) { if(s.size() < 2) if(s.empty()) {}} ");
|
||||
ASSERT_EQUALS("", errout.str());
|
||||
|
||||
check("void f1(const std::string &s) { if(s.size() >= 0) if(s.empty()) {}} ");
|
||||
ASSERT_EQUALS("", errout.str());
|
||||
|
||||
// TODO: These are identical condition since size cannot be negative
|
||||
check("void f1(const std::string &s) { if(s.size() <= 0) if(s.empty()) {}} ");
|
||||
ASSERT_EQUALS("", errout.str());
|
||||
|
||||
// TODO: These are identical condition since size cannot be negative
|
||||
check("void f1(const std::string &s) { if(s.size() < 1) if(s.empty()) {}} ");
|
||||
ASSERT_EQUALS("", errout.str());
|
||||
}
|
||||
|
||||
void identicalInnerCondition() {
|
||||
|
|
Loading…
Reference in New Issue