Skip to content

Commit 1d0ff1a

Browse files
Fix #14842 FN memleak in function with trailing return type (regression) (#8651)
Co-authored-by: chrchr-github <noreply@github.com>
1 parent 051584c commit 1d0ff1a

2 files changed

Lines changed: 44 additions & 2 deletions

File tree

lib/tokenize.cpp

Lines changed: 17 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7334,6 +7334,19 @@ void Tokenizer::simplifyVarDecl(const bool only_k_r_fpar)
73347334
simplifyVarDecl(list.front(), nullptr, only_k_r_fpar);
73357335
}
73367336

7337+
static Token* isTrailingReturnType(Token* tok)
7338+
{
7339+
while (Token::Match(tok, "%name%|::|>")) {
7340+
if (Token* open = tok->findOpeningBracket())
7341+
tok = open->tokAt(-1);
7342+
else
7343+
tok = tok->tokAt(-1);
7344+
}
7345+
if (tok && Token::simpleMatch(tok->tokAt(-1), ") ."))
7346+
return tok->tokAt(-1);
7347+
return nullptr;
7348+
}
7349+
73377350
// cppcheck-suppress functionConst - has side effects
73387351
void Tokenizer::simplifyVarDecl(Token * tokBegin, const Token * const tokEnd, const bool only_k_r_fpar)
73397352
{
@@ -7361,14 +7374,16 @@ void Tokenizer::simplifyVarDecl(Token * tokBegin, const Token * const tokEnd, co
73617374
if (!tok->linkAt(1))
73627375
syntaxError(tokBegin);
73637376
// Check for lambdas before skipping
7364-
if (Token::Match(tok->tokAt(-2), ") . %name%")) { // trailing return type
7377+
if (Token* trailingStart = isTrailingReturnType(tok)) {
73657378
// TODO: support lambda without parameter clause?
7366-
Token* lambdaStart = tok->linkAt(-2)->previous();
7379+
Token* lambdaStart = trailingStart->link()->tokAt(-1);
73677380
if (Token::simpleMatch(lambdaStart, "]"))
73687381
lambdaStart = lambdaStart->link();
73697382
Token* lambdaEnd = findLambdaEndScope(lambdaStart);
73707383
if (lambdaEnd)
73717384
simplifyVarDecl(lambdaEnd->link()->next(), lambdaEnd, only_k_r_fpar);
7385+
else
7386+
simplifyVarDecl(tok->tokAt(2), tok->linkAt(1), only_k_r_fpar);
73727387
} else {
73737388
for (Token* tok2 = tok->next(); tok2 != tok->linkAt(1); tok2 = tok2->next()) {
73747389
Token* lambdaEnd = findLambdaEndScope(tok2);

test/testtokenize.cpp

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -233,6 +233,7 @@ class TestTokenizer : public TestFixture {
233233
TEST_CASE(vardecl32);
234234
TEST_CASE(vardecl33);
235235
TEST_CASE(vardecl34);
236+
TEST_CASE(vardecl35);
236237
TEST_CASE(vardecl_stl_1);
237238
TEST_CASE(vardecl_stl_2);
238239
TEST_CASE(vardecl_stl_3);
@@ -2857,6 +2858,32 @@ class TestTokenizer : public TestFixture {
28572858
}
28582859
}
28592860

2861+
void vardecl35() { // #14842
2862+
{
2863+
const char code[] = "auto f() -> void {\n"
2864+
" auto p = new int;\n"
2865+
" *p = 0;\n"
2866+
"}\n";
2867+
ASSERT_EQUALS("auto f ( ) . void {\n"
2868+
"auto p ; p = new int ;\n"
2869+
"* p = 0 ;\n"
2870+
"}", tokenizeAndStringify(code));
2871+
ignore_errout();
2872+
}
2873+
{
2874+
const char code[] = "auto f() -> ::std::vector<int> {\n"
2875+
" int i = 0;\n"
2876+
" return { i };\n"
2877+
"}";
2878+
ASSERT_EQUALS("auto f ( ) . :: std :: vector < int > {\n"
2879+
"int i ; i = 0 ;\n"
2880+
"return { i } ;\n"
2881+
"}",
2882+
tokenizeAndStringify(code));
2883+
ignore_errout();
2884+
}
2885+
}
2886+
28602887
void volatile_variables() {
28612888
{
28622889
const char code[] = "volatile int a=0;\n"

0 commit comments

Comments
 (0)