diff --git a/lib/checknullpointer.cpp b/lib/checknullpointer.cpp index 3c3c3be1f..e3cbb9cac 100644 --- a/lib/checknullpointer.cpp +++ b/lib/checknullpointer.cpp @@ -1369,7 +1369,7 @@ private: /** parse condition. @sa ExecutionPath::parseCondition */ bool parseCondition(const Token &tok, std::list &checks) { for (const Token *tok2 = &tok; tok2; tok2 = tok2->next()) { - if (tok2->str() == "(" || tok2->str() == ")" || tok2->str() == "&&" || tok2->str() == "||") + if (tok2->str() == "(" || tok2->str() == ")" || tok2->str() == "&&" || tok2->str() == "||" || tok2->str() == "?") break; bool unknown = owner->inconclusiveFlag(); if (tok2->varId() && (CheckNullPointer::isPointerDeRef(tok2, unknown, symbolDatabase) || unknown)) diff --git a/test/testnullpointer.cpp b/test/testnullpointer.cpp index 89d0057cc..601b9fae3 100644 --- a/test/testnullpointer.cpp +++ b/test/testnullpointer.cpp @@ -53,6 +53,7 @@ private: TEST_CASE(nullpointer17); // #3567 TEST_CASE(nullpointer18); // #1927 TEST_CASE(nullpointer19); // #3811 + TEST_CASE(nullpointer20); // #3807 (fp: return p ? (p->x() || p->y()) : z) TEST_CASE(nullpointer_castToVoid); // #3771 TEST_CASE(pointerCheckAndDeRef); // check if pointer is null and then dereference it TEST_CASE(nullConstantDereference); // Dereference NULL constant @@ -1258,6 +1259,22 @@ private: ASSERT_EQUALS("", errout.str()); } + void nullpointer20() { // #3807 + check("void f(int x) {\n" + " struct xy *p = 0;\n" + " if (x) p = q;\n" + " if (p ? p->x || p->y : 0) { }\n" + "}"); + ASSERT_EQUALS("", errout.str()); + + check("void f(int x) {\n" // false negative + " struct xy *p = 0;\n" + " if (x) p = q;\n" + " if (y ? p->x : p->y) { }\n" + "}"); + TODO_ASSERT_EQUALS("error", "", errout.str()); + } + void nullpointer_castToVoid() { // #3771 check("void f () {\n" " int *buf = NULL;\n"