Fixed #9034 (Tokenizer::setVarId: function call parameter is not variable declaration)

This commit is contained in:
Daniel Marjamäki 2019-03-24 07:06:15 +01:00
parent 18aa968a7a
commit e0f1418228
2 changed files with 53 additions and 2 deletions

View File

@ -2396,7 +2396,7 @@ static bool setVarIdParseDeclaration(const Token **tok, const std::map<std::stri
if (tok2) {
bool isLambdaArg = false;
if (cpp) {
{
const Token *tok3 = (*tok)->previous();
if (tok3 && tok3->str() == ",") {
while (tok3 && !Token::Match(tok3,";|(|[|{")) {
@ -2404,11 +2404,24 @@ static bool setVarIdParseDeclaration(const Token **tok, const std::map<std::stri
tok3 = tok3->link();
tok3 = tok3->previous();
}
if (tok3 && executableScope && Token::Match(tok3->previous(), "%name% (")) {
const Token *fdecl = tok3->previous();
int count = 0;
while (Token::Match(fdecl, "%name%|*")) {
fdecl = fdecl->previous();
count++;
}
if (!Token::Match(fdecl, "[;{}] %name%") || count <= 1)
return false;
}
}
if (tok3 && Token::simpleMatch(tok3->previous(), "] (") && Token::simpleMatch(tok3->link(), ") {"))
if (cpp && tok3 && Token::simpleMatch(tok3->previous(), "] (") && Token::simpleMatch(tok3->link(), ") {"))
isLambdaArg = true;
}
*tok = tok2;
// In executable scopes, references must be assigned

View File

@ -92,6 +92,7 @@ private:
TEST_CASE(varid59); // #6696
TEST_CASE(varid60); // #7267 cast '(unsigned x)10'
TEST_CASE(varid61); // #4988 inline function
TEST_CASE(varid62);
TEST_CASE(varid_cpp_keywords_in_c_code);
TEST_CASE(varid_cpp_keywords_in_c_code2); // #5373: varid=0 for argument called "delete"
TEST_CASE(varidFunctionCall1);
@ -211,6 +212,31 @@ private:
return tokenizer.tokens()->stringifyList(true,true,true,true,false);
}
std::string compareVaridsForVariable(const char code[], const char varname[], const char filename[] = "test.cpp") {
errout.str("");
Settings settings;
settings.platform(Settings::Unix64);
settings.standards.c = Standards::C89;
settings.standards.cpp = Standards::CPP11;
Tokenizer tokenizer(&settings, this);
std::istringstream istr(code);
tokenizer.tokenize(istr, filename);
unsigned int varid = ~0U;
for (const Token *tok = tokenizer.tokens(); tok; tok = tok->next()) {
if (tok->str() == varname) {
if (varid == ~0U)
varid = tok->varId();
else if (varid != tok->varId())
return std::string("Variable ") + varname + " has different varids:\n" + tokenizer.tokens()->stringifyList(true,true,true,true,false);
}
}
return "same varid";
}
void varid1() {
{
const std::string actual = tokenize(
@ -1073,6 +1099,18 @@ private:
ASSERT_EQUALS(expected, tokenize(code, false));
}
void varid62() {
const char code[] = "void bar(int,int);\n"
"void f() {\n"
" for (size_t c = 0; c < 42; ++c) {\n"
" int x;\n"
" bar(r, r * x);\n"
" }\n"
"}";
// Ensure that there is only one variable id for "x"
ASSERT_EQUALS("same varid", compareVaridsForVariable(code, "x"));
}
void varid_cpp_keywords_in_c_code() {
const char code[] = "void f() {\n"
" delete d;\n"