Skip to content

Commit a57f98e

Browse files
committed
Fix #15008 internalAstError for
c++23 lambda
1 parent ab753cd commit a57f98e

4 files changed

Lines changed: 18 additions & 5 deletions

File tree

lib/astutils.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3304,12 +3304,12 @@ static T* findLambdaEndTokenGeneric(T* first)
33043304
return nullptr;
33053305
if (!maybeLambda(first->previous()))
33063306
return nullptr;
3307-
if (!Token::Match(first->link(), "] (|{|<"))
3307+
if (!Token::Match(first->link(), "] [({<.]"))
33083308
return nullptr;
33093309
const Token* roundOrCurly = first->link()->next();
33103310
if (roundOrCurly->link() && roundOrCurly->str() == "<")
33113311
roundOrCurly = roundOrCurly->link()->next();
3312-
if (first->astOperand1() != roundOrCurly)
3312+
if (first->astOperand1() != roundOrCurly && roundOrCurly->str() != ".")
33133313
return nullptr;
33143314
T * tok = first;
33153315

lib/tokenlist.cpp

Lines changed: 13 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1013,7 +1013,7 @@ static void compilePrecedence2(Token *&tok, AST_state& state)
10131013
else
10141014
compileUnaryOp(tok, state, compileScope);
10151015
} else if (tok->str() == "[") {
1016-
if (state.cpp && isPrefixUnary(tok, /*cpp*/ true) && Token::Match(tok->link(), "] (|{|<")) { // Lambda
1016+
if (state.cpp && isPrefixUnary(tok, /*cpp*/ true) && Token::Match(tok->link(), "] [({<.]")) { // Lambda
10171017
// What we do here:
10181018
// - Nest the round bracket under the square bracket.
10191019
// - Nest what follows the lambda (if anything) with the lambda opening [
@@ -1062,7 +1062,18 @@ static void compilePrecedence2(Token *&tok, AST_state& state)
10621062
continue;
10631063
}
10641064
} else {
1065-
Token* const curlyBracket = squareBracket->link()->next();
1065+
Token* curlyBracket = squareBracket->link()->next();
1066+
if (Token::simpleMatch(curlyBracket, ".")) { // trailing return type
1067+
curlyBracket = curlyBracket->next();
1068+
while (Token::Match(curlyBracket, "%type%|%name%|::|&|&&|*|<|(")) {
1069+
if (curlyBracket->link())
1070+
curlyBracket = curlyBracket->link()->next();
1071+
else
1072+
curlyBracket = curlyBracket->next();
1073+
}
1074+
}
1075+
if (!Token::simpleMatch(curlyBracket, "{"))
1076+
throw InternalError(tok, "Syntax error in lambda", InternalError::AST);
10661077
squareBracket->astOperand1(curlyBracket);
10671078
state.op.push(squareBracket);
10681079
tok = curlyBracket->link() ? curlyBracket->link()->next() : nullptr;

test/testtokenize.cpp

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7632,6 +7632,8 @@ class TestTokenizer : public TestFixture {
76327632
ASSERT_EQUALS("sf.{(i[{={", testAst("void g(int i) { S s{ .f = { [i]() {} } }; }\n"));
76337633

76347634
ASSERT_EQUALS("{([", testAst("void f() { []() {}; }\n")); // #13471
7635+
7636+
ASSERT_EQUALS("x{=[= 0return", testAst("void f() { auto x = [=] -> int { return 0; }; }\n")); // #15008
76357637
}
76367638

76377639
void astcase() {

test/testvalueflow.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8097,7 +8097,7 @@ class TestValueFlow : public TestFixture {
80978097
code = "void f(int& r) {\n" // #13515
80988098
" [0].p = &r;\n"
80998099
"}\n";
8100-
(void)valueOfTok(code, "=");
8100+
ASSERT_THROW_INTERNAL(valueOfTok(code, "="), AST);
81018101
}
81028102

81038103
void valueFlowCrash() {

0 commit comments

Comments
 (0)