Add a check for identical inner conditions (#1156)

This commit is contained in:
Paul Fultz II 2018-04-08 01:13:44 -05:00 committed by Daniel Marjamäki
parent 541e255159
commit b85dda77da
3 changed files with 27 additions and 0 deletions

View File

@ -585,6 +585,8 @@ void CheckCondition::multiCondition2()
} else if (isOppositeCond(false, _tokenizer->isCPP(), firstCondition, cond2, _settings->library, true)) {
if (!isAliased(vars))
oppositeInnerConditionError(firstCondition, cond2);
} else if(isSameExpression(_tokenizer->isCPP(), true, firstCondition, cond2, _settings->library, true)) {
identicalInnerConditionError(firstCondition, cond2);
}
}
} else {
@ -693,6 +695,18 @@ void CheckCondition::oppositeInnerConditionError(const Token *tok1, const Token*
reportError(errorPath, Severity::warning, "oppositeInnerCondition", msg, CWE398, false);
}
void CheckCondition::identicalInnerConditionError(const Token *tok1, const Token* tok2)
{
const std::string s1(tok1 ? tok1->expressionString() : "x");
const std::string s2(tok2 ? tok2->expressionString() : "x");
ErrorPath errorPath;
errorPath.push_back(ErrorPathItem(tok1, "outer condition: " + s1));
errorPath.push_back(ErrorPathItem(tok2, "identical inner condition: " + s2));
const std::string msg("Identical inner 'if' condition is always true.\n"
"Identical inner 'if' condition is always true (outer condition is '" + s1 + "' and inner condition is '" + s2 + "').");
reportError(errorPath, Severity::warning, "identicalInnerCondition", msg, CWE398, false);
}
void CheckCondition::identicalConditionAfterEarlyExitError(const Token *cond1, const Token* cond2)
{
const std::string cond(cond1 ? cond1->expressionString() : "x");

View File

@ -133,6 +133,8 @@ private:
void oppositeInnerConditionError(const Token *tok1, const Token* tok2);
void identicalInnerConditionError(const Token *tok1, const Token* tok2);
void identicalConditionAfterEarlyExitError(const Token *cond1, const Token *cond2);
void incorrectLogicOperatorError(const Token *tok, const std::string &condition, bool always, bool inconclusive);
@ -156,6 +158,7 @@ private:
c.multiConditionError(nullptr,1);
c.mismatchingBitAndError(nullptr, 0xf0, nullptr, 1);
c.oppositeInnerConditionError(nullptr, nullptr);
c.identicalInnerConditionError(nullptr, nullptr);
c.identicalConditionAfterEarlyExitError(nullptr, nullptr);
c.incorrectLogicOperatorError(nullptr, "foo > 3 && foo < 4", true, false);
c.redundantConditionError(nullptr, "If x > 11 the condition x > 10 is always true.", false);

View File

@ -87,6 +87,8 @@ private:
TEST_CASE(oppositeInnerConditionAnd);
TEST_CASE(oppositeInnerConditionEmpty);
TEST_CASE(identicalInnerCondition);
TEST_CASE(identicalConditionAfterEarlyExit);
TEST_CASE(clarifyCondition1); // if (a = b() < 0)
@ -1876,6 +1878,14 @@ private:
check("void f1(const std::string v[10]) { if(v[0].size() > 42) if(v[1].empty()) {}} ");
ASSERT_EQUALS("", errout.str());
}
void identicalInnerCondition() {
check("void f1(int a, int b) { if(a==b) if(a==b) {}}");
ASSERT_EQUALS("[test.cpp:1] -> [test.cpp:1]: (warning) Identical inner 'if' condition is always true.\n", errout.str());
check("void f2(int a, int b) { if(a!=b) if(a!=b) {}}");
ASSERT_EQUALS("[test.cpp:1] -> [test.cpp:1]: (warning) Identical inner 'if' condition is always true.\n", errout.str());
}
void identicalConditionAfterEarlyExit() {
check("void f(int x) {\n"