Fixed #8114 (false positive: Address of local auto-variable assigned to a function parameter.)
This commit is contained in:
parent
a2b6eaf311
commit
f42648fe22
|
@ -167,6 +167,34 @@ static bool checkRvalueExpression(const Token * const vartok)
|
||||||
return ((next->str() != "." || (!var->isPointer() && (!var->isClass() || var->type()))) && next->strAt(2) != ".");
|
return ((next->str() != "." || (!var->isPointer() && (!var->isClass() || var->type()))) && next->strAt(2) != ".");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static bool isAddressOfLocalVariableRecursive(const Token *expr)
|
||||||
|
{
|
||||||
|
if (!expr)
|
||||||
|
return false;
|
||||||
|
if (Token::Match(expr, "+|-"))
|
||||||
|
return isAddressOfLocalVariableRecursive(expr->astOperand1()) || isAddressOfLocalVariableRecursive(expr->astOperand2());
|
||||||
|
if (expr->str() == "(" && !expr->astOperand2())
|
||||||
|
return isAddressOfLocalVariableRecursive(expr->astOperand1());
|
||||||
|
if (expr->str() == "&" && !expr->astOperand2()) {
|
||||||
|
const Token *op = expr->astOperand1();
|
||||||
|
bool deref = false;
|
||||||
|
while (Token::Match(op, ".|[")) {
|
||||||
|
if (op->str() == "[")
|
||||||
|
deref = true;
|
||||||
|
op = op->astOperand1();
|
||||||
|
}
|
||||||
|
return op && isAutoVar(op) && (!deref || !op->variable()->isPointer());
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
static bool isAddressOfLocalVariable(const Token *expr)
|
||||||
|
{
|
||||||
|
if (!expr || !expr->valueType() || expr->valueType()->pointer == 0)
|
||||||
|
return false;
|
||||||
|
return isAddressOfLocalVariableRecursive(expr);
|
||||||
|
}
|
||||||
|
|
||||||
static bool variableIsUsedInScope(const Token* start, unsigned int varId, const Scope *scope)
|
static bool variableIsUsedInScope(const Token* start, unsigned int varId, const Scope *scope)
|
||||||
{
|
{
|
||||||
if (!start) // Ticket #5024
|
if (!start) // Ticket #5024
|
||||||
|
@ -239,9 +267,8 @@ void CheckAutoVariables::autoVariables()
|
||||||
if (Token::Match(tok, "[;{}] %var% = & %var%") && isRefPtrArg(tok->next()) && isAutoVar(tok->tokAt(4))) {
|
if (Token::Match(tok, "[;{}] %var% = & %var%") && isRefPtrArg(tok->next()) && isAutoVar(tok->tokAt(4))) {
|
||||||
if (checkRvalueExpression(tok->tokAt(4)))
|
if (checkRvalueExpression(tok->tokAt(4)))
|
||||||
errorAutoVariableAssignment(tok->next(), false);
|
errorAutoVariableAssignment(tok->next(), false);
|
||||||
} else if (Token::Match(tok, "[;{}] * %var% = & %var%") && isPtrArg(tok->tokAt(2)) && isAutoVar(tok->tokAt(5))) {
|
} else if (Token::Match(tok, "[;{}] * %var% =") && isPtrArg(tok->tokAt(2)) && isAddressOfLocalVariable(tok->tokAt(3)->astOperand2())) {
|
||||||
if (checkRvalueExpression(tok->tokAt(5)))
|
errorAutoVariableAssignment(tok->next(), false);
|
||||||
errorAutoVariableAssignment(tok->next(), false);
|
|
||||||
} else if (mSettings->isEnabled(Settings::WARNING) && Token::Match(tok, "[;{}] %var% = &| %var% ;") && isGlobalPtr(tok->next())) {
|
} else if (mSettings->isEnabled(Settings::WARNING) && Token::Match(tok, "[;{}] %var% = &| %var% ;") && isGlobalPtr(tok->next())) {
|
||||||
const Token * const pointer = tok->next();
|
const Token * const pointer = tok->next();
|
||||||
if (isAutoVarArray(tok->tokAt(3))) {
|
if (isAutoVarArray(tok->tokAt(3))) {
|
||||||
|
|
|
@ -75,6 +75,7 @@ private:
|
||||||
TEST_CASE(testautovar13); // ticket #5537 - crash
|
TEST_CASE(testautovar13); // ticket #5537 - crash
|
||||||
TEST_CASE(testautovar14); // ticket #4776 - assignment of function parameter, goto
|
TEST_CASE(testautovar14); // ticket #4776 - assignment of function parameter, goto
|
||||||
TEST_CASE(testautovar15); // ticket #6538
|
TEST_CASE(testautovar15); // ticket #6538
|
||||||
|
TEST_CASE(testautovar16); // ticket #8114
|
||||||
TEST_CASE(testautovar_array1);
|
TEST_CASE(testautovar_array1);
|
||||||
TEST_CASE(testautovar_array2);
|
TEST_CASE(testautovar_array2);
|
||||||
TEST_CASE(testautovar_ptrptr); // ticket #6956
|
TEST_CASE(testautovar_ptrptr); // ticket #6956
|
||||||
|
@ -439,6 +440,14 @@ private:
|
||||||
ASSERT_EQUALS("", errout.str());
|
ASSERT_EQUALS("", errout.str());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void testautovar16() { // Ticket #8114
|
||||||
|
check("void f(const void* ptr, bool* result) {\n"
|
||||||
|
" int dummy;\n"
|
||||||
|
" *result = (&dummy < ptr);\n"
|
||||||
|
"}");
|
||||||
|
ASSERT_EQUALS("", errout.str());
|
||||||
|
}
|
||||||
|
|
||||||
void testautovar_array1() {
|
void testautovar_array1() {
|
||||||
check("void func1(int* arr[2])\n"
|
check("void func1(int* arr[2])\n"
|
||||||
"{\n"
|
"{\n"
|
||||||
|
|
Loading…
Reference in New Issue