Fix issue 8722: Avoid duplicate messages due for followVar (#1367)

This commit is contained in:
Paul Fultz II 2018-09-05 23:55:36 -05:00 committed by Daniel Marjamäki
parent ee104303b7
commit 2da958efb5
3 changed files with 64 additions and 6 deletions

View File

@ -578,11 +578,13 @@ void CheckCondition::multiCondition2()
if (firstCondition->str() == "&&") { if (firstCondition->str() == "&&") {
tokens1.push(firstCondition->astOperand1()); tokens1.push(firstCondition->astOperand1());
tokens1.push(firstCondition->astOperand2()); tokens1.push(firstCondition->astOperand2());
} else if (isOppositeCond(false, mTokenizer->isCPP(), firstCondition, cond2, mSettings->library, true, &errorPath)) { } else if (!firstCondition->hasKnownValue()) {
if (!isAliased(vars)) if(isOppositeCond(false, mTokenizer->isCPP(), firstCondition, cond2, mSettings->library, true, &errorPath)) {
oppositeInnerConditionError(firstCondition, cond2, errorPath); if (!isAliased(vars))
} else if (isSameExpression(mTokenizer->isCPP(), true, firstCondition, cond2, mSettings->library, true, &errorPath)) { oppositeInnerConditionError(firstCondition, cond2, errorPath);
identicalInnerConditionError(firstCondition, cond2, errorPath); } else if (isSameExpression(mTokenizer->isCPP(), true, firstCondition, cond2, mSettings->library, true, &errorPath)) {
identicalInnerConditionError(firstCondition, cond2, errorPath);
}
} }
} }
} else { } else {
@ -596,7 +598,8 @@ void CheckCondition::multiCondition2()
if (secondCondition->str() == "||" || secondCondition->str() == "&&") { if (secondCondition->str() == "||" || secondCondition->str() == "&&") {
tokens2.push(secondCondition->astOperand1()); tokens2.push(secondCondition->astOperand1());
tokens2.push(secondCondition->astOperand2()); tokens2.push(secondCondition->astOperand2());
} else if (isSameExpression(mTokenizer->isCPP(), true, cond1, secondCondition, mSettings->library, true, &errorPath)) { } else if ((!cond1->hasKnownValue() || !secondCondition->hasKnownValue()) &&
isSameExpression(mTokenizer->isCPP(), true, cond1, secondCondition, mSettings->library, true, &errorPath)) {
if (!isAliased(vars)) if (!isAliased(vars))
identicalConditionAfterEarlyExitError(cond1, secondCondition, errorPath); identicalConditionAfterEarlyExitError(cond1, secondCondition, errorPath);
} }

View File

@ -104,6 +104,7 @@ private:
TEST_CASE(clarifyCondition8); TEST_CASE(clarifyCondition8);
TEST_CASE(alwaysTrue); TEST_CASE(alwaysTrue);
TEST_CASE(multiConditionAlwaysTrue);
TEST_CASE(checkInvalidTestForOverflow); TEST_CASE(checkInvalidTestForOverflow);
TEST_CASE(checkConditionIsAlwaysTrueOrFalseInsideIfWhile); TEST_CASE(checkConditionIsAlwaysTrueOrFalseInsideIfWhile);
@ -2518,6 +2519,31 @@ private:
ASSERT_EQUALS("[test.cpp:4]: (style) Condition '!b' is always true\n", errout.str()); ASSERT_EQUALS("[test.cpp:4]: (style) Condition '!b' is always true\n", errout.str());
} }
void multiConditionAlwaysTrue() {
check("void f() {\n"
" int val = 0;\n"
" if (val < 0) continue;\n"
" if (val > 0) {}\n"
"}\n");
ASSERT_EQUALS("", errout.str());
check("void f() {\n"
" int val = 0;\n"
" if (val < 0) {\n"
" if (val > 0) {}\n"
" }\n"
"}\n");
ASSERT_EQUALS("", errout.str());
check("void f() {\n"
" int val = 0;\n"
" if (val < 0) {\n"
" if (val < 0) {}\n"
" }\n"
"}\n");
ASSERT_EQUALS("", errout.str());
}
void checkInvalidTestForOverflow() { void checkInvalidTestForOverflow() {
check("void f(char *p, unsigned int x) {\n" check("void f(char *p, unsigned int x) {\n"
" assert((p + x) < p);\n" " assert((p + x) < p);\n"

View File

@ -141,6 +141,7 @@ private:
TEST_CASE(duplicateVarExpressionUnique); TEST_CASE(duplicateVarExpressionUnique);
TEST_CASE(duplicateVarExpressionAssign); TEST_CASE(duplicateVarExpressionAssign);
TEST_CASE(duplicateVarExpressionCrash); TEST_CASE(duplicateVarExpressionCrash);
TEST_CASE(multiConditionSameExpression);
TEST_CASE(checkSignOfUnsignedVariable); TEST_CASE(checkSignOfUnsignedVariable);
TEST_CASE(checkSignOfPointer); TEST_CASE(checkSignOfPointer);
@ -4596,6 +4597,34 @@ private:
} }
void multiConditionSameExpression() {
check("void f() {\n"
" int val = 0;\n"
" if (val < 0) continue;\n"
" if ((val > 0)) {}\n"
"}\n");
ASSERT_EQUALS("[test.cpp:2] -> [test.cpp:3]: (style) The expression 'val < 0' is always false.\n"
"[test.cpp:2] -> [test.cpp:4]: (style) The expression 'val > 0' is always false.\n", errout.str());
check("void f() {\n"
" int val = 0;\n"
" if (val < 0) {\n"
" if ((val > 0)) {}\n"
" }\n"
"}\n");
ASSERT_EQUALS("[test.cpp:2] -> [test.cpp:3]: (style) The expression 'val < 0' is always false.\n"
"[test.cpp:2] -> [test.cpp:4]: (style) The expression 'val > 0' is always false.\n", errout.str());
check("void f() {\n"
" int val = 0;\n"
" if (val < 0) {\n"
" if ((val < 0)) {}\n"
" }\n"
"}\n");
ASSERT_EQUALS("[test.cpp:2] -> [test.cpp:3]: (style) The expression 'val < 0' is always false.\n"
"[test.cpp:2] -> [test.cpp:4]: (style) The expression 'val < 0' is always false.\n", errout.str());
}
void checkSignOfUnsignedVariable() { void checkSignOfUnsignedVariable() {
check( check(
"void foo() {\n" "void foo() {\n"