From 511f8a4c1f969253d855812131a47c62a5e892fd Mon Sep 17 00:00:00 2001 From: Frank Zingsheim Date: Sun, 12 May 2013 10:19:43 +0200 Subject: [PATCH] More general fix to #4187 (False positive: Variable inside a lambda is reported as uninitialized) --- lib/tokenize.cpp | 22 +++++++++++++++------- lib/tokenize.h | 1 + test/testtokenize.cpp | 36 +++++++++++++++++++++++------------- 3 files changed, 39 insertions(+), 20 deletions(-) diff --git a/lib/tokenize.cpp b/lib/tokenize.cpp index 05c9c2e2d..ca97cc792 100644 --- a/lib/tokenize.cpp +++ b/lib/tokenize.cpp @@ -4978,14 +4978,17 @@ static void incdec(std::string &value, const std::string &op) value = ostr.str(); } - - void Tokenizer::simplifyVarDecl(bool only_k_r_fpar) +{ + simplifyVarDecl(list.front(), NULL, only_k_r_fpar); +} + +void Tokenizer::simplifyVarDecl(Token * tokBegin, Token * tokEnd, bool only_k_r_fpar) { // Split up variable declarations.. // "int a=4;" => "int a; a=4;" bool finishedwithkr = true; - for (Token *tok = list.front(); tok; tok = tok->next()) { + for (Token *tok = tokBegin; tok != tokEnd; tok = tok->next()) { if (Token::simpleMatch(tok, "= {")) { tok = tok->next()->link(); } @@ -5000,11 +5003,16 @@ void Tokenizer::simplifyVarDecl(bool only_k_r_fpar) } else continue; } else if (tok->str() == "(") { + for (Token * tok2 = tok; tok2 != tok->link(); tok2 = tok2->next()) { + if (isCPP() && Token::Match(tok2, "[(,] [")) { + // lambda function at tok2->next() + // find start of lambda body + Token * lambdaBody = Token::findsimplematch(tok2, "{", tok->link()); + if (lambdaBody && lambdaBody->link()) + simplifyVarDecl(lambdaBody, lambdaBody->link(), only_k_r_fpar); + } + } tok = tok->link(); - - // TestTokenizer::vardecl24 - lambda functions.. - if (isCPP() && tok->previous()->str() == "}") - tok = tok->previous()->link(); } if (tok->previous() && !Token::Match(tok->previous(), "{|}|;|)|public:|protected:|private:")) diff --git a/lib/tokenize.h b/lib/tokenize.h index ca4e3a9ba..a8604c4c6 100644 --- a/lib/tokenize.h +++ b/lib/tokenize.h @@ -208,6 +208,7 @@ public: * \param only_k_r_fpar Only simplify K&R function parameters */ void simplifyVarDecl(bool only_k_r_fpar); + void simplifyVarDecl(Token * tokBegin, Token * tokEnd, bool only_k_r_fpar); /** * Simplify variable initialization diff --git a/test/testtokenize.cpp b/test/testtokenize.cpp index 404c3e27b..630d4b495 100644 --- a/test/testtokenize.cpp +++ b/test/testtokenize.cpp @@ -5730,21 +5730,31 @@ private: } void vardecl24() { // #4187 - variable declaration within lambda function - const char code[] = "void f() {\n" - " std::for_each(ints.begin(), ints.end(), [](int val)\n" - " {\n" - " int temp = 0;\n" - " });\n" - "}"; + const char code1[] = "void f() {\n" + " std::for_each(ints.begin(), ints.end(), [](int val)\n" + " {\n" + " int temp = 0;\n" + " });\n" + "}"; - const char expected[] = "void f ( ) {\n" - "std :: for_each ( ints . begin ( ) , ints . end ( ) , [ ] ( int val )\n" - "{\n" - "int temp ; temp = 0 ;\n" - "} ) ;\n" - "}"; + const char expected1[] = "void f ( ) {\n" + "std :: for_each ( ints . begin ( ) , ints . end ( ) , [ ] ( int val )\n" + "{\n" + "int temp ; temp = 0 ;\n" + "} ) ;\n" + "}"; - ASSERT_EQUALS(expected, tokenizeAndStringify(code)); + ASSERT_EQUALS(expected1, tokenizeAndStringify(code1)); + + const char code2[] = "void f(int j) {\n" + " g( [](){int temp = 0;} , j );\n" + "}"; + + const char expected2[] = "void f ( int j ) {\n" + "g ( [ ] ( ) { int temp ; temp = 0 ; } , j ) ;\n" + "}"; + + ASSERT_EQUALS(expected2, tokenizeAndStringify(code2)); } void volatile_variables() {