fix #3064 (false negative: returning address of stack variable)
This commit is contained in:
parent
a96028b43b
commit
e7dc765ece
|
@ -165,6 +165,12 @@ void CheckAutoVariables::autoVariables()
|
|||
{
|
||||
errorReturnAddressToAutoVariable(tok);
|
||||
}
|
||||
else if (Token::Match(tok, "return & %var% ;") && tok->tokAt(2)->varId())
|
||||
{
|
||||
const Variable * var1 = symbolDatabase->getVariableFromVarId(tok->tokAt(2)->varId());
|
||||
if (var1 && var1->isArgument() && var1->typeStartToken() == var1->typeEndToken())
|
||||
errorReturnAddressOfFunctionParameter(tok, tok->strAt(2));
|
||||
}
|
||||
// Invalid pointer deallocation
|
||||
else if (Token::Match(tok, "free ( %var% ) ;") && isAutoVarArray(tok->tokAt(2)->varId()))
|
||||
{
|
||||
|
@ -264,6 +270,12 @@ void CheckAutoVariables::errorAutoVariableAssignment(const Token *tok, bool inco
|
|||
}
|
||||
}
|
||||
|
||||
void CheckAutoVariables::errorReturnAddressOfFunctionParameter(const Token *tok, const std::string &varname)
|
||||
{
|
||||
reportError(tok, Severity::error, "returnAddressOfFunctionParameter",
|
||||
"Return the address of function parameter '" + varname + "'");
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------------
|
||||
|
||||
// return temporary?
|
||||
|
|
|
@ -89,6 +89,7 @@ private:
|
|||
void errorReturnAutocstr(const Token *tok);
|
||||
void errorReturnTempPointer(const Token *tok);
|
||||
void errorInvalidDeallocation(const Token *tok);
|
||||
void errorReturnAddressOfFunctionParameter(const Token *tok, const std::string &varname);
|
||||
|
||||
void getErrorMessages(ErrorLogger *errorLogger, const Settings *settings)
|
||||
{
|
||||
|
@ -101,6 +102,7 @@ private:
|
|||
c.errorReturnAutocstr(0);
|
||||
c.errorReturnTempPointer(0);
|
||||
c.errorInvalidDeallocation(0);
|
||||
c.errorReturnAddressOfFunctionParameter(0, "parameter");
|
||||
}
|
||||
|
||||
std::string myName() const
|
||||
|
@ -114,7 +116,8 @@ private:
|
|||
"Check:\n"
|
||||
"* returning a pointer to auto or temporary variable\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";
|
||||
}
|
||||
};
|
||||
/// @}
|
||||
|
|
|
@ -98,6 +98,8 @@ private:
|
|||
|
||||
// global namespace
|
||||
TEST_CASE(testglobalnamespace);
|
||||
|
||||
TEST_CASE(returnParameterAddress);
|
||||
}
|
||||
|
||||
|
||||
|
@ -564,6 +566,16 @@ private:
|
|||
ASSERT_EQUALS("", errout.str());
|
||||
}
|
||||
|
||||
void returnParameterAddress()
|
||||
{
|
||||
check("int* foo(int y)\n"
|
||||
"{\n"
|
||||
" return &y;\n"
|
||||
"}\n");
|
||||
|
||||
ASSERT_EQUALS("[test.cpp:3]: (error) Return the address of function parameter 'y'\n", errout.str());
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
REGISTER_TEST(TestAutoVariables)
|
||||
|
|
Loading…
Reference in New Issue