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
This commit is contained in:
chrchr-github 2023-06-10 07:42:10 +02:00 committed by GitHub
parent d4705ca8ab
commit 7e0f64688f
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 27 additions and 4 deletions

View File

@ -5247,7 +5247,8 @@ void Tokenizer::createLinks2()
} }
} else if (token->str() == "<" && } else if (token->str() == "<" &&
((token->previous() && (token->previous()->isTemplate() || ((token->previous() && (token->previous()->isTemplate() ||
(token->previous()->isName() && !token->previous()->varId()))) || (token->previous()->isName() && !token->previous()->varId()) ||
token->strAt(-1) == "]")) ||
Token::Match(token->next(), ">|>>"))) { Token::Match(token->next(), ">|>>"))) {
type.push(token); type.push(token);
if (token->previous()->str() == "template") if (token->previous()->str() == "template")

View File

@ -1750,11 +1750,13 @@ void TokenList::validateAst() const
continue; continue;
} }
if (const Token* lambdaEnd = findLambdaEndToken(tok)) { // skip lambda captures
tok = tok->link();
continue;
}
// Check binary operators // Check binary operators
if (Token::Match(tok, "%or%|%oror%|%assign%|%comp%")) { if (Token::Match(tok, "%or%|%oror%|%assign%|%comp%")) {
// Skip lambda captures
if (Token::Match(tok, "= ,|]"))
continue;
// Skip pure virtual functions // Skip pure virtual functions
if (Token::simpleMatch(tok->previous(), ") = 0")) if (Token::simpleMatch(tok->previous(), ") = 0"))
continue; continue;

View File

@ -3489,6 +3489,20 @@ private:
ASSERT_EQUALS(true, tok1->link() == tok2); ASSERT_EQUALS(true, tok1->link() == tok2);
ASSERT_EQUALS(true, tok2->link() == tok1); ASSERT_EQUALS(true, tok2->link() == tok1);
} }
{ // #11275
const char code[] = "void f() {\n"
" []<typename T>() {};\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() { void simplifyString() {
@ -7269,6 +7283,12 @@ private:
" a bar;\n" " a bar;\n"
" (decltype(bar.b)::value_type){};\n" " (decltype(bar.b)::value_type){};\n"
"}\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() { void checkIfCppCast() {
ASSERT_NO_THROW(tokenizeAndStringify("struct a {\n" ASSERT_NO_THROW(tokenizeAndStringify("struct a {\n"