From 0ad542fa295cdc3dc5fe0f29f3334bfc7f51ba51 Mon Sep 17 00:00:00 2001 From: chrchr-github <78114321+chrchr-github@users.noreply.github.com> Date: Fri, 5 Apr 2024 13:15:46 +0200 Subject: [PATCH 1/6] Update astutils.h --- lib/astutils.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/astutils.h b/lib/astutils.h index 10699f8de61..75629d902ce 100644 --- a/lib/astutils.h +++ b/lib/astutils.h @@ -163,7 +163,7 @@ bool astIsUniqueSmartPointer(const Token* tok); bool astIsIterator(const Token *tok); -bool astIsContainer(const Token *tok); +const Library::Container* astIsContainer(const Token *tok); bool astIsContainerView(const Token* tok); bool astIsContainerOwned(const Token* tok); From 08309684adffbbcd6922c11f0887bbe0698178e3 Mon Sep 17 00:00:00 2001 From: chrchr-github <78114321+chrchr-github@users.noreply.github.com> Date: Fri, 5 Apr 2024 13:16:34 +0200 Subject: [PATCH 2/6] Update astutils.cpp --- lib/astutils.cpp | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/lib/astutils.cpp b/lib/astutils.cpp index 1a672ef000b..49b66d02f9e 100644 --- a/lib/astutils.cpp +++ b/lib/astutils.cpp @@ -241,8 +241,9 @@ bool astIsIterator(const Token *tok) return tok && tok->valueType() && tok->valueType()->type == ValueType::Type::ITERATOR; } -bool astIsContainer(const Token* tok) { - return getLibraryContainer(tok) != nullptr && !astIsIterator(tok); +const Library::Container* astIsContainer(const Token* tok) { + const Library::Container* container = getLibraryContainer(tok); + return container != nullptr && !astIsIterator(tok) ? container : nullptr; } bool astIsContainerView(const Token* tok) From e9e856cd62150ab38a29b684d6d616cd94f2eccd Mon Sep 17 00:00:00 2001 From: chrchr-github <78114321+chrchr-github@users.noreply.github.com> Date: Fri, 5 Apr 2024 13:17:47 +0200 Subject: [PATCH 3/6] Update valueflow.cpp --- lib/valueflow.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/lib/valueflow.cpp b/lib/valueflow.cpp index ee8ad0d0d14..b1fa0aef573 100644 --- a/lib/valueflow.cpp +++ b/lib/valueflow.cpp @@ -4455,6 +4455,7 @@ static void valueFlowLifetimeFunction(Token *tok, TokenList &tokenlist, ErrorLog if (Token::Match(tok->astParent(), ". %name% (") && astIsRHS(tok)) memtok = tok->astParent()->astOperand1(); const int returnContainer = settings.library.returnValueContainer(tok); + const Library::Container* container{}; if (returnContainer >= 0) { std::vector args = getArguments(tok); for (int argnr = 1; argnr <= args.size(); ++argnr) { @@ -4489,7 +4490,7 @@ static void valueFlowLifetimeFunction(Token *tok, TokenList &tokenlist, ErrorLog tok->next(), tokenlist, errorLogger, settings); } } else if (memtok && Token::Match(tok->astParent(), ". push_back|push_front|insert|push|assign") && - astIsContainer(memtok)) { + (container = astIsContainer(memtok)) && !container->stdStringLike) { std::vector args = getArguments(tok); const std::size_t n = args.size(); if (n > 1 && Token::typeStr(args[n - 2]) == Token::typeStr(args[n - 1]) && From b2bc09d71cbe9ad242bdd5f27e9421b0f2cf4869 Mon Sep 17 00:00:00 2001 From: chrchr-github <78114321+chrchr-github@users.noreply.github.com> Date: Fri, 5 Apr 2024 13:21:51 +0200 Subject: [PATCH 4/6] Update testautovariables.cpp --- test/testautovariables.cpp | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/test/testautovariables.cpp b/test/testautovariables.cpp index 666023b5f3c..ef8cd776a2b 100644 --- a/test/testautovariables.cpp +++ b/test/testautovariables.cpp @@ -2815,6 +2815,16 @@ class TestAutoVariables : public TestFixture { " return ss;\n" "}\n"); ASSERT_EQUALS("", errout_str()); + + check("void f() {\n" // #12568 + " std::string str;\n" + " {\n" + " std::unique_ptr b(new char[1]{});\n" + " str.assign(b.get());\n" + " }\n" + " std::cerr << str;\n" + "}\n"); + ASSERT_EQUALS("", errout_str()); } void danglingLifetimeContainerView() From d3428429ea246f6522b7ca6266f70c0008843668 Mon Sep 17 00:00:00 2001 From: chrchr-github Date: Fri, 5 Apr 2024 20:28:05 +0200 Subject: [PATCH 5/6] Add helper function --- lib/astutils.cpp | 9 +++++++-- lib/astutils.h | 3 ++- lib/valueflow.cpp | 3 +-- 3 files changed, 10 insertions(+), 5 deletions(-) diff --git a/lib/astutils.cpp b/lib/astutils.cpp index 49b66d02f9e..9f80afd5ec0 100644 --- a/lib/astutils.cpp +++ b/lib/astutils.cpp @@ -241,9 +241,14 @@ bool astIsIterator(const Token *tok) return tok && tok->valueType() && tok->valueType()->type == ValueType::Type::ITERATOR; } -const Library::Container* astIsContainer(const Token* tok) { +bool astIsContainer(const Token* tok) { + return getLibraryContainer(tok) != nullptr && !astIsIterator(tok); +} + +bool astIsUniversalContainer(const Token* tok) +{ const Library::Container* container = getLibraryContainer(tok); - return container != nullptr && !astIsIterator(tok) ? container : nullptr; + return container && !container->stdStringLike && !astIsIterator(tok); } bool astIsContainerView(const Token* tok) diff --git a/lib/astutils.h b/lib/astutils.h index 75629d902ce..b7072d3ea68 100644 --- a/lib/astutils.h +++ b/lib/astutils.h @@ -163,7 +163,8 @@ bool astIsUniqueSmartPointer(const Token* tok); bool astIsIterator(const Token *tok); -const Library::Container* astIsContainer(const Token *tok); +bool astIsContainer(const Token *tok); +bool astIsUniversalContainer(const Token *tok); bool astIsContainerView(const Token* tok); bool astIsContainerOwned(const Token* tok); diff --git a/lib/valueflow.cpp b/lib/valueflow.cpp index b1fa0aef573..5cdb635526b 100644 --- a/lib/valueflow.cpp +++ b/lib/valueflow.cpp @@ -4455,7 +4455,6 @@ static void valueFlowLifetimeFunction(Token *tok, TokenList &tokenlist, ErrorLog if (Token::Match(tok->astParent(), ". %name% (") && astIsRHS(tok)) memtok = tok->astParent()->astOperand1(); const int returnContainer = settings.library.returnValueContainer(tok); - const Library::Container* container{}; if (returnContainer >= 0) { std::vector args = getArguments(tok); for (int argnr = 1; argnr <= args.size(); ++argnr) { @@ -4490,7 +4489,7 @@ static void valueFlowLifetimeFunction(Token *tok, TokenList &tokenlist, ErrorLog tok->next(), tokenlist, errorLogger, settings); } } else if (memtok && Token::Match(tok->astParent(), ". push_back|push_front|insert|push|assign") && - (container = astIsContainer(memtok)) && !container->stdStringLike) { + astIsUniversalContainer(memtok)) { std::vector args = getArguments(tok); const std::size_t n = args.size(); if (n > 1 && Token::typeStr(args[n - 2]) == Token::typeStr(args[n - 1]) && From 1adefe834843f7acd64814432f0ba671329485f7 Mon Sep 17 00:00:00 2001 From: chrchr-github Date: Fri, 5 Apr 2024 21:04:21 +0200 Subject: [PATCH 6/6] Rename --- lib/astutils.cpp | 2 +- lib/astutils.h | 2 +- lib/valueflow.cpp | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/lib/astutils.cpp b/lib/astutils.cpp index 9f80afd5ec0..beb4ef5e9ef 100644 --- a/lib/astutils.cpp +++ b/lib/astutils.cpp @@ -245,7 +245,7 @@ bool astIsContainer(const Token* tok) { return getLibraryContainer(tok) != nullptr && !astIsIterator(tok); } -bool astIsUniversalContainer(const Token* tok) +bool astIsNonStringContainer(const Token* tok) { const Library::Container* container = getLibraryContainer(tok); return container && !container->stdStringLike && !astIsIterator(tok); diff --git a/lib/astutils.h b/lib/astutils.h index b7072d3ea68..1526d00a7d7 100644 --- a/lib/astutils.h +++ b/lib/astutils.h @@ -164,7 +164,7 @@ bool astIsUniqueSmartPointer(const Token* tok); bool astIsIterator(const Token *tok); bool astIsContainer(const Token *tok); -bool astIsUniversalContainer(const Token *tok); +bool astIsNonStringContainer(const Token *tok); bool astIsContainerView(const Token* tok); bool astIsContainerOwned(const Token* tok); diff --git a/lib/valueflow.cpp b/lib/valueflow.cpp index 5cdb635526b..61cfc06acaa 100644 --- a/lib/valueflow.cpp +++ b/lib/valueflow.cpp @@ -4489,7 +4489,7 @@ static void valueFlowLifetimeFunction(Token *tok, TokenList &tokenlist, ErrorLog tok->next(), tokenlist, errorLogger, settings); } } else if (memtok && Token::Match(tok->astParent(), ". push_back|push_front|insert|push|assign") && - astIsUniversalContainer(memtok)) { + astIsNonStringContainer(memtok)) { std::vector args = getArguments(tok); const std::size_t n = args.size(); if (n > 1 && Token::typeStr(args[n - 2]) == Token::typeStr(args[n - 1]) &&