From d52b031301a9f0d92614bca3e8afca48a361f490 Mon Sep 17 00:00:00 2001 From: Frank Zingsheim Date: Thu, 9 Apr 2015 19:58:12 +0200 Subject: [PATCH] Fixed #6638: (varid for loop in for statement) --- lib/tokenize.cpp | 18 +++++++++++------- test/testvarid.cpp | 20 ++++++++++++++++++++ 2 files changed, 31 insertions(+), 7 deletions(-) diff --git a/lib/tokenize.cpp b/lib/tokenize.cpp index 1211505fe..4f76eaeab 100644 --- a/lib/tokenize.cpp +++ b/lib/tokenize.cpp @@ -2575,11 +2575,11 @@ void Tokenizer::setVarId() std::stack scopeStack; scopeStack.push(scopeStackEntryType()); - const Token * functionDeclEnd = nullptr; + std::stack functionDeclEndStack; bool initlist = false; for (Token *tok = list.front(); tok; tok = tok->next()) { - if (tok == functionDeclEnd) { - functionDeclEnd = nullptr; + if (!functionDeclEndStack.empty() && tok == functionDeclEndStack.top()) { + functionDeclEndStack.pop(); if (tok->str() == ":") initlist = true; else if (tok->str() == ";") { @@ -2589,16 +2589,20 @@ void Tokenizer::setVarId() scopeInfo.pop(); } else if (tok->str() == "{") scopeStack.push(scopeStackEntryType(true, _varId)); - } else if (!functionDeclEnd && !initlist && tok->str()=="(") { + } else if (!initlist && tok->str()=="(") { + const Token * newFunctionDeclEnd = nullptr; if (!scopeStack.top().isExecutable) - functionDeclEnd = isFunctionHead(tok, "{:;"); + newFunctionDeclEnd = isFunctionHead(tok, "{:;"); else { Token const * tokenLinkNext = tok->link()->next(); if (tokenLinkNext->str() == "{") // might be for- or while-loop or if-statement - functionDeclEnd = tokenLinkNext; + newFunctionDeclEnd = tokenLinkNext; } - if (functionDeclEnd) + if (newFunctionDeclEnd && + (functionDeclEndStack.empty() || newFunctionDeclEnd != functionDeclEndStack.top())) { + functionDeclEndStack.push(newFunctionDeclEnd); scopeInfo.push(variableId); + } } else if (tok->str() == "{") { // parse anonymous unions as part of the current scope if (!(initlist && Token::Match(tok->previous(), "%name%|>|>>") && Token::Match(tok->link(), "} ,|{"))) { diff --git a/test/testvarid.cpp b/test/testvarid.cpp index 9a31ef0a1..97be75bc2 100644 --- a/test/testvarid.cpp +++ b/test/testvarid.cpp @@ -86,6 +86,7 @@ private: TEST_CASE(varid55); // #5868: Function::addArgument with varid 0 for argument named the same as a typedef TEST_CASE(varid56); // function with a throw() TEST_CASE(varid57); // #6636: new scope by {} + TEST_CASE(varid58); // #6638: for loop in for condition TEST_CASE(varid_cpp_keywords_in_c_code); TEST_CASE(varid_cpp_keywords_in_c_code2); // #5373: varid=0 for argument called "delete" TEST_CASE(varidFunctionCall1); @@ -1023,6 +1024,25 @@ private: ASSERT_EQUALS(expected1, tokenize(code1, false, "test.cpp")); } + void varid58() { // #6638: for loop in for condition + const char code1[] = "void f() {\n" + " for (int i;\n" + " ({for(int i;i;++i){i++;}i++;}),i;\n" + " ({for(int i;i;++i){i++;}i++;}),i++) {\n" + " i++;\n" + " }\n" + "}\n"; + const char expected1[] = "\n\n##file 0\n" + "1: void f ( ) {\n" + "2: for ( int i@1 ;\n" + "3: { for ( int i@2 ; i@2 ; ++ i@2 ) { i@2 ++ ; } i@1 ++ ; } , i@1 ;\n" + "4: { for ( int i@3 ; i@3 ; ++ i@3 ) { i@3 ++ ; } i@1 ++ ; } , i@1 ++ ) {\n" + "5: i@1 ++ ;\n" + "6: }\n" + "7: }\n"; + ASSERT_EQUALS(expected1, tokenize(code1, false, "test.cpp")); + } + void varid_cpp_keywords_in_c_code() { const char code[] = "void f() {\n" " delete d;\n"