Refactorized CheckAutoVariables::assignFunctionArg():

- Splitted message into style message (assigning non-pointers) and warning message (assigning pointers)
- Support operator++/-- (#4793)
This commit is contained in:
PKEuS 2014-08-04 11:45:24 +02:00
parent 4a3d719386
commit ac59485e7e
3 changed files with 34 additions and 11 deletions

View File

@ -119,17 +119,23 @@ static bool variableIsUsedInScope(const Token* start, unsigned int varId, const
void CheckAutoVariables::assignFunctionArg() void CheckAutoVariables::assignFunctionArg()
{ {
if (!_settings->isEnabled("warning")) bool style = _settings->isEnabled("style");
bool warning = _settings->isEnabled("warning");
if (!style && !warning)
return; return;
const SymbolDatabase *symbolDatabase = _tokenizer->getSymbolDatabase(); const SymbolDatabase *symbolDatabase = _tokenizer->getSymbolDatabase();
const std::size_t functions = symbolDatabase->functionScopes.size(); const std::size_t functions = symbolDatabase->functionScopes.size();
for (std::size_t i = 0; i < functions; ++i) { for (std::size_t i = 0; i < functions; ++i) {
const Scope * scope = symbolDatabase->functionScopes[i]; const Scope * scope = symbolDatabase->functionScopes[i];
for (const Token *tok = scope->classStart; tok && tok != scope->classEnd; tok = tok->next()) { for (const Token *tok = scope->classStart; tok && tok != scope->classEnd; tok = tok->next()) {
if (Token::Match(tok, "[;{}] %var% =") && if (Token::Match(tok, "[;{}] %var% =|++|--") &&
isNonReferenceArg(tok->next()) && isNonReferenceArg(tok->next()) &&
!variableIsUsedInScope(Token::findsimplematch(tok->tokAt(2), ";"), tok->next()->varId(), scope)) { !variableIsUsedInScope(Token::findsimplematch(tok->tokAt(2), ";"), tok->next()->varId(), scope)) {
errorUselessAssignmentPtrArg(tok->next()); if (tok->next()->variable()->isPointer() && warning)
errorUselessAssignmentPtrArg(tok->next());
else if (style)
errorUselessAssignmentArg(tok->next());
} }
} }
} }
@ -274,12 +280,20 @@ void CheckAutoVariables::errorReturnAddressOfFunctionParameter(const Token *tok,
"value is invalid."); "value is invalid.");
} }
void CheckAutoVariables::errorUselessAssignmentArg(const Token *tok)
{
reportError(tok,
Severity::style,
"uselessAssignmentArg",
"Assignment of function parameter has no effect outside the function.");
}
void CheckAutoVariables::errorUselessAssignmentPtrArg(const Token *tok) void CheckAutoVariables::errorUselessAssignmentPtrArg(const Token *tok)
{ {
reportError(tok, reportError(tok,
Severity::warning, Severity::warning,
"uselessAssignmentPtrArg", "uselessAssignmentPtrArg",
"Assignment of function parameter has no effect outside the function."); "Assignment of function parameter has no effect outside the function. Did you forget dereferencing it?");
} }
//--------------------------------------------------------------------------- //---------------------------------------------------------------------------

View File

@ -87,6 +87,7 @@ private:
void errorReturnTempReference(const Token *tok); void errorReturnTempReference(const Token *tok);
void errorInvalidDeallocation(const Token *tok); void errorInvalidDeallocation(const Token *tok);
void errorReturnAddressOfFunctionParameter(const Token *tok, const std::string &varname); void errorReturnAddressOfFunctionParameter(const Token *tok, const std::string &varname);
void errorUselessAssignmentArg(const Token *tok);
void errorUselessAssignmentPtrArg(const Token *tok); void errorUselessAssignmentPtrArg(const Token *tok);
void getErrorMessages(ErrorLogger *errorLogger, const Settings *settings) const { void getErrorMessages(ErrorLogger *errorLogger, const Settings *settings) const {
@ -98,6 +99,7 @@ private:
c.errorReturnTempReference(0); c.errorReturnTempReference(0);
c.errorInvalidDeallocation(0); c.errorInvalidDeallocation(0);
c.errorReturnAddressOfFunctionParameter(0, "parameter"); c.errorReturnAddressOfFunctionParameter(0, "parameter");
c.errorUselessAssignmentArg(0);
c.errorUselessAssignmentPtrArg(0); c.errorUselessAssignmentPtrArg(0);
} }
@ -112,7 +114,8 @@ private:
"* assigning address of an variable to an effective parameter of a function\n" "* assigning address of an variable to an effective parameter of a function\n"
"* returning reference to local/temporary variable\n" "* returning reference to local/temporary variable\n"
"* returning address of function parameter\n" "* returning address of function parameter\n"
"* useless assignment of pointer parameter\n"; "* suspicious assignment of pointer argument\n"
"* useless assignment of function argument\n";
} }
}; };
/// @} /// @}

View File

@ -41,6 +41,7 @@ private:
Settings settings; Settings settings;
settings.inconclusive = inconclusive; settings.inconclusive = inconclusive;
settings.addEnabled("warning"); settings.addEnabled("warning");
settings.addEnabled("style");
// Tokenize.. // Tokenize..
Tokenizer tokenizer(&settings, this); Tokenizer tokenizer(&settings, this);
@ -132,7 +133,7 @@ private:
" int num = 2;\n" " int num = 2;\n"
" res = &num;\n" " res = &num;\n"
"}"); "}");
ASSERT_EQUALS("[test.cpp:4]: (warning) Assignment of function parameter has no effect outside the function.\n", errout.str()); ASSERT_EQUALS("[test.cpp:4]: (warning) Assignment of function parameter has no effect outside the function. Did you forget dereferencing it?\n", errout.str());
check("void func1(int **res)\n" check("void func1(int **res)\n"
"{\n" "{\n"
@ -161,7 +162,7 @@ private:
" int num = 2;\n" " int num = 2;\n"
" res = &num;\n" " res = &num;\n"
"}"); "}");
ASSERT_EQUALS("[test.cpp:7]: (warning) Assignment of function parameter has no effect outside the function.\n", errout.str()); ASSERT_EQUALS("[test.cpp:7]: (warning) Assignment of function parameter has no effect outside the function. Did you forget dereferencing it?\n", errout.str());
check("class Fred {\n" check("class Fred {\n"
" void func1(int **res);\n" " void func1(int **res);\n"
@ -264,12 +265,12 @@ private:
check("void foo(char* p) {\n" check("void foo(char* p) {\n"
" p = 0;\n" " p = 0;\n"
"}"); "}");
ASSERT_EQUALS("[test.cpp:2]: (warning) Assignment of function parameter has no effect outside the function.\n", errout.str()); ASSERT_EQUALS("[test.cpp:2]: (warning) Assignment of function parameter has no effect outside the function. Did you forget dereferencing it?\n", errout.str());
check("void foo(int b) {\n" check("void foo(int b) {\n"
" b = foo(b);\n" " b = foo(b);\n"
"}"); "}");
ASSERT_EQUALS("[test.cpp:2]: (warning) Assignment of function parameter has no effect outside the function.\n", errout.str()); ASSERT_EQUALS("[test.cpp:2]: (style) Assignment of function parameter has no effect outside the function.\n", errout.str());
check("void foo(char* p) {\n" check("void foo(char* p) {\n"
" if (!p) p = buf;\n" " if (!p) p = buf;\n"
@ -297,13 +298,13 @@ private:
check("void foo(Foo* p) {\n" check("void foo(Foo* p) {\n"
" p = 0;\n" " p = 0;\n"
"}"); "}");
ASSERT_EQUALS("[test.cpp:2]: (warning) Assignment of function parameter has no effect outside the function.\n", errout.str()); ASSERT_EQUALS("[test.cpp:2]: (warning) Assignment of function parameter has no effect outside the function. Did you forget dereferencing it?\n", errout.str());
check("class Foo {};\n" check("class Foo {};\n"
"void foo(Foo p) {\n" "void foo(Foo p) {\n"
" p = 0;\n" " p = 0;\n"
"}"); "}");
ASSERT_EQUALS("[test.cpp:3]: (warning) Assignment of function parameter has no effect outside the function.\n", errout.str()); ASSERT_EQUALS("[test.cpp:3]: (style) Assignment of function parameter has no effect outside the function.\n", errout.str());
check("void foo(Foo p) {\n" check("void foo(Foo p) {\n"
" p = 0;\n" " p = 0;\n"
@ -321,6 +322,11 @@ private:
" return d;" " return d;"
"}",false,false); "}",false,false);
ASSERT_EQUALS("", errout.str()); ASSERT_EQUALS("", errout.str());
check("void foo(int* ptr) {\n" // #4793
" ptr++;\n"
"}");
ASSERT_EQUALS("[test.cpp:2]: (warning) Assignment of function parameter has no effect outside the function. Did you forget dereferencing it?\n", errout.str());
} }
void testautovar11() { // #4641 - fp, assign local struct member address to function parameter void testautovar11() { // #4641 - fp, assign local struct member address to function parameter