From ccf21766644919c609154b7e57a675c38f1126ed Mon Sep 17 00:00:00 2001 From: chrchr-github <78114321+chrchr-github@users.noreply.github.com> Date: Tue, 1 Nov 2022 11:50:08 +0100 Subject: [PATCH] Fix #11370 FP constStatement with lambda (#4570) * Update tokenlist.cpp * Update testincompletestatement.cpp * Fix #11370 FP constStatement with lambda * Format --- lib/tokenlist.cpp | 13 ++++++++++++- test/testincompletestatement.cpp | 6 ++++++ test/testtokenize.cpp | 4 ++++ 3 files changed, 22 insertions(+), 1 deletion(-) diff --git a/lib/tokenlist.cpp b/lib/tokenlist.cpp index 342decd7f..d4217b232 100644 --- a/lib/tokenlist.cpp +++ b/lib/tokenlist.cpp @@ -493,6 +493,17 @@ static Token * createAstAtToken(Token *tok, bool cpp); static Token* skipDecl(Token* tok, std::vector* inner = nullptr) { + auto isDecltypeFuncParam = [](const Token* tok) -> bool { + if (!Token::simpleMatch(tok, ")")) + return false; + tok = tok->next(); + while (Token::Match(tok, "*|&|&&|const")) + tok = tok->next(); + if (Token::simpleMatch(tok, "(")) + tok = tok->link()->next(); + return Token::Match(tok, "%name%| ,|)"); + }; + if (!Token::Match(tok->previous(), "( %name%")) return tok; Token *vartok = tok; @@ -504,7 +515,7 @@ static Token* skipDecl(Token* tok, std::vector* inner = nullptr) return tok; } else if (Token::Match(vartok, "%var% [:=(]")) { return vartok; - } else if (Token::Match(vartok, "decltype|typeof (") && !Token::Match(tok->linkAt(1), ") [,)]")) { + } else if (Token::Match(vartok, "decltype|typeof (") && !isDecltypeFuncParam(tok->linkAt(1))) { if (inner) inner->push_back(vartok->tokAt(2)); return vartok->linkAt(1)->next(); diff --git a/test/testincompletestatement.cpp b/test/testincompletestatement.cpp index 7106fb7f3..a5a340e97 100644 --- a/test/testincompletestatement.cpp +++ b/test/testincompletestatement.cpp @@ -709,6 +709,12 @@ private: " (*s).i;\n" "}\n"); ASSERT_EQUALS("[test.cpp:3]: (warning) Redundant code: Found unused member access.\n", errout.str()); + + check("int a[2];\n" // #11370 + "void f() {\n" + " auto g = [](decltype(a[0]) i) {};\n" + "}\n"); + ASSERT_EQUALS("", errout.str()); } void vardecl() { diff --git a/test/testtokenize.cpp b/test/testtokenize.cpp index 714dda106..165fbb288 100644 --- a/test/testtokenize.cpp +++ b/test/testtokenize.cpp @@ -6243,6 +6243,10 @@ private: ASSERT_EQUALS("decltypexy+(yx+{", testAst("decltype(x+y){y+x};")); ASSERT_EQUALS("adecltypeac::(,decltypead::(,", testAst("template void b(a &, decltype(a::c), decltype(a::d));")); + ASSERT_EQUALS("g{([= decltypea0[(", + testAst("auto g = [](decltype(a[0]) i) {};")); + ASSERT_EQUALS("g{([= decltypea0[(i&", + testAst("auto g = [](decltype(a[0])& i) {};")); ASSERT_NO_THROW(tokenizeAndStringify("struct A;\n" // #10839 "struct B { A* hash; };\n"