From 7e0f64688f9d02d526864e7977bc78bbcdaf2f43 Mon Sep 17 00:00:00 2001 From: chrchr-github <78114321+chrchr-github@users.noreply.github.com> Date: Sat, 10 Jun 2023 07:42:10 +0200 Subject: [PATCH] Fix #11275 internalAstError on C++20 templated lambda / Fix #11400 internalAstError on nested lambda (#5134) * Fix #11275 internalAstError on C++20 templated lambda * Fix #11400 internalAstError on nested lambda passed as argument --- lib/tokenize.cpp | 3 ++- lib/tokenlist.cpp | 8 +++++--- test/testtokenize.cpp | 20 ++++++++++++++++++++ 3 files changed, 27 insertions(+), 4 deletions(-) diff --git a/lib/tokenize.cpp b/lib/tokenize.cpp index cd11989de..b0fc121dd 100644 --- a/lib/tokenize.cpp +++ b/lib/tokenize.cpp @@ -5247,7 +5247,8 @@ void Tokenizer::createLinks2() } } else if (token->str() == "<" && ((token->previous() && (token->previous()->isTemplate() || - (token->previous()->isName() && !token->previous()->varId()))) || + (token->previous()->isName() && !token->previous()->varId()) || + token->strAt(-1) == "]")) || Token::Match(token->next(), ">|>>"))) { type.push(token); if (token->previous()->str() == "template") diff --git a/lib/tokenlist.cpp b/lib/tokenlist.cpp index f7e79170c..737065498 100644 --- a/lib/tokenlist.cpp +++ b/lib/tokenlist.cpp @@ -1750,11 +1750,13 @@ void TokenList::validateAst() const continue; } + if (const Token* lambdaEnd = findLambdaEndToken(tok)) { // skip lambda captures + tok = tok->link(); + continue; + } + // Check binary operators if (Token::Match(tok, "%or%|%oror%|%assign%|%comp%")) { - // Skip lambda captures - if (Token::Match(tok, "= ,|]")) - continue; // Skip pure virtual functions if (Token::simpleMatch(tok->previous(), ") = 0")) continue; diff --git a/test/testtokenize.cpp b/test/testtokenize.cpp index 4a3829ba1..af455a0cf 100644 --- a/test/testtokenize.cpp +++ b/test/testtokenize.cpp @@ -3489,6 +3489,20 @@ private: ASSERT_EQUALS(true, tok1->link() == tok2); ASSERT_EQUALS(true, tok2->link() == tok1); } + + { // #11275 + const char code[] = "void f() {\n" + " []() {};\n" + "}\n"; + errout.str(""); + Tokenizer tokenizer(&settings0, this); + std::istringstream istr(code); + ASSERT(tokenizer.tokenize(istr, "test.cpp")); + const Token* tok1 = Token::findsimplematch(tokenizer.tokens(), "< T"); + const Token* tok2 = Token::findsimplematch(tok1, "> ("); + ASSERT_EQUALS(true, tok1->link() == tok2); + ASSERT_EQUALS(true, tok2->link() == tok1); + } } void simplifyString() { @@ -7269,6 +7283,12 @@ private: " a bar;\n" " (decltype(bar.b)::value_type){};\n" "}\n")); + + ASSERT_NO_THROW(tokenizeAndStringify("struct S { char c{}; };\n" // #11400 + "void takesFunc(auto f) {}\n" + "int main() { \n" + " takesFunc([func = [](S s) { return s.c; }] {});\n" + "}\n")); } void checkIfCppCast() { ASSERT_NO_THROW(tokenizeAndStringify("struct a {\n"