More general fix to #4187 (False positive: Variable inside a lambda is reported as uninitialized)

This commit is contained in:
Frank Zingsheim 2013-05-12 10:19:43 +02:00
parent d387e8b770
commit 511f8a4c1f
3 changed files with 39 additions and 20 deletions

View File

@ -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:"))

View File

@ -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

View File

@ -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() {