Fix #9997 False negative: variable is not used (#4104)

This commit is contained in:
chrchr-github 2022-06-07 21:20:33 +02:00 committed by GitHub
parent 1d677c57a8
commit 69834d537b
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
5 changed files with 29 additions and 8 deletions

View File

@ -1195,7 +1195,7 @@ void CheckUnusedVar::checkFunctionVariableUsage()
if (isIncrementOrDecrement && tok->astParent() && precedes(tok, tok->astOperand1())) if (isIncrementOrDecrement && tok->astParent() && precedes(tok, tok->astOperand1()))
continue; continue;
if (tok->str() == "=" && isRaiiClass(tok->valueType(), mTokenizer->isCPP(), false)) if (tok->str() == "=" && !(tok->valueType() && tok->valueType()->pointer) && isRaiiClass(tok->valueType(), mTokenizer->isCPP(), false))
continue; continue;
const bool isPointer = tok->valueType() && tok->valueType()->pointer; const bool isPointer = tok->valueType() && tok->valueType()->pointer;

View File

@ -381,7 +381,6 @@ static void fillProgramMemoryFromAssignments(ProgramMemory& pm, const Token* tok
++indentlevel; ++indentlevel;
continue; continue;
} }
tok2 = cond->astParent()->previous();
} else if (conditionIsTrue(cond, state)) { } else if (conditionIsTrue(cond, state)) {
if (inElse) if (inElse)
tok2 = tok2->link()->tokAt(-2); tok2 = tok2->link()->tokAt(-2);

View File

@ -144,7 +144,7 @@ private:
const Token * const tok = (offset < 0) const Token * const tok = (offset < 0)
? tokenizer.list.back()->tokAt(1+offset) ? tokenizer.list.back()->tokAt(1+offset)
: tokenizer.tokens()->tokAt(offset); : tokenizer.tokens()->tokAt(offset);
return (::isReturnScope)(tok); return (isReturnScope)(tok);
} }
void isReturnScopeTest() { void isReturnScopeTest() {
@ -176,7 +176,7 @@ private:
tokenizer.simplifyTokens1(""); tokenizer.simplifyTokens1("");
const Token * const tok1 = Token::findsimplematch(tokenizer.tokens(), tokStr1, strlen(tokStr1)); const Token * const tok1 = Token::findsimplematch(tokenizer.tokens(), tokStr1, strlen(tokStr1));
const Token * const tok2 = Token::findsimplematch(tok1->next(), tokStr2, strlen(tokStr2)); const Token * const tok2 = Token::findsimplematch(tok1->next(), tokStr2, strlen(tokStr2));
return (::isSameExpression)(false, false, tok1, tok2, library, false, true, nullptr); return (isSameExpression)(false, false, tok1, tok2, library, false, true, nullptr);
} }
void isSameExpressionTest() { void isSameExpressionTest() {
@ -214,7 +214,7 @@ private:
ASSERT_LOC(tokenizer.tokenize(istr, "test.cpp"), file, line); ASSERT_LOC(tokenizer.tokenize(istr, "test.cpp"), file, line);
const Token * const tok1 = Token::findsimplematch(tokenizer.tokens(), startPattern, strlen(startPattern)); const Token * const tok1 = Token::findsimplematch(tokenizer.tokens(), startPattern, strlen(startPattern));
const Token * const tok2 = Token::findsimplematch(tokenizer.tokens(), endPattern, strlen(endPattern)); const Token * const tok2 = Token::findsimplematch(tokenizer.tokens(), endPattern, strlen(endPattern));
return (::isVariableChanged)(tok1, tok2, 1, false, &settings, true); return (isVariableChanged)(tok1, tok2, 1, false, &settings, true);
} }
void isVariableChangedTest() { void isVariableChangedTest() {
@ -236,7 +236,7 @@ private:
std::istringstream istr(code); std::istringstream istr(code);
ASSERT_LOC(tokenizer.tokenize(istr, "test.cpp"), file, line); ASSERT_LOC(tokenizer.tokenize(istr, "test.cpp"), file, line);
const Token * const argtok = Token::findmatch(tokenizer.tokens(), pattern); const Token * const argtok = Token::findmatch(tokenizer.tokens(), pattern);
return (::isVariableChangedByFunctionCall)(argtok, 0, &settings, inconclusive); return (isVariableChangedByFunctionCall)(argtok, 0, &settings, inconclusive);
} }
void isVariableChangedByFunctionCallTest() { void isVariableChangedByFunctionCallTest() {

View File

@ -1281,8 +1281,7 @@ private:
const Token *tok = Token::findsimplematch(tokenizer.tokens(), "sizeof ("); const Token *tok = Token::findsimplematch(tokenizer.tokens(), "sizeof (");
ASSERT(!!tok); ASSERT(!!tok);
tok = tok->next(); tok = tok->next();
// TODO ASSERT(tok->hasKnownIntValue()); TODO_ASSERT_EQUALS(true, false, tok->hasKnownIntValue() && tok->getKnownIntValue() == 10);
// TODO ASSERT_EQUALS(10, tok->getKnownIntValue());
} }
void valueType1() { void valueType1() {

View File

@ -131,6 +131,7 @@ private:
TEST_CASE(localvar61); // #9407 TEST_CASE(localvar61); // #9407
TEST_CASE(localvar62); // #10824 TEST_CASE(localvar62); // #10824
TEST_CASE(localvar63); // #6928 TEST_CASE(localvar63); // #6928
TEST_CASE(localvar64); // #9997
TEST_CASE(localvarloops); // loops TEST_CASE(localvarloops); // loops
TEST_CASE(localvaralias1); TEST_CASE(localvaralias1);
TEST_CASE(localvaralias2); // ticket #1637 TEST_CASE(localvaralias2); // ticket #1637
@ -3485,6 +3486,28 @@ private:
ASSERT_EQUALS("[test.cpp:2]: (style) Variable 'x' is assigned a value that is never used.\n", errout.str()); ASSERT_EQUALS("[test.cpp:2]: (style) Variable 'x' is assigned a value that is never used.\n", errout.str());
} }
void localvar64() { // #9997
functionVariableUsage("class S {\n"
" ~S();\n"
" S* f();\n"
" S* g(int);\n"
"};\n"
"void h(S* s, bool b) {\n"
" S* p = nullptr;\n"
" S* q = nullptr;\n"
" if (b) {\n"
" p = s;\n"
" q = s->f()->g(-2);\n"
" }\n"
" else\n"
" q = s;\n"
"}\n");
ASSERT_EQUALS("[test.cpp:10]: (style) Variable 'p' is assigned a value that is never used.\n"
"[test.cpp:11]: (style) Variable 'q' is assigned a value that is never used.\n"
"[test.cpp:14]: (style) Variable 'q' is assigned a value that is never used.\n",
errout.str());
}
void localvarloops() { void localvarloops() {
// loops // loops
functionVariableUsage("void fun(int c) {\n" functionVariableUsage("void fun(int c) {\n"