From 32be4094e72d60709083a64753060fcadb36d213 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daniel=20Marjam=C3=A4ki?= Date: Tue, 31 Dec 2013 17:51:56 +0100 Subject: [PATCH] Symbol database: only put variables in variable list --- lib/symboldatabase.cpp | 7 +++++-- lib/tokenize.cpp | 8 ++++---- test/testbufferoverrun.cpp | 10 +++++----- test/testsymboldatabase.cpp | 9 +++++++++ test/testtokenize.cpp | 19 +++++++++++++++++++ 5 files changed, 42 insertions(+), 11 deletions(-) diff --git a/lib/symboldatabase.cpp b/lib/symboldatabase.cpp index d6acbc2be..6d95db8ee 100644 --- a/lib/symboldatabase.cpp +++ b/lib/symboldatabase.cpp @@ -2330,8 +2330,11 @@ const Token *Scope::checkVariable(const Token *tok, AccessControl varaccess) while (tok && tok->str() == "[") tok = tok->link()->next(); - if (vartok->varId() == 0 && !vartok->isBoolean()) - check->debugMessage(vartok, "Scope::checkVariable found variable \'" + vartok->str() + "\' with varid 0."); + if (vartok->varId() == 0) { + if (!vartok->isBoolean()) + check->debugMessage(vartok, "Scope::checkVariable found variable \'" + vartok->str() + "\' with varid 0."); + return tok; + } const Type *vType = NULL; diff --git a/lib/tokenize.cpp b/lib/tokenize.cpp index 672b726d9..324cef805 100644 --- a/lib/tokenize.cpp +++ b/lib/tokenize.cpp @@ -2170,7 +2170,7 @@ void Tokenizer::simplifyTemplates() //--------------------------------------------------------------------------- -static bool setVarIdParseDeclaration(const Token **tok, const std::map &variableId, bool executableScope) +static bool setVarIdParseDeclaration(const Token **tok, const std::map &variableId, bool executableScope, bool cpp) { const Token *tok2 = *tok; @@ -2183,7 +2183,7 @@ static bool setVarIdParseDeclaration(const Token **tok, const std::mapisName()) { - 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; typeCount = 0; } else if (tok2->str() == "const") { @@ -2465,7 +2465,7 @@ void Tokenizer::setVarId() if (notstart.find(tok2->str()) != notstart.end()) 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") { variableId[tok2->previous()->str()] = ++_varId; @@ -2482,7 +2482,7 @@ void Tokenizer::setVarId() continue; 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; tok = tok2->previous(); } diff --git a/test/testbufferoverrun.cpp b/test/testbufferoverrun.cpp index 96e1653ed..c47ab9d59 100644 --- a/test/testbufferoverrun.cpp +++ b/test/testbufferoverrun.cpp @@ -2029,25 +2029,25 @@ private: void array_index_same_struct_and_var_name() { // don't throw internal error check("struct tt {\n" - " char typename[21];\n" + " char name[21];\n" "} ;\n" "void doswitch(struct tt *x)\n" "{\n" " struct tt *tt=x;\n" - " tt->typename;\n" + " tt->name;\n" "}"); ASSERT_EQUALS("", errout.str()); // detect error check("struct tt {\n" - " char typename[21];\n" + " char name[21];\n" "} ;\n" "void doswitch(struct tt *x)\n" "{\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() { diff --git a/test/testsymboldatabase.cpp b/test/testsymboldatabase.cpp index 914e1c41b..3cd5cbe43 100644 --- a/test/testsymboldatabase.cpp +++ b/test/testsymboldatabase.cpp @@ -203,6 +203,7 @@ private: TEST_CASE(symboldatabase39); // ticket #5120 (infinite recursion) TEST_CASE(symboldatabase40); // ticket #5153 TEST_CASE(symboldatabase41); // ticket #5197 (unknown macro) + TEST_CASE(symboldatabase42); // only put variables in variable list 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); } + 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() { { GET_SYMBOL_DB("class Base {\n" diff --git a/test/testtokenize.cpp b/test/testtokenize.cpp index 594ae1828..e108923b7 100644 --- a/test/testtokenize.cpp +++ b/test/testtokenize.cpp @@ -280,6 +280,7 @@ private: TEST_CASE(varid_in_class10); TEST_CASE(varid_in_class11); // #4277 - anonymous union TEST_CASE(varid_in_class12); // #4637 - method + TEST_CASE(varid_in_class13); // #4637 - method TEST_CASE(varid_initList); TEST_CASE(varid_operator); TEST_CASE(varid_throw); @@ -4421,6 +4422,24 @@ private: 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() { const char code1[] = "class A {\n" " A() : x(0) {}\n"