diff --git a/lib/checknullpointer.cpp b/lib/checknullpointer.cpp index 698476b12..5f31ff60e 100644 --- a/lib/checknullpointer.cpp +++ b/lib/checknullpointer.cpp @@ -350,8 +350,19 @@ void CheckNullPointer::nullPointerStructByDeRefAndChec() continue; } + /** + * @todo There are lots of false negatives here. A dereference + * is only investigated if a few specific conditions are met. + */ + // dereference in assignment - if (Token::Match(tok1, "[{};] %var% = %var% . %var%")) + if (Token::Match(tok1, "[;{}] %var% . %var%")) + { + tok1 = tok1->next(); + } + + // dereference in assignment + else if (Token::Match(tok1, "[{};] %var% = %var% . %var%")) { if (std::string(tok1->strAt(1)) == tok1->strAt(3)) continue; diff --git a/test/testnullpointer.cpp b/test/testnullpointer.cpp index 82f108fac..e106577c2 100644 --- a/test/testnullpointer.cpp +++ b/test/testnullpointer.cpp @@ -193,13 +193,27 @@ private: "}\n"); ASSERT_EQUALS("[test.cpp:3]: (error) Possible null pointer dereference: abc - otherwise it is redundant to check if abc is null at line 4\n", errout.str()); - check("void foo(struct ABC *abc)\n" - "{\n" + check("void foo(struct ABC *abc) {\n" " bar(abc->a);\n" " if (!abc)\n" " ;\n" "}\n"); - ASSERT_EQUALS("[test.cpp:3]: (error) Possible null pointer dereference: abc - otherwise it is redundant to check if abc is null at line 4\n", errout.str()); + ASSERT_EQUALS("[test.cpp:2]: (error) Possible null pointer dereference: abc - otherwise it is redundant to check if abc is null at line 3\n", errout.str()); + + check("void foo(ABC *abc) {\n" + " abc->do_something();\n" + " if (abc)\n" + " ;\n" + "}\n"); + ASSERT_EQUALS("[test.cpp:2]: (error) Possible null pointer dereference: abc - otherwise it is redundant to check if abc is null at line 3\n", errout.str()); + + // TODO: False negative if member of member is dereferenced + check("void foo(ABC *abc) {\n" + " abc->next->a = 0;\n" + " if (abc->next)\n" + " ;\n" + "}\n"); + TODO_ASSERT_EQUALS("[test.cpp:2]: (error) Possible null pointer dereference: abc - otherwise it is redundant to check if abc is null at line 3\n", "", errout.str()); // ok dereferencing in a condition check("void foo(struct ABC *abc)\n"