From 54fbfd7c0fd0f197164904da3e5858b6ed01b718 Mon Sep 17 00:00:00 2001 From: Paul Fultz II Date: Sun, 27 Mar 2022 03:02:30 -0500 Subject: [PATCH] Fix 10895: FP danglingTempReference with emplace() (#3948) * Fix 10895: FP danglingTempReference with emplace() * Format --- cfg/std.cfg | 10 ++++++++-- lib/checkstl.cpp | 20 ++++++++++++++++++-- test/testautovariables.cpp | 7 +++++++ 3 files changed, 33 insertions(+), 4 deletions(-) diff --git a/cfg/std.cfg b/cfg/std.cfg index 229725771..4f043a6ca 100644 --- a/cfg/std.cfg +++ b/cfg/std.cfg @@ -8223,6 +8223,10 @@ initializer list (7) string& replace (const_iterator i1, const_iterator i2, init + + + + @@ -8245,6 +8249,7 @@ initializer list (7) string& replace (const_iterator i1, const_iterator i2, init + @@ -8253,6 +8258,7 @@ initializer list (7) string& replace (const_iterator i1, const_iterator i2, init + @@ -8304,11 +8310,11 @@ initializer list (7) string& replace (const_iterator i1, const_iterator i2, init - + - + diff --git a/lib/checkstl.cpp b/lib/checkstl.cpp index 86819458c..3a7672159 100644 --- a/lib/checkstl.cpp +++ b/lib/checkstl.cpp @@ -72,6 +72,21 @@ static bool isElementAccessYield(const Library::Container::Yield& yield) return contains({Library::Container::Yield::ITEM, Library::Container::Yield::AT_INDEX}, yield); } +static bool containerAppendsElement(const Library::Container* container, const Token* parent) +{ + if (Token::Match(parent, ". %name% (")) { + Library::Container::Action action = container->getAction(parent->strAt(1)); + if (contains({Library::Container::Action::INSERT, + Library::Container::Action::CHANGE, + Library::Container::Action::CHANGE_INTERNAL, + Library::Container::Action::PUSH, + Library::Container::Action::RESIZE}, + action)) + return true; + } + return false; +} + static bool containerYieldsElement(const Library::Container* container, const Token* parent) { if (Token::Match(parent, ". %name% (")) { @@ -86,7 +101,7 @@ static const Token* getContainerIndex(const Library::Container* container, const { if (Token::Match(parent, ". %name% (")) { Library::Container::Yield yield = container->getYield(parent->strAt(1)); - if (isElementAccessYield(yield) && !Token::simpleMatch(parent->tokAt(2), "( )")) + if (yield == Library::Container::Yield::AT_INDEX && !Token::simpleMatch(parent->tokAt(2), "( )")) return parent->tokAt(2)->astOperand2(); } if (!container->arrayLike_indexOp && !container->stdStringLike) @@ -133,7 +148,8 @@ void CheckStl::outOfBounds() continue; if (!value.errorSeverity() && !mSettings->severity.isEnabled(Severity::warning)) continue; - if (value.intvalue == 0 && (indexTok || containerYieldsElement(container, parent))) { + if (value.intvalue == 0 && (indexTok || (containerYieldsElement(container, parent) && + !containerAppendsElement(container, parent)))) { std::string indexExpr; if (indexTok && !indexTok->hasKnownValue()) indexExpr = indexTok->expressionString(); diff --git a/test/testautovariables.cpp b/test/testautovariables.cpp index 5653de030..18f083b16 100644 --- a/test/testautovariables.cpp +++ b/test/testautovariables.cpp @@ -2565,6 +2565,13 @@ private: " }\n" "};\n"); ASSERT_EQUALS("", errout.str()); + + check("void f() {\n" + " std::queue q;\n" + " auto& h = q.emplace();\n" + " h = 1;\n" + "}\n"); + ASSERT_EQUALS("", errout.str()); } void danglingLifetimeContainerView()