Fix 10210: FN: nullPointerRedundantCheck regression in member function (#3512)
This commit is contained in:
parent
f1f86db0da
commit
130d1abbce
|
@ -2291,7 +2291,8 @@ bool isVariablesChanged(const Token* start,
|
||||||
|
|
||||||
bool isThisChanged(const Token* tok, int indirect, const Settings* settings, bool cpp)
|
bool isThisChanged(const Token* tok, int indirect, const Settings* settings, bool cpp)
|
||||||
{
|
{
|
||||||
if (Token::Match(tok->previous(), "%name% (")) {
|
if ((Token::Match(tok->previous(), "%name% (") && !Token::simpleMatch(tok->astOperand1(), ".")) ||
|
||||||
|
Token::Match(tok->tokAt(-3), "this . %name% (")) {
|
||||||
if (tok->previous()->function()) {
|
if (tok->previous()->function()) {
|
||||||
return (!tok->previous()->function()->isConst());
|
return (!tok->previous()->function()->isConst());
|
||||||
} else if (!tok->previous()->isKeyword()) {
|
} else if (!tok->previous()->isKeyword()) {
|
||||||
|
|
|
@ -2333,7 +2333,8 @@ struct ValueFlowAnalyzer : Analyzer {
|
||||||
return isThisModified(tok);
|
return isThisModified(tok);
|
||||||
|
|
||||||
// bailout: global non-const variables
|
// bailout: global non-const variables
|
||||||
if (isGlobal() && Token::Match(tok, "%name% (") && !Token::simpleMatch(tok->linkAt(1), ") {")) {
|
if (isGlobal() && !dependsOnThis() && Token::Match(tok, "%name% (") &&
|
||||||
|
!Token::simpleMatch(tok->linkAt(1), ") {")) {
|
||||||
if (tok->function()) {
|
if (tok->function()) {
|
||||||
if (!tok->function()->isConstexpr() && !isConstFunctionCall(tok, getSettings()->library))
|
if (!tok->function()->isConstexpr() && !isConstFunctionCall(tok, getSettings()->library))
|
||||||
return Action::Invalid;
|
return Action::Invalid;
|
||||||
|
|
|
@ -124,6 +124,7 @@ private:
|
||||||
TEST_CASE(nullpointer82); // #10331
|
TEST_CASE(nullpointer82); // #10331
|
||||||
TEST_CASE(nullpointer83); // #9870
|
TEST_CASE(nullpointer83); // #9870
|
||||||
TEST_CASE(nullpointer84); // #9873
|
TEST_CASE(nullpointer84); // #9873
|
||||||
|
TEST_CASE(nullpointer85); // #10210
|
||||||
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
|
||||||
|
@ -2525,6 +2526,27 @@ private:
|
||||||
errout.str());
|
errout.str());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void nullpointer85() // #10210
|
||||||
|
{
|
||||||
|
check("struct MyStruct {\n"
|
||||||
|
" int GetId() const {\n"
|
||||||
|
" int id = 0;\n"
|
||||||
|
" int page = m_notebook->GetSelection();\n"
|
||||||
|
" if (m_notebook && (m_notebook->GetPageCount() > 0))\n"
|
||||||
|
" id = page;\n"
|
||||||
|
" return id;\n"
|
||||||
|
" }\n"
|
||||||
|
" wxNoteBook *m_notebook = nullptr;\n"
|
||||||
|
"};\n"
|
||||||
|
"int f() {\n"
|
||||||
|
" const MyStruct &s = Get();\n"
|
||||||
|
" return s.GetId();\n"
|
||||||
|
"}\n");
|
||||||
|
ASSERT_EQUALS(
|
||||||
|
"[test.cpp:5] -> [test.cpp:4]: (warning) Either the condition 'm_notebook' is redundant or there is possible null pointer dereference: m_notebook.\n",
|
||||||
|
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"
|
||||||
|
|
Loading…
Reference in New Issue