Symbol database: only put variables in variable list
This commit is contained in:
parent
621cf6e777
commit
32be4094e7
|
@ -2330,8 +2330,11 @@ const Token *Scope::checkVariable(const Token *tok, AccessControl varaccess)
|
||||||
while (tok && tok->str() == "[")
|
while (tok && tok->str() == "[")
|
||||||
tok = tok->link()->next();
|
tok = tok->link()->next();
|
||||||
|
|
||||||
if (vartok->varId() == 0 && !vartok->isBoolean())
|
if (vartok->varId() == 0) {
|
||||||
|
if (!vartok->isBoolean())
|
||||||
check->debugMessage(vartok, "Scope::checkVariable found variable \'" + vartok->str() + "\' with varid 0.");
|
check->debugMessage(vartok, "Scope::checkVariable found variable \'" + vartok->str() + "\' with varid 0.");
|
||||||
|
return tok;
|
||||||
|
}
|
||||||
|
|
||||||
const Type *vType = NULL;
|
const Type *vType = NULL;
|
||||||
|
|
||||||
|
|
|
@ -2170,7 +2170,7 @@ void Tokenizer::simplifyTemplates()
|
||||||
//---------------------------------------------------------------------------
|
//---------------------------------------------------------------------------
|
||||||
|
|
||||||
|
|
||||||
static bool setVarIdParseDeclaration(const Token **tok, const std::map<std::string,unsigned int> &variableId, bool executableScope)
|
static bool setVarIdParseDeclaration(const Token **tok, const std::map<std::string,unsigned int> &variableId, bool executableScope, bool cpp)
|
||||||
{
|
{
|
||||||
const Token *tok2 = *tok;
|
const Token *tok2 = *tok;
|
||||||
|
|
||||||
|
@ -2183,7 +2183,7 @@ static bool setVarIdParseDeclaration(const Token **tok, const std::map<std::stri
|
||||||
bool hasstruct = false; // Is there a "struct" or "class"?
|
bool hasstruct = false; // Is there a "struct" or "class"?
|
||||||
while (tok2) {
|
while (tok2) {
|
||||||
if (tok2->isName()) {
|
if (tok2->isName()) {
|
||||||
if (tok2->str() == "class" || tok2->str() == "struct" || tok2->str() == "union" || tok2->str() == "typename") {
|
if (tok2->str() == "struct" || tok2->str() == "union" || (cpp && (tok2->str() == "class" || tok2->str() == "typename"))) {
|
||||||
hasstruct = true;
|
hasstruct = true;
|
||||||
typeCount = 0;
|
typeCount = 0;
|
||||||
} else if (tok2->str() == "const") {
|
} else if (tok2->str() == "const") {
|
||||||
|
@ -2465,7 +2465,7 @@ void Tokenizer::setVarId()
|
||||||
if (notstart.find(tok2->str()) != notstart.end())
|
if (notstart.find(tok2->str()) != notstart.end())
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
const bool decl = setVarIdParseDeclaration(&tok2, variableId, executableScope.top());
|
const bool decl = setVarIdParseDeclaration(&tok2, variableId, executableScope.top(), isCPP());
|
||||||
|
|
||||||
if (decl && Token::Match(tok2->previous(), "%type% [;[=,)]") && tok2->previous()->str() != "const") {
|
if (decl && Token::Match(tok2->previous(), "%type% [;[=,)]") && tok2->previous()->str() != "const") {
|
||||||
variableId[tok2->previous()->str()] = ++_varId;
|
variableId[tok2->previous()->str()] = ++_varId;
|
||||||
|
@ -2482,7 +2482,7 @@ void Tokenizer::setVarId()
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
const Token *tok3 = tok2->next();
|
const Token *tok3 = tok2->next();
|
||||||
if (!tok3->isStandardType() && tok3->str() != "void" && !Token::Match(tok3,"struct|union|class %type%") && tok3->str() != "." && !setVarIdParseDeclaration(&tok3,variableId,executableScope.top())) {
|
if (!tok3->isStandardType() && tok3->str() != "void" && !Token::Match(tok3,"struct|union|class %type%") && tok3->str() != "." && !setVarIdParseDeclaration(&tok3,variableId,executableScope.top(),isCPP())) {
|
||||||
variableId[tok2->previous()->str()] = ++_varId;
|
variableId[tok2->previous()->str()] = ++_varId;
|
||||||
tok = tok2->previous();
|
tok = tok2->previous();
|
||||||
}
|
}
|
||||||
|
|
|
@ -2029,25 +2029,25 @@ private:
|
||||||
void array_index_same_struct_and_var_name() {
|
void array_index_same_struct_and_var_name() {
|
||||||
// don't throw internal error
|
// don't throw internal error
|
||||||
check("struct tt {\n"
|
check("struct tt {\n"
|
||||||
" char typename[21];\n"
|
" char name[21];\n"
|
||||||
"} ;\n"
|
"} ;\n"
|
||||||
"void doswitch(struct tt *x)\n"
|
"void doswitch(struct tt *x)\n"
|
||||||
"{\n"
|
"{\n"
|
||||||
" struct tt *tt=x;\n"
|
" struct tt *tt=x;\n"
|
||||||
" tt->typename;\n"
|
" tt->name;\n"
|
||||||
"}");
|
"}");
|
||||||
ASSERT_EQUALS("", errout.str());
|
ASSERT_EQUALS("", errout.str());
|
||||||
|
|
||||||
// detect error
|
// detect error
|
||||||
check("struct tt {\n"
|
check("struct tt {\n"
|
||||||
" char typename[21];\n"
|
" char name[21];\n"
|
||||||
"} ;\n"
|
"} ;\n"
|
||||||
"void doswitch(struct tt *x)\n"
|
"void doswitch(struct tt *x)\n"
|
||||||
"{\n"
|
"{\n"
|
||||||
" struct tt *tt=x;\n"
|
" struct tt *tt=x;\n"
|
||||||
" tt->typename[22] = 123;\n"
|
" tt->name[22] = 123;\n"
|
||||||
"}");
|
"}");
|
||||||
ASSERT_EQUALS("[test.cpp:7]: (error) Array 'tt.typename[21]' accessed at index 22, which is out of bounds.\n", errout.str());
|
ASSERT_EQUALS("[test.cpp:7]: (error) Array 'tt.name[21]' accessed at index 22, which is out of bounds.\n", errout.str());
|
||||||
}
|
}
|
||||||
|
|
||||||
void buffer_overrun_1_standard_functions() {
|
void buffer_overrun_1_standard_functions() {
|
||||||
|
|
|
@ -203,6 +203,7 @@ private:
|
||||||
TEST_CASE(symboldatabase39); // ticket #5120 (infinite recursion)
|
TEST_CASE(symboldatabase39); // ticket #5120 (infinite recursion)
|
||||||
TEST_CASE(symboldatabase40); // ticket #5153
|
TEST_CASE(symboldatabase40); // ticket #5153
|
||||||
TEST_CASE(symboldatabase41); // ticket #5197 (unknown macro)
|
TEST_CASE(symboldatabase41); // ticket #5197 (unknown macro)
|
||||||
|
TEST_CASE(symboldatabase42); // only put variables in variable list
|
||||||
|
|
||||||
TEST_CASE(isImplicitlyVirtual);
|
TEST_CASE(isImplicitlyVirtual);
|
||||||
|
|
||||||
|
@ -1672,6 +1673,14 @@ private:
|
||||||
ASSERT(db && db->findScopeByName("X1") && db->findScopeByName("X1")->functionList.size() == 1 && !db->findScopeByName("X1")->functionList.front().hasBody);
|
ASSERT(db && db->findScopeByName("X1") && db->findScopeByName("X1")->functionList.size() == 1 && !db->findScopeByName("X1")->functionList.front().hasBody);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void symboldatabase42() { // only put variables in variable list
|
||||||
|
GET_SYMBOL_DB("void f() { extern int x(); }\n");
|
||||||
|
ASSERT(db);
|
||||||
|
const Scope * const fscope = db ? db->findScopeByName("f") : NULL;
|
||||||
|
ASSERT(fscope);
|
||||||
|
ASSERT_EQUALS(0U, fscope ? fscope->varlist.size() : ~0U); // "x" is not a variable
|
||||||
|
}
|
||||||
|
|
||||||
void isImplicitlyVirtual() {
|
void isImplicitlyVirtual() {
|
||||||
{
|
{
|
||||||
GET_SYMBOL_DB("class Base {\n"
|
GET_SYMBOL_DB("class Base {\n"
|
||||||
|
|
|
@ -280,6 +280,7 @@ private:
|
||||||
TEST_CASE(varid_in_class10);
|
TEST_CASE(varid_in_class10);
|
||||||
TEST_CASE(varid_in_class11); // #4277 - anonymous union
|
TEST_CASE(varid_in_class11); // #4277 - anonymous union
|
||||||
TEST_CASE(varid_in_class12); // #4637 - method
|
TEST_CASE(varid_in_class12); // #4637 - method
|
||||||
|
TEST_CASE(varid_in_class13); // #4637 - method
|
||||||
TEST_CASE(varid_initList);
|
TEST_CASE(varid_initList);
|
||||||
TEST_CASE(varid_operator);
|
TEST_CASE(varid_operator);
|
||||||
TEST_CASE(varid_throw);
|
TEST_CASE(varid_throw);
|
||||||
|
@ -4421,6 +4422,24 @@ private:
|
||||||
tokenizeDebugListing(code));
|
tokenizeDebugListing(code));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void varid_in_class13() {
|
||||||
|
const char code1[] = "struct a { char typename; };";
|
||||||
|
ASSERT_EQUALS("\n\n##file 0\n"
|
||||||
|
"1: struct a { char typename@1 ; } ;\n",
|
||||||
|
tokenizeDebugListing(code1, false, "test.c"));
|
||||||
|
ASSERT_EQUALS("\n\n##file 0\n"
|
||||||
|
"1: struct a { char typename ; } ;\n", // not valid C++ code
|
||||||
|
tokenizeDebugListing(code1, false, "test.cpp"));
|
||||||
|
|
||||||
|
const char code2[] = "struct a { char typename[2]; };";
|
||||||
|
ASSERT_EQUALS("\n\n##file 0\n"
|
||||||
|
"1: struct a { char typename@1 [ 2 ] ; } ;\n",
|
||||||
|
tokenizeDebugListing(code2, false, "test.c"));
|
||||||
|
ASSERT_EQUALS("\n\n##file 0\n"
|
||||||
|
"1: struct a { char typename [ 2 ] ; } ;\n", // not valid C++ code
|
||||||
|
tokenizeDebugListing(code2, false, "test.cpp"));
|
||||||
|
}
|
||||||
|
|
||||||
void varid_initList() {
|
void varid_initList() {
|
||||||
const char code1[] = "class A {\n"
|
const char code1[] = "class A {\n"
|
||||||
" A() : x(0) {}\n"
|
" A() : x(0) {}\n"
|
||||||
|
|
Loading…
Reference in New Issue