diff --git a/lib/tokenize.cpp b/lib/tokenize.cpp index e1599c172..106b78e30 100644 --- a/lib/tokenize.cpp +++ b/lib/tokenize.cpp @@ -2366,11 +2366,25 @@ static bool setVarIdParseDeclaration(const Token **tok, const std::mapprevious(); + if (tok3 && tok3->str() == ",") { + while (tok3 && !Token::Match(tok3,";|(|[|{")) { + if (Token::Match(tok3, ")|]")) + tok3 = tok3->link(); + tok3 = tok3->previous(); + } + } + if (tok3 && Token::simpleMatch(tok3->previous(), "] (") && Token::simpleMatch(tok3->link(), ") {")) + isLambdaArg = true; + } + *tok = tok2; // In executable scopes, references must be assigned // Catching by reference is an exception - if (executableScope && ref) { + if (executableScope && ref && !isLambdaArg) { if (Token::Match(tok2, "(|=|{|:")) ; // reference is assigned => ok else if (tok2->str() != ")" || tok2->link()->strAt(-1) != "catch") diff --git a/test/testvarid.cpp b/test/testvarid.cpp index dd4e6505e..698ae153f 100644 --- a/test/testvarid.cpp +++ b/test/testvarid.cpp @@ -157,6 +157,7 @@ private: TEST_CASE(varid_rangeBasedFor); TEST_CASE(varid_structinit); // #6406 TEST_CASE(varid_arrayinit); // #7579 + TEST_CASE(varid_lambda_arg); TEST_CASE(varidclass1); TEST_CASE(varidclass2); @@ -2400,6 +2401,25 @@ private: ASSERT_EQUALS("1: void foo ( int * a@1 ) { int b@2 [ 1 ] = { x * a@1 [ 0 ] } ; }\n", tokenize("void foo(int*a) { int b[] = { x*a[0] }; }")); } + void varid_lambda_arg() { + // #8664 + const char code1[] = "static void func(int ec) {\n" + " func2([](const std::error_code& ec) { return ec; });\n" + "}"; + const char exp1[] = "1: static void func ( int ec@1 ) {\n" + "2: func2 ( [ ] ( const std :: error_code & ec@2 ) { return ec@2 ; } ) ;\n" + "3: }\n"; + ASSERT_EQUALS(exp1, tokenize(code1)); + + const char code2[] = "static void func(int ec) {\n" + " func2([](int x, const std::error_code& ec) { return x + ec; });\n" + "}"; + const char exp2[] = "1: static void func ( int ec@1 ) {\n" + "2: func2 ( [ ] ( int x@2 , const std :: error_code & ec@3 ) { return x@2 + ec@3 ; } ) ;\n" + "3: }\n"; + ASSERT_EQUALS(exp2, tokenize(code2)); + } + void varidclass1() { const std::string actual = tokenize( "class Fred\n"