Fixed #6934 (False positive returnLocalVariable - assigning local array to function argument)
This commit is contained in:
parent
d0ab3aea70
commit
f7a7a8a95c
|
@ -6223,6 +6223,7 @@ bool Tokenizer::simplifyKnownVariables()
|
|||
|
||||
// variable id for float/double variables
|
||||
std::set<unsigned int> floatvars;
|
||||
std::set<unsigned int> arrays;
|
||||
|
||||
// auto variables..
|
||||
for (Token *tok = list.front(); tok; tok = tok->next()) {
|
||||
|
@ -6240,6 +6241,13 @@ bool Tokenizer::simplifyKnownVariables()
|
|||
floatvars.insert(tok2->tokAt(2)->varId());
|
||||
}
|
||||
|
||||
if (Token::Match(tok2, "[;{}] %type% |* %name% [")) {
|
||||
const Token *nameToken = tok2->tokAt(2);
|
||||
if (nameToken->str() == "*")
|
||||
nameToken = nameToken->next();
|
||||
arrays.insert(nameToken->varId());
|
||||
}
|
||||
|
||||
if (tok2->str() == "{")
|
||||
++indentlevel;
|
||||
|
||||
|
@ -6309,6 +6317,9 @@ bool Tokenizer::simplifyKnownVariables()
|
|||
if (!simplifyKnownVariablesGetData(varid, &tok2, &tok3, value, valueVarId, valueIsPointer, floatvars.find(tok2->varId()) != floatvars.end()))
|
||||
continue;
|
||||
|
||||
if (valueVarId > 0 && arrays.find(valueVarId) != arrays.end())
|
||||
continue;
|
||||
|
||||
ret |= simplifyKnownVariablesSimplify(&tok2, tok3, varid, structname, value, valueVarId, valueIsPointer, valueToken, indentlevel);
|
||||
}
|
||||
|
||||
|
|
|
@ -662,6 +662,21 @@ static void valueFlowArray(TokenList *tokenlist)
|
|||
if (it != constantArrays.end()) {
|
||||
ValueFlow::Value value;
|
||||
value.tokvalue = it->second;
|
||||
value.setKnown();
|
||||
setTokenValue(tok, value);
|
||||
}
|
||||
|
||||
// pointer = array
|
||||
else if (tok->variable() &&
|
||||
tok->variable()->isArray() &&
|
||||
Token::simpleMatch(tok->astParent(), "=") &&
|
||||
tok == tok->astParent()->astOperand2() &&
|
||||
tok->astParent()->astOperand1() &&
|
||||
tok->astParent()->astOperand1()->variable() &&
|
||||
tok->astParent()->astOperand1()->variable()->isPointer()) {
|
||||
ValueFlow::Value value;
|
||||
value.tokvalue = tok;
|
||||
value.setKnown();
|
||||
setTokenValue(tok, value);
|
||||
}
|
||||
continue;
|
||||
|
@ -675,7 +690,7 @@ static void valueFlowArray(TokenList *tokenlist)
|
|||
continue;
|
||||
}
|
||||
|
||||
if (Token::Match(tok, "const char %var% [ %num%| ] = %str% ;")) {
|
||||
else if (Token::Match(tok, "const char %var% [ %num%| ] = %str% ;")) {
|
||||
const Token *vartok = tok->tokAt(2);
|
||||
const Token *strtok = vartok->next()->link()->tokAt(2);
|
||||
constantArrays[vartok->varId()] = strtok;
|
||||
|
|
|
@ -145,7 +145,6 @@ private:
|
|||
TEST_CASE(pointeralias2);
|
||||
TEST_CASE(pointeralias3);
|
||||
TEST_CASE(pointeralias4);
|
||||
TEST_CASE(pointeralias5);
|
||||
|
||||
TEST_CASE(reduceConstness);
|
||||
|
||||
|
@ -2651,23 +2650,6 @@ private:
|
|||
|
||||
|
||||
void pointeralias1() {
|
||||
{
|
||||
const char code[] = "void f()\n"
|
||||
"{\n"
|
||||
" char buf[100];\n"
|
||||
" char *p = buf;\n"
|
||||
" free(p);\n"
|
||||
"}\n";
|
||||
|
||||
const char expected[] = "void f ( ) "
|
||||
"{ "
|
||||
"char buf [ 100 ] ; "
|
||||
"free ( buf ) ; "
|
||||
"}";
|
||||
|
||||
ASSERT_EQUALS(expected, tok(code));
|
||||
}
|
||||
|
||||
{
|
||||
const char code[] = "void f(char *p1)\n"
|
||||
"{\n"
|
||||
|
@ -2701,38 +2683,6 @@ private:
|
|||
|
||||
ASSERT_EQUALS(expected, tok(code));
|
||||
}
|
||||
|
||||
{
|
||||
const char code[] = "int *foo()\n"
|
||||
"{\n"
|
||||
" int a[10];\n"
|
||||
" int *b = a;\n"
|
||||
" return b;\n"
|
||||
"}\n";
|
||||
|
||||
const char expected[] = "int * foo ( ) "
|
||||
"{ "
|
||||
"int a [ 10 ] ; "
|
||||
"return a ; "
|
||||
"}";
|
||||
|
||||
ASSERT_EQUALS(expected, tok(code));
|
||||
}
|
||||
|
||||
{
|
||||
const char code[] = "void f() {\n"
|
||||
" int a[10];\n"
|
||||
" int *b = a;\n"
|
||||
" memset(b,0,sizeof(a));\n"
|
||||
"}";
|
||||
|
||||
const char expected[] = "void f ( ) {"
|
||||
" int a [ 10 ] ;"
|
||||
" memset ( a , 0 , 40 ) ; "
|
||||
"}";
|
||||
|
||||
ASSERT_EQUALS(expected, tok(code));
|
||||
}
|
||||
}
|
||||
|
||||
void pointeralias2() {
|
||||
|
@ -2764,21 +2714,6 @@ private:
|
|||
}
|
||||
|
||||
void pointeralias4() {
|
||||
const char code[] = "void f()\n"
|
||||
"{\n"
|
||||
" int a[10];\n"
|
||||
" int *p = &a[0];\n"
|
||||
" *p = 0;\n"
|
||||
"}\n";
|
||||
const char expected[] = "void f ( ) "
|
||||
"{"
|
||||
" int a [ 10 ] ;"
|
||||
" * a = 0 ; "
|
||||
"}";
|
||||
ASSERT_EQUALS(expected, tok(code));
|
||||
}
|
||||
|
||||
void pointeralias5() {
|
||||
const char code[] = "int f()\n"
|
||||
"{\n"
|
||||
" int i;\n"
|
||||
|
|
|
@ -229,6 +229,13 @@ private:
|
|||
" return x;\n"
|
||||
"}";
|
||||
TODO_ASSERT_EQUALS(true, false, testValueOfX(code, 3U, "\"abcd\""));
|
||||
|
||||
code = "void f() {\n"
|
||||
" int a[10];\n"
|
||||
" int *x = a;\n" // <- a value is a
|
||||
" *x = 0;\n" // .. => x value is a
|
||||
"}";
|
||||
ASSERT_EQUALS(true, testValueOfX(code, 4, "a"));
|
||||
}
|
||||
|
||||
void valueFlowCalculations() {
|
||||
|
|
Loading…
Reference in New Issue