From b96ab6ba261ae290680ed80f01d246bc37249cf0 Mon Sep 17 00:00:00 2001 From: Daniel Marjamaki Date: Sat, 5 Nov 2011 12:23:05 +0100 Subject: [PATCH] Fixed #3188 (Function parser false positive) --- lib/tokenize.cpp | 25 ++++++++++++++++++++----- lib/tokenize.h | 3 ++- test/testsymboldatabase.cpp | 14 ++++++++++++++ test/testtokenize.cpp | 2 +- 4 files changed, 37 insertions(+), 7 deletions(-) diff --git a/lib/tokenize.cpp b/lib/tokenize.cpp index 162eb4d25..9a08ed16a 100644 --- a/lib/tokenize.cpp +++ b/lib/tokenize.cpp @@ -1952,6 +1952,10 @@ bool Tokenizer::tokenize(std::istream &code, return false; } + // Convert K&R function declarations to modern C + simplifyVarDecl(true); + simplifyFunctionParameters(); + // check for simple syntax errors.. for (const Token *tok = _tokens; tok; tok = tok->next()) { if (Token::simpleMatch(tok, "> struct {") && @@ -2376,7 +2380,7 @@ bool Tokenizer::tokenize(std::istream &code, simplifyInitVar(); // Split up variable declarations. - simplifyVarDecl(); + simplifyVarDecl(false); // f(x=g()) => x=g(); f(x) simplifyAssignmentInFunctionCall(); @@ -2420,7 +2424,7 @@ bool Tokenizer::tokenize(std::istream &code, simplifyInitVar(); // Split up variable declarations. - simplifyVarDecl(); + simplifyVarDecl(false); if (!preprocessorCondition) { setVarId(); @@ -4222,9 +4226,8 @@ bool Tokenizer::simplifyTokenList() simplifyInitVar(); // Simplify variable declarations - simplifyVarDecl(); + simplifyVarDecl(false); - simplifyFunctionParameters(); elseif(); simplifyErrNoInWhile(); simplifyIfAssign(); @@ -5629,7 +5632,7 @@ static void incdec(std::string &value, const std::string &op) -void Tokenizer::simplifyVarDecl() +void Tokenizer::simplifyVarDecl(bool only_k_r_fpar) { // Split up variable declarations.. // "int a=4;" => "int a; a=4;" @@ -5640,6 +5643,18 @@ void Tokenizer::simplifyVarDecl() break; } + if (only_k_r_fpar) { + if (tok->str() == "(" || tok->str() == "{") { + tok = tok->link(); + if (!tok) + break; + if (tok->next() && Token::Match(tok, ") !!{")) + tok = tok->next(); + else continue; + } else + continue; + } + if (tok->previous() && !Token::Match(tok->previous(), "{|}|;|)|public:|protected:|private:")) continue; diff --git a/lib/tokenize.h b/lib/tokenize.h index 2058ba49b..b2e099928 100644 --- a/lib/tokenize.h +++ b/lib/tokenize.h @@ -220,8 +220,9 @@ public: /** * Simplify variable declarations (split up) + * \param only_k_r_fpar Only simplify K&R function parameters */ - void simplifyVarDecl(); + void simplifyVarDecl(bool only_k_r_fpar); /** * Simplify variable initialization diff --git a/test/testsymboldatabase.cpp b/test/testsymboldatabase.cpp index eeb547dcd..02c60df6f 100644 --- a/test/testsymboldatabase.cpp +++ b/test/testsymboldatabase.cpp @@ -98,6 +98,8 @@ private: TEST_CASE(hasMissingInlineClassFunctionReturningFunctionPointer); TEST_CASE(hasClassFunctionReturningFunctionPointer); + TEST_CASE(parseFunctionCorrect); + TEST_CASE(hasGlobalVariables1); TEST_CASE(hasGlobalVariables2); TEST_CASE(hasGlobalVariables3); @@ -535,6 +537,18 @@ private: } } + void parseFunctionCorrect() { + // ticket 3188 - "if" statement parsed as function + GET_SYMBOL_DB("void func(i) int i; { if (i == 1) return; }\n") + ASSERT(db != NULL); + + // 3 scopes: Global, function, if + ASSERT_EQUALS(3, db->scopeList.size()); + + ASSERT(tokenizer.getFunctionTokenByName("func") != NULL); + ASSERT(tokenizer.getFunctionTokenByName("if") == NULL); + } + void hasGlobalVariables1() { GET_SYMBOL_DB("int i;\n") diff --git a/test/testtokenize.cpp b/test/testtokenize.cpp index ef4921ab5..bb5aab0c4 100644 --- a/test/testtokenize.cpp +++ b/test/testtokenize.cpp @@ -4114,7 +4114,7 @@ private: const std::string actual(tokenizeAndStringify(code)); - ASSERT_EQUALS("void foo ( a , b ) unsigned int a ; unsigned int b ; { }", actual); + ASSERT_EQUALS("void foo ( unsigned int a , unsigned int b ) { }", actual); } void vardecl3() {