Symbol database: only put variables in variable list

This commit is contained in:
Daniel Marjamäki 2013-12-31 17:51:56 +01:00
parent 621cf6e777
commit 32be4094e7
5 changed files with 42 additions and 11 deletions

View File

@ -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) {
check->debugMessage(vartok, "Scope::checkVariable found variable \'" + vartok->str() + "\' with varid 0."); if (!vartok->isBoolean())
check->debugMessage(vartok, "Scope::checkVariable found variable \'" + vartok->str() + "\' with varid 0.");
return tok;
}
const Type *vType = NULL; const Type *vType = NULL;

View File

@ -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();
} }

View File

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

View File

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

View File

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