Skip to content

Commit 88008fe

Browse files
rikardfalkeborndanmar
authored andcommitted
findLambdaEndToken handle explicit type (cppcheck-opensource#1458)
* findLambdaEndToken: Add tests * Add handling of explicit return in findLambdaEndToken() * Use AST in findLambdaEndToken() * Fix ast when lambda is mutable
1 parent fafd074 commit 88008fe

5 files changed

Lines changed: 43 additions & 13 deletions

File tree

lib/astutils.cpp

Lines changed: 6 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -939,18 +939,12 @@ const Token *findLambdaEndToken(const Token *first)
939939
{
940940
if (!first || first->str() != "[")
941941
return nullptr;
942-
const Token* tok = first->link();
943-
if (Token::simpleMatch(tok, "] {"))
944-
return tok->linkAt(1);
945-
if (!Token::simpleMatch(tok, "] ("))
946-
return nullptr;
947-
tok = tok->linkAt(1)->next();
948-
if (tok && tok->str() == "constexpr")
949-
tok = tok->next();
950-
if (tok && tok->str() == "mutable")
951-
tok = tok->next();
952-
if (tok && tok->str() == "{")
953-
return tok->link();
942+
const Token * tok = first;
943+
944+
if (tok->astOperand1() && tok->astOperand1()->str() == "(")
945+
tok = tok->astOperand1();
946+
if (tok->astOperand1() && tok->astOperand1()->str() == "{")
947+
return tok->astOperand1()->link();
954948
return nullptr;
955949
}
956950

lib/astutils.h

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -126,7 +126,6 @@ std::vector<const Token *> getArguments(const Token *ftok);
126126

127127
/**
128128
* find lambda function end token
129-
* \todo handle explicit return type
130129
* \param first The [ token
131130
* \return nullptr or the }
132131
*/

lib/tokenlist.cpp

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -680,6 +680,8 @@ static void compilePrecedence2(Token *&tok, AST_state& state)
680680
if (Token::simpleMatch(squareBracket->link(), "] (")) {
681681
Token* const roundBracket = squareBracket->link()->next();
682682
Token* curlyBracket = roundBracket->link()->next();
683+
if (curlyBracket && curlyBracket->str() == "mutable")
684+
curlyBracket = curlyBracket->next();
683685
if (curlyBracket && curlyBracket->originalName() == "->") {
684686
while (Token::Match(curlyBracket, "%name%|.|::|&|*"))
685687
curlyBracket = curlyBracket->next();

test/testastutils.cpp

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,11 +33,44 @@ class TestAstUtils : public TestFixture {
3333
private:
3434

3535
void run() override {
36+
TEST_CASE(findLambdaEndToken);
3637
TEST_CASE(isReturnScope);
3738
TEST_CASE(isVariableChanged);
3839
TEST_CASE(isVariableChangedByFunctionCall);
3940
}
4041

42+
bool findLambdaEndToken(const char code[]) {
43+
Settings settings;
44+
Tokenizer tokenizer(&settings, this);
45+
std::istringstream istr(code);
46+
tokenizer.tokenize(istr, "test.cpp");
47+
const Token * const tokEnd = ::findLambdaEndToken(tokenizer.tokens());
48+
return tokEnd && tokEnd->next() == nullptr;
49+
}
50+
51+
void findLambdaEndToken() {
52+
ASSERT(nullptr == ::findLambdaEndToken(nullptr));
53+
ASSERT_EQUALS(false, findLambdaEndToken("void f() { }"));
54+
ASSERT_EQUALS(true, findLambdaEndToken("[]{ }"));
55+
ASSERT_EQUALS(true, findLambdaEndToken("[]{ return 0 }"));
56+
ASSERT_EQUALS(true, findLambdaEndToken("[](){ }"));
57+
ASSERT_EQUALS(true, findLambdaEndToken("[&](){ }"));
58+
ASSERT_EQUALS(true, findLambdaEndToken("[&, i](){ }"));
59+
ASSERT_EQUALS(true, findLambdaEndToken("[](void) { return -1 }"));
60+
ASSERT_EQUALS(true, findLambdaEndToken("[](int a, int b) { return a + b }"));
61+
ASSERT_EQUALS(true, findLambdaEndToken("[](int a, int b) mutable { return a + b }"));
62+
ASSERT_EQUALS(true, findLambdaEndToken("[](int a, int b) constexpr { return a + b }"));
63+
ASSERT_EQUALS(true, findLambdaEndToken("[](void) -> int { return -1 }"));
64+
ASSERT_EQUALS(true, findLambdaEndToken("[](void) mutable -> int { return -1 }"));
65+
ASSERT_EQUALS(false, findLambdaEndToken("[](void) foo -> int { return -1 }"));
66+
ASSERT_EQUALS(true, findLambdaEndToken("[](void) constexpr -> int { return -1 }"));
67+
ASSERT_EQUALS(true, findLambdaEndToken("[](void) constexpr -> int* { return x }"));
68+
ASSERT_EQUALS(true, findLambdaEndToken("[](void) constexpr -> const * int { return x }"));
69+
ASSERT_EQUALS(true, findLambdaEndToken("[](void) mutable -> const * int { return x }"));
70+
ASSERT_EQUALS(true, findLambdaEndToken("[](void) constexpr -> const ** int { return x }"));
71+
ASSERT_EQUALS(true, findLambdaEndToken("[](void) constexpr -> const * const* int { return x }"));
72+
}
73+
4174
bool isReturnScope(const char code[], int offset) {
4275
Settings settings;
4376
Tokenizer tokenizer(&settings, this);

test/testtokenize.cpp

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8551,6 +8551,8 @@ class TestTokenizer : public TestFixture {
85518551
ASSERT_EQUALS("{([cd,(return 0return", testAst("return [](int a, int b) -> int { return 0; }(c, d);"));
85528552
ASSERT_EQUALS("x{([=", testAst("x = [&]()->std::string const & {};"));
85538553
ASSERT_EQUALS("f{([=", testAst("f = []() -> foo* {};"));
8554+
ASSERT_EQUALS("f{([=", testAst("f = [](void) mutable -> foo* {};"));
8555+
ASSERT_EQUALS("f{([=", testAst("f = []() mutable {};"));
85548556

85558557
ASSERT_EQUALS("x{([= 0return", testAst("x = [](){return 0; };"));
85568558

0 commit comments

Comments
 (0)