diff --git a/lib/valueflow.cpp b/lib/valueflow.cpp index 5ce932dc6..aec6e169e 100644 --- a/lib/valueflow.cpp +++ b/lib/valueflow.cpp @@ -3581,11 +3581,20 @@ static void valueFlowForwardLifetime(Token * tok, TokenList *tokenlist, ErrorLog if (!expr) return; + if (expr->exprId() == 0) + return; + const Token* endOfVarScope = getEndOfExprScope(expr); // Only forward lifetime values std::list values = parent->astOperand2()->values(); values.remove_if(&isNotLifetimeValue); + // Dont forward lifetimes that overlap + values.remove_if([&](const ValueFlow::Value& value) { + return findAstNode(value.tokvalue, [&](const Token* child) { + return child->exprId() == expr->exprId(); + }); + }); // Skip RHS const Token *nextExpression = nextAfterAstRightmostLeaf(parent); diff --git a/test/testnullpointer.cpp b/test/testnullpointer.cpp index b2fdd2568..c01f1a4a7 100644 --- a/test/testnullpointer.cpp +++ b/test/testnullpointer.cpp @@ -137,6 +137,7 @@ private: TEST_CASE(nullpointer91); // #10678 TEST_CASE(nullpointer92); TEST_CASE(nullpointer93); // #3929 + TEST_CASE(nullpointer94); // #11040 TEST_CASE(nullpointer_addressOf); // address of TEST_CASE(nullpointerSwitch); // #2626 TEST_CASE(nullpointer_cast); // #4692 @@ -2732,6 +2733,19 @@ private: ASSERT_EQUALS("[test.cpp:7]: (error) Null pointer dereference: myNull\n", errout.str()); } + void nullpointer94() // #11040 + { + check("struct entry { struct entry* next; size_t len; };\n" + "void f(struct entry **kep, size_t slen) {\n" + " while (*kep)\n" + " kep = &(*kep)->next;\n" + " *kep = (struct entry*)malloc(sizeof(**kep));\n" + " (*kep)->next = 0;\n" + " (*kep)->len = slen;\n" + "}\n"); + ASSERT_EQUALS("", errout.str()); + } + void nullpointer_addressOf() { // address of check("void f() {\n" " struct X *x = 0;\n"