From 45a3828da7da41e312a32598b03fd3de4bfd61b3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daniel=20Marjam=C3=A4ki?= Date: Sat, 19 Mar 2011 09:04:03 +0100 Subject: [PATCH] Tokenizer::setVarId: Better handling of class declarations when variable usage comes before variable declaration --- lib/tokenize.cpp | 27 ++++++++++++++++++++++++++- test/testmemleak.cpp | 3 +-- test/testtokenize.cpp | 26 +++++++++++++++++++++++--- 3 files changed, 50 insertions(+), 6 deletions(-) diff --git a/lib/tokenize.cpp b/lib/tokenize.cpp index b43e0cd41..8b313945a 100644 --- a/lib/tokenize.cpp +++ b/lib/tokenize.cpp @@ -3580,11 +3580,36 @@ void Tokenizer::setVarId() // Variable declaration found => Set variable ids if (Token::Match(tok2, "[,();[=]") && !varname.empty()) { + // Are we in a class declaration? + // Then start at the start of the class declaration.. + while (NULL != (tok2 = tok2->previous())) + { + if (tok2->str() == "}" || tok2->str() == ")") + tok2 = tok2->link(); + else if (tok2->str() == "(") + break; + else if (tok2->str() == "{") + { + while (NULL != (tok2 = tok2->previous())) + { + if (Token::Match(tok2, "[,;{})]")) + break; + if (Token::Match(tok2, "class|struct")) + break; + } + break; + } + } + + // Start token + if (!Token::Match(tok2, "class|struct")) + tok2 = tok; + ++_varId; int indentlevel = 0; int parlevel = 0; bool funcDeclaration = false; - for (tok2 = tok->next(); tok2; tok2 = tok2->next()) + while (NULL != (tok2 = tok2->next())) { const char c = tok2->str()[0]; if (c == varname[0]) diff --git a/test/testmemleak.cpp b/test/testmemleak.cpp index 17cd57147..ad202b8ce 100644 --- a/test/testmemleak.cpp +++ b/test/testmemleak.cpp @@ -4235,8 +4235,7 @@ private: "private:\n" " char *s;\n" "};\n"); - TODO_ASSERT_EQUALS("publicAllocation", - "", errout.str()); + ASSERT_EQUALS("[test.cpp:7]: (warning) Possible leak in public function. The pointer 's' is not deallocated before it is allocated.\n", errout.str()); } void func2() diff --git a/test/testtokenize.cpp b/test/testtokenize.cpp index 54e5b527d..cdbbe8e73 100644 --- a/test/testtokenize.cpp +++ b/test/testtokenize.cpp @@ -193,6 +193,7 @@ private: TEST_CASE(varidclass7); TEST_CASE(varidclass8); TEST_CASE(varidclass9); + TEST_CASE(varidclass10); // variable declaration below usage TEST_CASE(file1); TEST_CASE(file2); @@ -3090,7 +3091,7 @@ private: "10:\n" "11: void Bar :: f ( )\n" "12: {\n" - "13: foo@2 . x = x@3 ;\n" // TODO: it would be even better if the ". x" was ". x@4" instead + "13: foo@2 . x@4 = x@3 ;\n" "14: }\n"); ASSERT_EQUALS(expected, actual); } @@ -3261,7 +3262,7 @@ private: "8:\n" "9: void A :: f ( )\n" "10: {\n" - "11: i = 0 ;\n" + "11: i@1 = 0 ;\n" "12: }\n"); ASSERT_EQUALS(expected, actual); @@ -3381,7 +3382,7 @@ private: "1: class Fred {\n" "2: public:\n" "3: void foo ( int d@1 ) {\n" - "4: int i@2 ; i@2 = bar ( x * d@1 ) ;\n" + "4: int i@2 ; i@2 = bar ( x@3 * d@1 ) ;\n" "5: }\n" "6: int x@3 ;\n" "7: }\n"); @@ -3415,6 +3416,25 @@ private: ASSERT_EQUALS(expected, tokenizeDebugListing(code)); } + void varidclass10() + { + const std::string code("class A {\n" + " void f() {\n" + " a = 3;\n" + " }\n" + " int a;\n" + "};\n;"); + + const std::string expected("\n\n##file 0\n" + "1: class A {\n" + "2: void f ( ) {\n" + "3: a@1 = 3 ;\n" + "4: }\n" + "5: int a@1 ;\n" + "6: } ;\n"); + ASSERT_EQUALS(expected, tokenizeDebugListing(code)); + } + void file1() {