From 6ed727564c0562d5985183478a63598ee7d3125d Mon Sep 17 00:00:00 2001 From: Reijo Tomperi Date: Wed, 30 Sep 2009 14:40:10 +0300 Subject: [PATCH] Fix #759 (Tokenizer: Incorrect var id when two variables with same name) http://sourceforge.net/apps/trac/cppcheck/ticket/759 --- src/tokenize.cpp | 7 +++- test/testtokenize.cpp | 87 ++++++++++++++++++++++++++++++------------- 2 files changed, 68 insertions(+), 26 deletions(-) diff --git a/src/tokenize.cpp b/src/tokenize.cpp index bba2f72a5..edcf684b4 100644 --- a/src/tokenize.cpp +++ b/src/tokenize.cpp @@ -1078,6 +1078,7 @@ void Tokenizer::setVarId() int indentlevel = 0; int parlevel = 0; bool dot = false; + bool funcDeclaration = false; for (tok2 = tok->next(); tok2; tok2 = tok2->next()) { if (!dot && tok2->str() == varname && !Token::Match(tok2->previous(), "struct|union")) @@ -1089,6 +1090,10 @@ void Tokenizer::setVarId() --indentlevel; if (indentlevel < 0) break; + + // We have reached the end of a loop: "for( int i;;) { }" + if (funcDeclaration && indentlevel <= 0) + break; } else if (tok2->str() == "(") ++parlevel; @@ -1096,7 +1101,7 @@ void Tokenizer::setVarId() { // Is this a function parameter or a variable declared in for example a for loop? if (parlevel == 0 && indentlevel == 0 && Token::Match(tok2, ") const| {")) - ; + funcDeclaration = true; else --parlevel; } diff --git a/test/testtokenize.cpp b/test/testtokenize.cpp index e704824fe..9bb5a07bc 100644 --- a/test/testtokenize.cpp +++ b/test/testtokenize.cpp @@ -930,34 +930,71 @@ private: void varid1() { - const std::string code("static int i = 1;\n" - "void f()\n" - "{\n" - " int i = 2;\n" - " for (int i = 0; i < 10; ++i)\n" - " i = 3;\n" - " i = 4;\n" - "}\n"); + { + const std::string code("static int i = 1;\n" + "void f()\n" + "{\n" + " int i = 2;\n" + " for (int i = 0; i < 10; ++i)\n" + " i = 3;\n" + " i = 4;\n" + "}\n"); - // tokenize.. - Tokenizer tokenizer; - std::istringstream istr(code); - tokenizer.tokenize(istr, "test.cpp"); - tokenizer.setVarId(); + // tokenize.. + Tokenizer tokenizer; + std::istringstream istr(code); + tokenizer.tokenize(istr, "test.cpp"); + tokenizer.setVarId(); - // result.. - const std::string actual(tokenizer.tokens()->stringifyList(true)); - const std::string expected("\n\n##file 0\n" - "1: static int i@1 = 1 ;\n" - "2: void f ( )\n" - "3: {\n" - "4: int i@2 ; i@2 = 2 ;\n" - "5: for ( int i@3 = 0 ; i@3 < 10 ; ++ i@3 )\n" - "6: i@3 = 3 ;\n" - "7: i@2 = 4 ;\n" - "8: }\n"); + // result.. + const std::string actual(tokenizer.tokens()->stringifyList(true)); + const std::string expected("\n\n##file 0\n" + "1: static int i@1 = 1 ;\n" + "2: void f ( )\n" + "3: {\n" + "4: int i@2 ; i@2 = 2 ;\n" + "5: for ( int i@3 = 0 ; i@3 < 10 ; ++ i@3 )\n" + "6: i@3 = 3 ;\n" + "7: i@2 = 4 ;\n" + "8: }\n"); - ASSERT_EQUALS(expected, actual); + ASSERT_EQUALS(expected, actual); + } + + { + const std::string code("static int i = 1;\n" + "void f()\n" + "{\n" + " int i = 2;\n" + " for (int i = 0; i < 10; ++i)\n" + " {\n" + " i = 3;\n" + " }\n" + " i = 4;\n" + "}\n"); + + // tokenize.. + Tokenizer tokenizer; + std::istringstream istr(code); + tokenizer.tokenize(istr, "test.cpp"); + tokenizer.setVarId(); + + // result.. + const std::string actual(tokenizer.tokens()->stringifyList(true)); + const std::string expected("\n\n##file 0\n" + "1: static int i@1 = 1 ;\n" + "2: void f ( )\n" + "3: {\n" + "4: int i@2 ; i@2 = 2 ;\n" + "5: for ( int i@3 = 0 ; i@3 < 10 ; ++ i@3 )\n" + "6: {\n" + "7: i@3 = 3 ;\n" + "8: }\n" + "9: i@2 = 4 ;\n" + "10: }\n"); + + ASSERT_EQUALS(expected, actual); + } } void varid2()