Skip to content

Commit 06ed088

Browse files
authored
Fix issue 9751: Wrong lifetime caused by std::function (#2676)
1 parent 03b41ac commit 06ed088

2 files changed

Lines changed: 23 additions & 2 deletions

File tree

lib/forwardanalyzer.cpp

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -47,7 +47,7 @@ struct ForwardTraversal {
4747
if (checkScope(lambdaEndToken).isModified())
4848
return Progress::Break;
4949
if (out)
50-
*out = lambdaEndToken;
50+
*out = lambdaEndToken->next();
5151
// Skip class scope
5252
} else if (tok->str() == "{" && tok->scope() && tok->scope()->isClassOrStruct()) {
5353
if (out)
@@ -291,6 +291,9 @@ struct ForwardTraversal {
291291
if (!analyzer->lowerToPossible())
292292
return Progress::Break;
293293
} else if (tok->link() && tok->str() == "}") {
294+
const Scope* scope = tok->scope();
295+
if(!scope)
296+
return Progress::Break;
294297
if (Token::Match(tok->link()->previous(), ")|else {")) {
295298
const bool inElse = Token::simpleMatch(tok->link()->previous(), "else {");
296299
const Token* condTok = getCondTokFromEnd(tok);
@@ -305,9 +308,11 @@ struct ForwardTraversal {
305308
analyzer->assume(condTok, !inElse, tok);
306309
if (Token::simpleMatch(tok, "} else {"))
307310
tok = tok->linkAt(2);
308-
} else if (Token::simpleMatch(tok->link()->previous(), "try {")) {
311+
} else if (scope->type == Scope::eTry) {
309312
if (!analyzer->lowerToPossible())
310313
return Progress::Break;
314+
} else if (scope->type == Scope::eLambda) {
315+
return Progress::Break;
311316
} else if (Token::simpleMatch(tok->next(), "else {")) {
312317
tok = tok->linkAt(2);
313318
}

test/testnullpointer.cpp

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -97,6 +97,7 @@ class TestNullPointer : public TestFixture {
9797
TEST_CASE(nullpointer54); // #9573
9898
TEST_CASE(nullpointer55); // #8144
9999
TEST_CASE(nullpointer56); // #9701
100+
TEST_CASE(nullpointer57); // #9751
100101
TEST_CASE(nullpointer_addressOf); // address of
101102
TEST_CASE(nullpointerSwitch); // #2626
102103
TEST_CASE(nullpointer_cast); // #4692
@@ -1824,6 +1825,21 @@ class TestNullPointer : public TestFixture {
18241825
ASSERT_EQUALS("", errout.str());
18251826
}
18261827

1828+
void nullpointer57() {
1829+
check("void f() {\n"
1830+
" FILE* fptr = fopen(\"test\", \"r\");\n"
1831+
" if (fptr != nullptr) {\n"
1832+
" std::function<void()> fn([&] {\n"
1833+
" fclose(fptr);\n"
1834+
" fptr = NULL;\n"
1835+
" });\n"
1836+
" fgetc(fptr);\n"
1837+
" fn();\n"
1838+
" }\n"
1839+
"}\n");
1840+
ASSERT_EQUALS("", errout.str());
1841+
}
1842+
18271843
void nullpointer_addressOf() { // address of
18281844
check("void f() {\n"
18291845
" struct X *x = 0;\n"

0 commit comments

Comments
 (0)