From e9f369d3790e946f38d8d8e576b83a9809f1934d Mon Sep 17 00:00:00 2001 From: chrchr Date: Thu, 20 Jul 2023 17:16:25 +0200 Subject: [PATCH 1/5] Fix #11546 FP danglingTemporaryLifetime with unknown member --- lib/valueflow.cpp | 24 ++++++++++++++---------- test/testautovariables.cpp | 13 +++++++++++++ 2 files changed, 27 insertions(+), 10 deletions(-) diff --git a/lib/valueflow.cpp b/lib/valueflow.cpp index a6ea2761aae..4aed64717b0 100644 --- a/lib/valueflow.cpp +++ b/lib/valueflow.cpp @@ -4259,26 +4259,30 @@ struct LifetimeStore { } }; -static bool isOwningVariables(const std::list& vars, int depth = 10) +static bool isOwningVariables(const std::list& vars, const std::vector& args, int depth = 10) { if (depth < 0) return false; - return vars.empty() || std::all_of(vars.cbegin(), vars.cend(), [&](const Variable& var) { - if (var.isReference() || var.isPointer()) - return false; + return std::any_of(vars.cbegin(), vars.cend(), [&](const Variable& var) { const ValueType* vt = var.valueType(); if (vt) { - if (vt->pointer > 0) + if (std::none_of(args.begin(), args.end(), [vt](const Token* arg) { + return arg->valueType() && arg->valueType()->type == vt->type; + })) return false; - if (vt->isPrimitive()) + if (vt->pointer > 0) return true; - if (vt->isEnum()) + if (vt->reference != Reference::None) return true; + if (vt->isPrimitive()) + return false; + if (vt->isEnum()) + return false; // TODO: Check container inner type if (vt->type == ValueType::CONTAINER && vt->container) - return !vt->container->view; + return vt->container->view; if (vt->typeScope) - return isOwningVariables(vt->typeScope->varlist, depth - 1); + return isOwningVariables(vt->typeScope->varlist, args, depth - 1); } return false; }); @@ -4357,7 +4361,7 @@ static void valueFlowLifetimeUserConstructor(Token* tok, else ls.byVal(tok, tokenlist, errorLogger, settings); }); - } else if (!isOwningVariables(constructor->nestedIn->varlist)) { + } else if (isOwningVariables(constructor->nestedIn->varlist, args)) { LifetimeStore::forEach(args, "Passed to constructor of '" + name + "'.", ValueFlow::Value::LifetimeKind::SubObject, diff --git a/test/testautovariables.cpp b/test/testautovariables.cpp index 5fbe371f6a3..d7a1b5dd17b 100644 --- a/test/testautovariables.cpp +++ b/test/testautovariables.cpp @@ -3649,6 +3649,19 @@ class TestAutoVariables : public TestFixture { "}\n", true); ASSERT_EQUALS("", errout.str()); + + check("struct S {\n" + " explicit S(const char* p) { m = p; }\n" + " void g();\n" + " std::string m;\n" + " int* t{};\n" + "};\n" + "void f(const std::stringstream& buffer) {\n" + " S s(buffer.str().c_str());\n" + " s.g();\n" + "}\n", + true); + ASSERT_EQUALS("", errout.str()); } void danglingLifetimeAggegrateConstructor() { From de7096e3009f067790de5b51c731a83baa682579 Mon Sep 17 00:00:00 2001 From: chrchr-github <78114321+chrchr-github@users.noreply.github.com> Date: Sun, 30 Jul 2023 01:21:55 +0200 Subject: [PATCH 2/5] Update valueflow.cpp --- lib/valueflow.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/lib/valueflow.cpp b/lib/valueflow.cpp index 4aed64717b0..c8b928915c1 100644 --- a/lib/valueflow.cpp +++ b/lib/valueflow.cpp @@ -4259,7 +4259,7 @@ struct LifetimeStore { } }; -static bool isOwningVariables(const std::list& vars, const std::vector& args, int depth = 10) +static bool hasBorrowingVariables(const std::list& vars, const std::vector& args, int depth = 10) { if (depth < 0) return false; @@ -4361,7 +4361,7 @@ static void valueFlowLifetimeUserConstructor(Token* tok, else ls.byVal(tok, tokenlist, errorLogger, settings); }); - } else if (isOwningVariables(constructor->nestedIn->varlist, args)) { + } else if (hasBorrowingVariables(constructor->nestedIn->varlist, args)) { LifetimeStore::forEach(args, "Passed to constructor of '" + name + "'.", ValueFlow::Value::LifetimeKind::SubObject, From f66896e14f09b101c5ce1e81493e3c134a9bb3dc Mon Sep 17 00:00:00 2001 From: chrchr-github <78114321+chrchr-github@users.noreply.github.com> Date: Sun, 30 Jul 2023 01:33:18 +0200 Subject: [PATCH 3/5] Update valueflow.cpp --- lib/valueflow.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/valueflow.cpp b/lib/valueflow.cpp index c8b928915c1..585e1403b4f 100644 --- a/lib/valueflow.cpp +++ b/lib/valueflow.cpp @@ -4282,7 +4282,7 @@ static bool hasBorrowingVariables(const std::list& vars, const std::ve if (vt->type == ValueType::CONTAINER && vt->container) return vt->container->view; if (vt->typeScope) - return isOwningVariables(vt->typeScope->varlist, args, depth - 1); + return hasBorrowingVariables(vt->typeScope->varlist, args, depth - 1); } return false; }); From 574ad3ab927da3f342548ea6220d4fb59c2b6570 Mon Sep 17 00:00:00 2001 From: chrchr Date: Mon, 7 Aug 2023 12:18:46 +0200 Subject: [PATCH 4/5] Address reviewer comments --- lib/valueflow.cpp | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/lib/valueflow.cpp b/lib/valueflow.cpp index 673a60bc17d..030a6d7d56a 100644 --- a/lib/valueflow.cpp +++ b/lib/valueflow.cpp @@ -4250,8 +4250,9 @@ static bool hasBorrowingVariables(const std::list& vars, const std::ve return std::any_of(vars.cbegin(), vars.cend(), [&](const Variable& var) { const ValueType* vt = var.valueType(); if (vt) { - if (std::none_of(args.begin(), args.end(), [vt](const Token* arg) { - return arg->valueType() && arg->valueType()->type == vt->type; + if (vt->pointer > 0 && + std::none_of(args.begin(), args.end(), [vt](const Token* arg) { + return arg->valueType() && arg->valueType()->type == vt->type; })) return false; if (vt->pointer > 0) @@ -4268,7 +4269,7 @@ static bool hasBorrowingVariables(const std::list& vars, const std::ve if (vt->typeScope) return hasBorrowingVariables(vt->typeScope->varlist, args, depth - 1); } - return false; + return true; }); } From ad02e1341824bf0baddb317a33d2bdf2fe3316aa Mon Sep 17 00:00:00 2001 From: chrchr Date: Mon, 7 Aug 2023 12:37:41 +0200 Subject: [PATCH 5/5] Format --- lib/valueflow.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/valueflow.cpp b/lib/valueflow.cpp index 030a6d7d56a..eb5dc9e0f7a 100644 --- a/lib/valueflow.cpp +++ b/lib/valueflow.cpp @@ -4252,7 +4252,7 @@ static bool hasBorrowingVariables(const std::list& vars, const std::ve if (vt) { if (vt->pointer > 0 && std::none_of(args.begin(), args.end(), [vt](const Token* arg) { - return arg->valueType() && arg->valueType()->type == vt->type; + return arg->valueType() && arg->valueType()->type == vt->type; })) return false; if (vt->pointer > 0)