Fixed #5005 (false positive: (warning) Assignment of function parameter has no effect outside the function.)
This commit is contained in:
parent
1234ec95f0
commit
0ef1529ba5
|
@ -118,12 +118,27 @@ static bool variableIsUsedInScope(const Token* start, unsigned int varId, const
|
|||
return false;
|
||||
}
|
||||
|
||||
void CheckAutoVariables::assignFunctionArg()
|
||||
{
|
||||
if (!_settings->isEnabled("warning"))
|
||||
return;
|
||||
const SymbolDatabase *symbolDatabase = _tokenizer->getSymbolDatabase();
|
||||
const std::size_t functions = symbolDatabase->functionScopes.size();
|
||||
for (std::size_t i = 0; i < functions; ++i) {
|
||||
const Scope * scope = symbolDatabase->functionScopes[i];
|
||||
for (const Token *tok = scope->classStart; tok && tok != scope->classEnd; tok = tok->next()) {
|
||||
if (Token::Match(tok, "[;{}] %var% =") &&
|
||||
isNonReferenceArg(tok->next()) &&
|
||||
!variableIsUsedInScope(Token::findsimplematch(tok->tokAt(2), ";"), tok->next()->varId(), scope)) {
|
||||
errorUselessAssignmentPtrArg(tok->next());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void CheckAutoVariables::autoVariables()
|
||||
{
|
||||
const SymbolDatabase *symbolDatabase = _tokenizer->getSymbolDatabase();
|
||||
|
||||
const bool reportWarnings(_settings->isEnabled("warning"));
|
||||
|
||||
const std::size_t functions = symbolDatabase->functionScopes.size();
|
||||
for (std::size_t i = 0; i < functions; ++i) {
|
||||
const Scope * scope = symbolDatabase->functionScopes[i];
|
||||
|
@ -135,11 +150,6 @@ void CheckAutoVariables::autoVariables()
|
|||
} else if (Token::Match(tok, "[;{}] * %var% = & %var%") && isPtrArg(tok->tokAt(2)) && isAutoVar(tok->tokAt(5))) {
|
||||
if (checkRvalueExpression(tok->tokAt(5)))
|
||||
errorAutoVariableAssignment(tok->next(), false);
|
||||
} else if (reportWarnings &&
|
||||
Token::Match(tok, "[;{}] %var% =") &&
|
||||
isNonReferenceArg(tok->next()) &&
|
||||
!variableIsUsedInScope(Token::findsimplematch(tok->tokAt(2), ";"), tok->next()->varId(), scope)) {
|
||||
errorUselessAssignmentPtrArg(tok->next());
|
||||
} else if (Token::Match(tok, "[;{}] %var% . %var% = & %var%")) {
|
||||
// TODO: check if the parameter is only changed temporarily (#2969)
|
||||
if (_settings->inconclusive) {
|
||||
|
|
|
@ -44,6 +44,7 @@ public:
|
|||
/** @brief Run checks against the normal token list */
|
||||
void runChecks(const Tokenizer *tokenizer, const Settings *settings, ErrorLogger *errorLogger) {
|
||||
CheckAutoVariables checkAutoVariables(tokenizer, settings, errorLogger);
|
||||
checkAutoVariables.assignFunctionArg();
|
||||
checkAutoVariables.returnReference();
|
||||
}
|
||||
|
||||
|
@ -53,6 +54,9 @@ public:
|
|||
checkAutoVariables.returnPointerToLocalArray();
|
||||
}
|
||||
|
||||
/** assign function argument */
|
||||
void assignFunctionArg();
|
||||
|
||||
/** Check auto variables */
|
||||
void autoVariables();
|
||||
|
||||
|
|
|
@ -49,6 +49,7 @@ private:
|
|||
|
||||
CheckAutoVariables checkAutoVariables(&tokenizer, &settings, this);
|
||||
checkAutoVariables.returnReference();
|
||||
checkAutoVariables.assignFunctionArg();
|
||||
|
||||
if (runSimpleChecks) {
|
||||
const std::string str1(tokenizer.tokens()->stringifyList(0,true));
|
||||
|
@ -305,6 +306,13 @@ private:
|
|||
" p = 0;\n"
|
||||
"}");
|
||||
ASSERT_EQUALS("", errout.str());
|
||||
|
||||
check("double foo(double d) {\n" // #5005
|
||||
" int i = d;\n"
|
||||
" d = i;\n"
|
||||
" return d;"
|
||||
"}",false,false);
|
||||
ASSERT_EQUALS("", errout.str());
|
||||
}
|
||||
|
||||
void testautovar11() { // #4641 - fp, assign local struct member address to function parameter
|
||||
|
|
Loading…
Reference in New Issue