From c0f55a2b855648518b2af653ef0ee45607f01af4 Mon Sep 17 00:00:00 2001 From: Paul Fultz II Date: Wed, 3 Aug 2022 12:05:07 -0500 Subject: [PATCH] Fix 11142: FP nullPointer before assignment (#4319) * Fix 11142: FP nullPointer before assignment * Format * Use simpleMatch --- lib/valueflow.cpp | 16 +++++++++++++++- test/testnullpointer.cpp | 11 +++++++++++ 2 files changed, 26 insertions(+), 1 deletion(-) diff --git a/lib/valueflow.cpp b/lib/valueflow.cpp index 59e3b09fd..68465f673 100644 --- a/lib/valueflow.cpp +++ b/lib/valueflow.cpp @@ -3634,6 +3634,19 @@ static void valueFlowLifetimeConstructor(Token *tok, ErrorLogger *errorLogger, const Settings *settings); +static bool isRangeForScope(const Scope* scope) +{ + if (!scope) + return false; + if (scope->type != Scope::eFor) + return false; + if (!scope->bodyStart) + return false; + if (!Token::simpleMatch(scope->bodyStart->previous(), ") {")) + return false; + return Token::simpleMatch(scope->bodyStart->linkAt(-1)->astOperand2(), ":"); +} + static const Token* getEndOfVarScope(const Variable* var) { if (!var) @@ -3651,7 +3664,8 @@ static const Token* getEndOfVarScope(const Variable* var) // If the variable is defined in a for/while initializer then we want to // pick one token after the end so forward analysis can analyze the exit // conditions - if (innerScope != outerScope && outerScope->isExecutable() && innerScope->isLocal()) + if (innerScope != outerScope && outerScope->isExecutable() && innerScope->isLoopScope() && + !isRangeForScope(innerScope)) return innerScope->bodyEnd->next(); return innerScope->bodyEnd; } diff --git a/test/testnullpointer.cpp b/test/testnullpointer.cpp index 45c13b658..7cc241894 100644 --- a/test/testnullpointer.cpp +++ b/test/testnullpointer.cpp @@ -138,6 +138,7 @@ private: TEST_CASE(nullpointer92); TEST_CASE(nullpointer93); // #3929 TEST_CASE(nullpointer94); // #11040 + TEST_CASE(nullpointer95); // #11142 TEST_CASE(nullpointer_addressOf); // address of TEST_CASE(nullpointerSwitch); // #2626 TEST_CASE(nullpointer_cast); // #4692 @@ -2751,6 +2752,16 @@ private: ASSERT_EQUALS("", errout.str()); } + void nullpointer95() // #11142 + { + check("void f(std::vector& v) {\n" + " for (auto& p : v)\n" + " if (*p < 2)\n" + " p = nullptr;\n" + "}\n"); + ASSERT_EQUALS("", errout.str()); + } + void nullpointer_addressOf() { // address of check("void f() {\n" " struct X *x = 0;\n"