Fix 10408: FP nullPointer on 'return x.release()' (#3404)

This commit is contained in:
Paul Fultz II 2021-08-15 00:43:50 -05:00 committed by GitHub
parent 422e411b6c
commit f81ddd2daa
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 17 additions and 2 deletions

View File

@ -4245,6 +4245,8 @@ static void valueFlowForwardAssign(Token* const tok,
ErrorLogger* const errorLogger,
const Settings* const settings)
{
if (Token::simpleMatch(tok->astParent(), "return"))
return;
const Token* endOfVarScope = getEndOfVarScope(tok, vars);
if (std::any_of(values.begin(), values.end(), std::mem_fn(&ValueFlow::Value::isLifetimeValue))) {
valueFlowForwardLifetime(tok, tokenlist, errorLogger, settings);
@ -6390,7 +6392,7 @@ static void valueFlowSmartPointer(TokenList *tokenlist, ErrorLogger * errorLogge
ValueFlow::Value v(0);
v.setKnown();
values.push_back(v);
valueFlowForwardAssign(tok->tokAt(4), var, values, false, false, tokenlist, errorLogger, settings);
valueFlowForwardAssign(tok->tokAt(3), var, values, false, false, tokenlist, errorLogger, settings);
} else {
tok->removeValues(std::mem_fn(&ValueFlow::Value::isIntValue));
Token* inTok = tok->tokAt(3)->astOperand2();
@ -6405,7 +6407,7 @@ static void valueFlowSmartPointer(TokenList *tokenlist, ErrorLogger * errorLogge
ValueFlow::Value v(0);
v.setKnown();
values.push_back(v);
valueFlowForwardAssign(tok->tokAt(4), var, values, false, false, tokenlist, errorLogger, settings);
valueFlowForwardAssign(tok->tokAt(3), var, values, false, false, tokenlist, errorLogger, settings);
}
} else if (Token::Match(tok->previous(), "%name%|> (|{") && astIsSmartPointer(tok) &&
astIsSmartPointer(tok->astOperand1())) {

View File

@ -115,6 +115,7 @@ private:
TEST_CASE(nullpointer73); // #10321
TEST_CASE(nullpointer74);
TEST_CASE(nullpointer75);
TEST_CASE(nullpointer76); // #10408
TEST_CASE(nullpointer_addressOf); // address of
TEST_CASE(nullpointerSwitch); // #2626
TEST_CASE(nullpointer_cast); // #4692
@ -2364,6 +2365,18 @@ private:
ASSERT_EQUALS("", errout.str());
}
void nullpointer76()
{
check("int* foo(int y) {\n"
" std::unique_ptr<int> x = std::make_unique<int>(0);\n"
" if( y == 0 )\n"
" return x.release();\n"
" (*x) ++;\n"
" return x.release();\n"
"}\n");
ASSERT_EQUALS("", errout.str());
}
void nullpointer_addressOf() { // address of
check("void f() {\n"
" struct X *x = 0;\n"