Fix #10824 FN unreadVariable for pointer assignment when destructor exists (regression) (#3864)

* Fix #10824 FN unreadVariable for pointer assignment when destructor exists (regression)

* unused variable

* Issue warning for missing cfg

* Format
This commit is contained in:
chrchr-github 2022-03-02 11:11:44 +01:00 committed by GitHub
parent de728f472c
commit 9c50136571
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 46 additions and 15 deletions

View File

@ -972,13 +972,6 @@ void CheckUnusedVar::checkFunctionVariableUsage_iterateScopes(const Scope* const
} else if (varid1 && Token::Match(tok, "%varid% .", varid1)) {
variables.read(varid1, tok);
variables.write(varid1, start);
} else if (var &&
var->mType == Variables::pointer &&
Token::Match(tok, "%name% ;") &&
tok->varId() == 0 &&
tok->hasKnownIntValue() &&
tok->values().front().intvalue == 0) {
variables.use(varid1, tok);
} else {
variables.write(varid1, tok);
}
@ -1156,6 +1149,15 @@ void CheckUnusedVar::checkFunctionVariableUsage()
// Parse all executing scopes..
const SymbolDatabase *symbolDatabase = mTokenizer->getSymbolDatabase();
auto reportLibraryCfgError = [this](const Token* tok, const std::string& typeName) {
if (mSettings->checkLibrary && mSettings->severity.isEnabled(Severity::information)) {
reportError(tok,
Severity::information,
"checkLibraryCheckType",
"--check-library: Provide <type-checks><unusedvar> configuration for " + typeName);
}
};
// only check functions
for (const Scope * scope : symbolDatabase->functionScopes) {
// Bailout when there are lambdas or inline functions
@ -1281,12 +1283,7 @@ void CheckUnusedVar::checkFunctionVariableUsage()
const Token* scopeEnd = getEndOfExprScope(expr, scope, /*smallest*/ false);
if (fwdAnalysis.unusedValue(expr, start, scopeEnd)) {
if (!bailoutTypeName.empty() && bailoutTypeName != "auto") {
if (mSettings->checkLibrary && mSettings->severity.isEnabled(Severity::information)) {
reportError(tok,
Severity::information,
"checkLibraryCheckType",
"--check-library: Provide <type-checks><unusedvar> configuration for " + bailoutTypeName);
}
reportLibraryCfgError(tok, bailoutTypeName);
continue;
}
@ -1339,6 +1336,26 @@ void CheckUnusedVar::checkFunctionVariableUsage()
// variable has been read but not written
else if (!usage._write && !usage._allocateMemory && var && !var->isStlType() && !isEmptyType(var->type()))
unassignedVariableError(usage._var->nameToken(), varname);
else if (!usage._var->isMaybeUnused() && !usage._modified && !usage._read && var) {
if (usage._lastAccess->linenr() == var->nameToken()->linenr() && var->nameToken()->next()->isSplittedVarDeclEq()) {
bool error = true;
if (mTokenizer->isCPP() && var->isClass() &&
(!var->valueType() || var->valueType()->type == ValueType::Type::UNKNOWN_TYPE)) {
const std::string typeName = var->getTypeName();
switch (mSettings->library.getTypeCheck("unusedvar", typeName)) {
case Library::TypeCheck::def:
reportLibraryCfgError(var->nameToken(), typeName);
break;
case Library::TypeCheck::check:
break;
case Library::TypeCheck::suppress:
error = false;
}
}
if (error)
unreadVariableError(usage._var->nameToken(), varname, false);
}
}
}
}
}

View File

@ -791,7 +791,6 @@ static void compileTerm(Token *&tok, AST_state& state)
tok = tok->tokAt(2);
}
} else if (!state.cpp || !Token::Match(tok, "new|delete %name%|*|&|::|(|[")) {
Token* tok2 = tok;
std::vector<Token*> inner;
tok = skipDecl(tok, &inner);
for (Token* tok3 : inner) {

View File

@ -128,6 +128,7 @@ private:
TEST_CASE(localvar59); // #9737
TEST_CASE(localvar60);
TEST_CASE(localvar61); // #9407
TEST_CASE(localvar62); // #10824
TEST_CASE(localvarloops); // loops
TEST_CASE(localvaralias1);
TEST_CASE(localvaralias2); // ticket #1637
@ -2384,7 +2385,9 @@ private:
" int i = 0;\n"
" int &j = i;\n"
"}");
ASSERT_EQUALS("[test.cpp:4]: (style) Variable 'j' is assigned a value that is never used.\n", errout.str());
ASSERT_EQUALS("[test.cpp:4]: (style) Variable 'j' is assigned a value that is never used.\n"
"[test.cpp:3]: (style) Variable 'i' is assigned a value that is never used.\n",
errout.str());
functionVariableUsage("void foo()\n"
"{\n"
@ -3330,6 +3333,18 @@ private:
ASSERT_EQUALS("[test.cpp:5]: (style) Variable 'var' is assigned a value that is never used.\n", errout.str());
}
void localvar62() { // #10824
functionVariableUsage("void f() {\n"
" S* s = nullptr;\n"
"}\n");
ASSERT_EQUALS("[test.cpp:2]: (style) Variable 's' is assigned a value that is never used.\n", errout.str());
functionVariableUsage("void f() {\n"
" S* s{};\n"
"}\n");
TODO_ASSERT_EQUALS("[test.cpp:2]: (style) Variable 's' is assigned a value that is never used.\n", "", errout.str());
}
void localvarloops() {
// loops
functionVariableUsage("void fun(int c) {\n"