Fix issue 9751: Wrong lifetime caused by std::function (#2676)

This commit is contained in:
Paul Fultz II 2020-06-13 03:26:54 -05:00 committed by GitHub
parent 03b41ac987
commit 06ed088bd0
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 23 additions and 2 deletions

View File

@ -47,7 +47,7 @@ struct ForwardTraversal {
if (checkScope(lambdaEndToken).isModified()) if (checkScope(lambdaEndToken).isModified())
return Progress::Break; return Progress::Break;
if (out) if (out)
*out = lambdaEndToken; *out = lambdaEndToken->next();
// Skip class scope // Skip class scope
} else if (tok->str() == "{" && tok->scope() && tok->scope()->isClassOrStruct()) { } else if (tok->str() == "{" && tok->scope() && tok->scope()->isClassOrStruct()) {
if (out) if (out)
@ -291,6 +291,9 @@ struct ForwardTraversal {
if (!analyzer->lowerToPossible()) if (!analyzer->lowerToPossible())
return Progress::Break; return Progress::Break;
} else if (tok->link() && tok->str() == "}") { } else if (tok->link() && tok->str() == "}") {
const Scope* scope = tok->scope();
if(!scope)
return Progress::Break;
if (Token::Match(tok->link()->previous(), ")|else {")) { if (Token::Match(tok->link()->previous(), ")|else {")) {
const bool inElse = Token::simpleMatch(tok->link()->previous(), "else {"); const bool inElse = Token::simpleMatch(tok->link()->previous(), "else {");
const Token* condTok = getCondTokFromEnd(tok); const Token* condTok = getCondTokFromEnd(tok);
@ -305,9 +308,11 @@ struct ForwardTraversal {
analyzer->assume(condTok, !inElse, tok); analyzer->assume(condTok, !inElse, tok);
if (Token::simpleMatch(tok, "} else {")) if (Token::simpleMatch(tok, "} else {"))
tok = tok->linkAt(2); tok = tok->linkAt(2);
} else if (Token::simpleMatch(tok->link()->previous(), "try {")) { } else if (scope->type == Scope::eTry) {
if (!analyzer->lowerToPossible()) if (!analyzer->lowerToPossible())
return Progress::Break; return Progress::Break;
} else if (scope->type == Scope::eLambda) {
return Progress::Break;
} else if (Token::simpleMatch(tok->next(), "else {")) { } else if (Token::simpleMatch(tok->next(), "else {")) {
tok = tok->linkAt(2); tok = tok->linkAt(2);
} }

View File

@ -97,6 +97,7 @@ private:
TEST_CASE(nullpointer54); // #9573 TEST_CASE(nullpointer54); // #9573
TEST_CASE(nullpointer55); // #8144 TEST_CASE(nullpointer55); // #8144
TEST_CASE(nullpointer56); // #9701 TEST_CASE(nullpointer56); // #9701
TEST_CASE(nullpointer57); // #9751
TEST_CASE(nullpointer_addressOf); // address of TEST_CASE(nullpointer_addressOf); // address of
TEST_CASE(nullpointerSwitch); // #2626 TEST_CASE(nullpointerSwitch); // #2626
TEST_CASE(nullpointer_cast); // #4692 TEST_CASE(nullpointer_cast); // #4692
@ -1824,6 +1825,21 @@ private:
ASSERT_EQUALS("", errout.str()); ASSERT_EQUALS("", errout.str());
} }
void nullpointer57() {
check("void f() {\n"
" FILE* fptr = fopen(\"test\", \"r\");\n"
" if (fptr != nullptr) {\n"
" std::function<void()> 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 void nullpointer_addressOf() { // address of
check("void f() {\n" check("void f() {\n"
" struct X *x = 0;\n" " struct X *x = 0;\n"