Fixed #8114 (false positive: Address of local auto-variable assigned to a function parameter.)

This commit is contained in:
Daniel Marjamäki 2018-12-01 10:11:02 +01:00
parent a2b6eaf311
commit f42648fe22
2 changed files with 39 additions and 3 deletions

View File

@ -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))) {

View File

@ -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"