From 71deaaeb18ee145c24436bc6520f7954b5e50dc6 Mon Sep 17 00:00:00 2001 From: Paul Fultz II Date: Thu, 2 Apr 2020 03:17:58 -0500 Subject: [PATCH] Fix issue 9608: False Positive: returnDanglingLifetime with braced-init-list (#2583) --- lib/valueflow.cpp | 14 +++++++++++--- test/testautovariables.cpp | 8 ++++++++ 2 files changed, 19 insertions(+), 3 deletions(-) diff --git a/lib/valueflow.cpp b/lib/valueflow.cpp index c40185533..4b48e9c3a 100644 --- a/lib/valueflow.cpp +++ b/lib/valueflow.cpp @@ -3384,9 +3384,17 @@ static void valueFlowLifetimeConstructor(Token* tok, TokenList* tokenlist, Error valueFlowLifetimeConstructor(tok, Token::typeOf(parent->previous()), tokenlist, errorLogger, settings); } else if (Token::simpleMatch(tok, "{") && hasInitList(parent)) { std::vector args = getArguments(tok); - for (const Token *argtok : args) { - LifetimeStore ls{argtok, "Passed to initializer list.", ValueFlow::Value::LifetimeKind::Object}; - ls.byVal(tok, tokenlist, errorLogger, settings); + // Assume range constructor if passed a pair of iterators + if (astIsContainer(parent) && args.size() == 2 && astIsIterator(args[0]) && astIsIterator(args[1])) { + for (const Token *argtok : args) { + LifetimeStore ls{argtok, "Passed to initializer list.", ValueFlow::Value::LifetimeKind::Object}; + ls.byDerefCopy(tok, tokenlist, errorLogger, settings); + } + } else { + for (const Token *argtok : args) { + LifetimeStore ls{argtok, "Passed to initializer list.", ValueFlow::Value::LifetimeKind::Object}; + ls.byVal(tok, tokenlist, errorLogger, settings); + } } } else if (const Type* t = Token::typeOf(tok->previous())) { valueFlowLifetimeConstructor(tok, t, tokenlist, errorLogger, settings); diff --git a/test/testautovariables.cpp b/test/testautovariables.cpp index 2b4560de7..0fada3f5c 100644 --- a/test/testautovariables.cpp +++ b/test/testautovariables.cpp @@ -2476,6 +2476,14 @@ private: " return {&x, &x};\n" "}\n"); ASSERT_EQUALS("", errout.str()); + + check("std::vector f() {\n" + " std::set x;\n" + " x.insert(\"1\");\n" + " x.insert(\"2\");\n" + " return { x.begin(), x.end() };\n" + "}\n"); + ASSERT_EQUALS("", errout.str()); } void danglingLifetimeImplicitConversion() {