Fix spurious lambda detection (#5101)

This commit is contained in:
chrchr-github 2023-05-31 20:55:39 +02:00 committed by GitHub
parent a91222fad8
commit 0b44429a7c
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 26 additions and 4 deletions

View File

@ -2948,8 +2948,25 @@ const Token *findLambdaStartToken(const Token *last)
template<class T>
T* findLambdaEndTokenGeneric(T* first)
{
auto maybeLambda = [](T* tok) -> bool {
while (Token::Match(tok, "*|%name%|::|>")) {
if (tok->link())
tok = tok->link()->previous();
else {
if (tok->str() == ">")
return true;
if (tok->str() == "new")
return false;
tok = tok->previous();
}
}
return true;
};
if (!first || first->str() != "[")
return nullptr;
if (!maybeLambda(first->previous()))
return nullptr;
if (!Token::Match(first->link(), "] (|{"))
return nullptr;
if (first->astOperand1() != first->link()->next())

View File

@ -48,14 +48,15 @@ private:
TEST_CASE(isUsedAsBool);
}
#define findLambdaEndToken(code) findLambdaEndToken_(code, __FILE__, __LINE__)
bool findLambdaEndToken_(const char code[], const char* file, int line) {
#define findLambdaEndToken(...) findLambdaEndToken_(__FILE__, __LINE__, __VA_ARGS__)
bool findLambdaEndToken_(const char* file, int line, const char code[], const char pattern[] = nullptr, bool checkNext = true) {
const Settings settings;
Tokenizer tokenizer(&settings, this);
std::istringstream istr(code);
ASSERT_LOC(tokenizer.tokenize(istr, "test.cpp"), file, line);
const Token * const tokEnd = (::findLambdaEndToken)(tokenizer.tokens());
return tokEnd && tokEnd->next() == nullptr;
const Token* const tokStart = pattern ? Token::findsimplematch(tokenizer.tokens(), pattern, strlen(pattern)) : tokenizer.tokens();
const Token * const tokEnd = (::findLambdaEndToken)(tokStart);
return tokEnd && (!checkNext || tokEnd->next() == nullptr);
}
void findLambdaEndTokenTest() {
@ -80,6 +81,10 @@ private:
ASSERT_EQUALS(true, findLambdaEndToken("[](void) mutable -> const * int { return x; }"));
ASSERT_EQUALS(true, findLambdaEndToken("[](void) constexpr -> const ** int { return x; }"));
ASSERT_EQUALS(true, findLambdaEndToken("[](void) constexpr -> const * const* int { return x; }"));
ASSERT_EQUALS(false, findLambdaEndToken("int** a[] { new int*[2] { new int, new int} }", "[ ]"));
ASSERT_EQUALS(false, findLambdaEndToken("int** a[] { new int*[2] { new int, new int} }", "[ 2"));
ASSERT_EQUALS(false, findLambdaEndToken("shared_ptr<Type *[]> sp{ new Type *[2] {new Type, new Type}, Deleter<Type>{ 2 } };", "[ 2"));
ASSERT_EQUALS(true, findLambdaEndToken("int i = 5 * []{ return 7; }();", "[", /*checkNext*/ false));
}
#define findLambdaStartToken(code) findLambdaStartToken_(code, __FILE__, __LINE__)