From 0a718694afae837010f68a2bdbb8f158e1ea81aa Mon Sep 17 00:00:00 2001 From: Paul Fultz II Date: Tue, 1 Sep 2020 04:21:29 -0500 Subject: [PATCH] Fix issue 9852: False positive: danglingTemporaryLifetime when returning a vector of vectors (#2766) --- lib/checkautovariables.cpp | 13 +++++++++++-- test/testautovariables.cpp | 7 +++++++ 2 files changed, 18 insertions(+), 2 deletions(-) diff --git a/lib/checkautovariables.cpp b/lib/checkautovariables.cpp index 889b22569..f36694b32 100644 --- a/lib/checkautovariables.cpp +++ b/lib/checkautovariables.cpp @@ -445,8 +445,17 @@ static bool isDeadTemporary(bool cpp, const Token* tok, const Token* expr, const { if (!isTemporary(cpp, tok, library)) return false; - if (expr && !precedes(nextAfterAstRightmostLeaf(tok->astTop()), nextAfterAstRightmostLeaf(expr->astTop()))) - return false; + if (expr) { + if (!precedes(nextAfterAstRightmostLeaf(tok->astTop()), nextAfterAstRightmostLeaf(expr->astTop()))) + return false; + const Token* parent = tok->astParent(); + // Is in a for loop + if (astIsRHS(tok) && Token::simpleMatch(parent, ":") && Token::simpleMatch(parent->astParent(), "(") && Token::simpleMatch(parent->astParent()->previous(), "for (")) { + const Token* braces = parent->astParent()->link()->next(); + if (precedes(braces, expr) && precedes(expr, braces->link())) + return false; + } + } return true; } diff --git a/test/testautovariables.cpp b/test/testautovariables.cpp index 34bb9c0be..8748b85e8 100644 --- a/test/testautovariables.cpp +++ b/test/testautovariables.cpp @@ -2142,6 +2142,13 @@ private: " return std::vector{&a};\n" "}\n"); ASSERT_EQUALS("[test.cpp:3] -> [test.cpp:3] -> [test.cpp:2] -> [test.cpp:3]: (error) Returning object that points to local variable 'a' that will be invalid when returning.\n", errout.str()); + + check("std::vector> g();\n" + "void f() {\n" + " for(auto& x:g())\n" + " std::sort(x.begin(), x.end());\n" + "}\n"); + ASSERT_EQUALS("", errout.str()); } void danglingLifetime() {