From 23068673d453e96f69845da0deb2864bad200201 Mon Sep 17 00:00:00 2001 From: Paul Date: Wed, 10 Jun 2020 22:02:55 -0500 Subject: [PATCH] Fix issue 9751: Wrong lifetime caused by std::function --- lib/forwardanalyzer.cpp | 9 +++++++-- test/testnullpointer.cpp | 16 ++++++++++++++++ 2 files changed, 23 insertions(+), 2 deletions(-) diff --git a/lib/forwardanalyzer.cpp b/lib/forwardanalyzer.cpp index 8873687a10a..62334a3de95 100644 --- a/lib/forwardanalyzer.cpp +++ b/lib/forwardanalyzer.cpp @@ -47,7 +47,7 @@ struct ForwardTraversal { if (checkScope(lambdaEndToken).isModified()) return Progress::Break; if (out) - *out = lambdaEndToken; + *out = lambdaEndToken->next(); // Skip class scope } else if (tok->str() == "{" && tok->scope() && tok->scope()->isClassOrStruct()) { if (out) @@ -291,6 +291,9 @@ struct ForwardTraversal { if (!analyzer->lowerToPossible()) return Progress::Break; } else if (tok->link() && tok->str() == "}") { + const Scope* scope = tok->scope(); + if(!scope) + return Progress::Break; if (Token::Match(tok->link()->previous(), ")|else {")) { const bool inElse = Token::simpleMatch(tok->link()->previous(), "else {"); const Token* condTok = getCondTokFromEnd(tok); @@ -305,9 +308,11 @@ struct ForwardTraversal { analyzer->assume(condTok, !inElse, tok); if (Token::simpleMatch(tok, "} else {")) tok = tok->linkAt(2); - } else if (Token::simpleMatch(tok->link()->previous(), "try {")) { + } else if (scope->type == Scope::eTry) { if (!analyzer->lowerToPossible()) return Progress::Break; + } else if (scope->type == Scope::eLambda) { + return Progress::Break; } else if (Token::simpleMatch(tok->next(), "else {")) { tok = tok->linkAt(2); } diff --git a/test/testnullpointer.cpp b/test/testnullpointer.cpp index af63c3f1bcd..a6f4961278c 100644 --- a/test/testnullpointer.cpp +++ b/test/testnullpointer.cpp @@ -97,6 +97,7 @@ class TestNullPointer : public TestFixture { TEST_CASE(nullpointer54); // #9573 TEST_CASE(nullpointer55); // #8144 TEST_CASE(nullpointer56); // #9701 + TEST_CASE(nullpointer57); // #9751 TEST_CASE(nullpointer_addressOf); // address of TEST_CASE(nullpointerSwitch); // #2626 TEST_CASE(nullpointer_cast); // #4692 @@ -1824,6 +1825,21 @@ class TestNullPointer : public TestFixture { ASSERT_EQUALS("", errout.str()); } + void nullpointer57() { + check("void f() {\n" + " FILE* fptr = fopen(\"test\", \"r\");\n" + " if (fptr != nullptr) {\n" + " std::function fn([&] {\n" + " fclose(fptr);\n" + " fptr = NULL;\n" + " });\n" + " fgetc(fptr);\n" + " fn();\n" + " }\n" + "}\n"); + ASSERT_EQUALS("", errout.str()); + } + void nullpointer_addressOf() { // address of check("void f() {\n" " struct X *x = 0;\n"