From 3ec3bd52e0c2d7798d5730f06a7304a23a0d8e5d Mon Sep 17 00:00:00 2001 From: Paul Fultz II Date: Tue, 23 Jul 2019 17:04:49 -0500 Subject: [PATCH] Fix FP when using a pointer to a container (#2029) --- lib/checkstl.cpp | 5 ++--- lib/valueflow.cpp | 2 +- test/teststl.cpp | 19 +++++++++++++++++-- 3 files changed, 20 insertions(+), 6 deletions(-) diff --git a/lib/checkstl.cpp b/lib/checkstl.cpp index e09c06ee9..408f51c3f 100644 --- a/lib/checkstl.cpp +++ b/lib/checkstl.cpp @@ -823,13 +823,12 @@ void CheckStl::invalidContainer() for (const ValueFlow::Value& val:info.tok->values()) { if (!val.isLocalLifetimeValue()) continue; + if (val.lifetimeKind == ValueFlow::Value::LifetimeKind::Address) + continue; if (!val.tokvalue->variable()) continue; if (val.tokvalue->varId() != tok->varId()) continue; - // Skip possible temporaries - if (val.tokvalue == tok) - continue; ErrorPath ep; // Check the iterator is created before the change if (reaches(val.tokvalue, tok, library, &ep)) { diff --git a/lib/valueflow.cpp b/lib/valueflow.cpp index 87ea0e806..d2b3914c0 100644 --- a/lib/valueflow.cpp +++ b/lib/valueflow.cpp @@ -2771,7 +2771,7 @@ static const Token *getLifetimeToken(const Token *tok, ValueFlow::Value::ErrorPa return tok; if (var->isArgument()) { errorPath.emplace_back(var->declEndToken(), "Passed to reference."); - return var->nameToken(); + return tok; } else if (Token::simpleMatch(var->declEndToken(), "=")) { errorPath.emplace_back(var->declEndToken(), "Assigned to reference."); const Token *vartok = var->declEndToken()->astOperand2(); diff --git a/test/teststl.cpp b/test/teststl.cpp index 282be664b..a947f7036 100644 --- a/test/teststl.cpp +++ b/test/teststl.cpp @@ -2083,8 +2083,7 @@ private: " void* v = &i->foo;\n" " return v;\n" "}"); - ASSERT_EQUALS("[test.cpp:4] -> [test.cpp:1] -> [test.cpp:5] -> [test.cpp:3] -> [test.cpp:1] -> [test.cpp:6]: (error) Using pointer to local variable 'bars' that may be invalid.\n" - "[test.cpp:4] -> [test.cpp:1] -> [test.cpp:5] -> [test.cpp:4] -> [test.cpp:1] -> [test.cpp:6]: (error) Using pointer to local variable 'bars' that may be invalid.\n", errout.str()); + ASSERT_EQUALS("[test.cpp:4] -> [test.cpp:1] -> [test.cpp:5] -> [test.cpp:4] -> [test.cpp:1] -> [test.cpp:6]: (error) Using pointer to local variable 'bars' that may be invalid.\n", errout.str()); } void insert2() { @@ -3867,6 +3866,22 @@ private: "}\n", true); ASSERT_EQUALS("", errout.str()); + + check("void f(std::vector &v) {\n" + " int *v0 = &v[0];\n" + " v.push_back(123);\n" + " std::cout << (*v0)[0] << std::endl;\n" + "}\n", + true); + ASSERT_EQUALS("[test.cpp:1] -> [test.cpp:2] -> [test.cpp:3] -> [test.cpp:1] -> [test.cpp:4]: (error) Using pointer to local variable 'v' that may be invalid.\n", errout.str()); + + check("void f(std::vector &v) {\n" + " std::vector *v0 = &v;\n" + " v.push_back(123);\n" + " std::cout << (*v0)[0] << std::endl;\n" + "}\n", + true); + ASSERT_EQUALS("", errout.str()); } void findInsert() {