Fix 10895: FP danglingTempReference with emplace() (#3948)
* Fix 10895: FP danglingTempReference with emplace() * Format
This commit is contained in:
parent
21b8c36eb1
commit
54fbfd7c0f
10
cfg/std.cfg
10
cfg/std.cfg
|
@ -8223,6 +8223,10 @@ initializer list (7) string& replace (const_iterator i1, const_iterator i2, init
|
||||||
</container>
|
</container>
|
||||||
<container id="stdVector" startPattern="std :: vector <" inherits="stdVectorDeque">
|
<container id="stdVector" startPattern="std :: vector <" inherits="stdVectorDeque">
|
||||||
<type unstable="erase insert"/>
|
<type unstable="erase insert"/>
|
||||||
|
<access>
|
||||||
|
<function name="emplace_back" action="push" yields="item"/>
|
||||||
|
<function name="emplace_front" action="push" yields="item"/>
|
||||||
|
</access>
|
||||||
</container>
|
</container>
|
||||||
<container id="stdDeque" startPattern="std :: deque <" inherits="stdVectorDeque">
|
<container id="stdDeque" startPattern="std :: deque <" inherits="stdVectorDeque">
|
||||||
<type unstable="erase insert"/>
|
<type unstable="erase insert"/>
|
||||||
|
@ -8245,6 +8249,7 @@ initializer list (7) string& replace (const_iterator i1, const_iterator i2, init
|
||||||
</container>
|
</container>
|
||||||
<container id="stdQueue" startPattern="std :: queue|priority_queue <" inherits="stdContainer">
|
<container id="stdQueue" startPattern="std :: queue|priority_queue <" inherits="stdContainer">
|
||||||
<access>
|
<access>
|
||||||
|
<function name="emplace" action="push" yields="item"/>
|
||||||
<function name="push" action="push"/>
|
<function name="push" action="push"/>
|
||||||
<function name="pop" action="pop"/>
|
<function name="pop" action="pop"/>
|
||||||
<function name="front" yields="item"/>
|
<function name="front" yields="item"/>
|
||||||
|
@ -8253,6 +8258,7 @@ initializer list (7) string& replace (const_iterator i1, const_iterator i2, init
|
||||||
</container>
|
</container>
|
||||||
<container id="stdStack" startPattern="std :: stack <" inherits="stdContainer">
|
<container id="stdStack" startPattern="std :: stack <" inherits="stdContainer">
|
||||||
<access>
|
<access>
|
||||||
|
<function name="emplace" action="push" yields="item"/>
|
||||||
<function name="push" action="push"/>
|
<function name="push" action="push"/>
|
||||||
<function name="pop" action="pop"/>
|
<function name="pop" action="pop"/>
|
||||||
<function name="top" yields="item"/>
|
<function name="top" yields="item"/>
|
||||||
|
@ -8304,11 +8310,11 @@ initializer list (7) string& replace (const_iterator i1, const_iterator i2, init
|
||||||
<container id="stdList" startPattern="std :: list|forward_list <" inherits="stdContainer">
|
<container id="stdList" startPattern="std :: list|forward_list <" inherits="stdContainer">
|
||||||
<size>
|
<size>
|
||||||
<function name="push_back" action="push"/>
|
<function name="push_back" action="push"/>
|
||||||
<function name="emplace_back" action="push"/>
|
<function name="emplace_back" action="push" yields="item"/>
|
||||||
<function name="emplace_after" action="push"/>
|
<function name="emplace_after" action="push"/>
|
||||||
<function name="pop_back" action="pop"/>
|
<function name="pop_back" action="pop"/>
|
||||||
<function name="push_front" action="push"/>
|
<function name="push_front" action="push"/>
|
||||||
<function name="emplace_front" action="push"/>
|
<function name="emplace_front" action="push" yields="item"/>
|
||||||
<function name="pop_front" action="pop"/>
|
<function name="pop_front" action="pop"/>
|
||||||
<function name="erase_after" action="erase"/>
|
<function name="erase_after" action="erase"/>
|
||||||
<function name="insert_after" action="insert"/>
|
<function name="insert_after" action="insert"/>
|
||||||
|
|
|
@ -72,6 +72,21 @@ static bool isElementAccessYield(const Library::Container::Yield& yield)
|
||||||
return contains({Library::Container::Yield::ITEM, Library::Container::Yield::AT_INDEX}, 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)
|
static bool containerYieldsElement(const Library::Container* container, const Token* parent)
|
||||||
{
|
{
|
||||||
if (Token::Match(parent, ". %name% (")) {
|
if (Token::Match(parent, ". %name% (")) {
|
||||||
|
@ -86,7 +101,7 @@ static const Token* getContainerIndex(const Library::Container* container, const
|
||||||
{
|
{
|
||||||
if (Token::Match(parent, ". %name% (")) {
|
if (Token::Match(parent, ". %name% (")) {
|
||||||
Library::Container::Yield yield = container->getYield(parent->strAt(1));
|
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();
|
return parent->tokAt(2)->astOperand2();
|
||||||
}
|
}
|
||||||
if (!container->arrayLike_indexOp && !container->stdStringLike)
|
if (!container->arrayLike_indexOp && !container->stdStringLike)
|
||||||
|
@ -133,7 +148,8 @@ void CheckStl::outOfBounds()
|
||||||
continue;
|
continue;
|
||||||
if (!value.errorSeverity() && !mSettings->severity.isEnabled(Severity::warning))
|
if (!value.errorSeverity() && !mSettings->severity.isEnabled(Severity::warning))
|
||||||
continue;
|
continue;
|
||||||
if (value.intvalue == 0 && (indexTok || containerYieldsElement(container, parent))) {
|
if (value.intvalue == 0 && (indexTok || (containerYieldsElement(container, parent) &&
|
||||||
|
!containerAppendsElement(container, parent)))) {
|
||||||
std::string indexExpr;
|
std::string indexExpr;
|
||||||
if (indexTok && !indexTok->hasKnownValue())
|
if (indexTok && !indexTok->hasKnownValue())
|
||||||
indexExpr = indexTok->expressionString();
|
indexExpr = indexTok->expressionString();
|
||||||
|
|
|
@ -2565,6 +2565,13 @@ private:
|
||||||
" }\n"
|
" }\n"
|
||||||
"};\n");
|
"};\n");
|
||||||
ASSERT_EQUALS("", errout.str());
|
ASSERT_EQUALS("", errout.str());
|
||||||
|
|
||||||
|
check("void f() {\n"
|
||||||
|
" std::queue<int> q;\n"
|
||||||
|
" auto& h = q.emplace();\n"
|
||||||
|
" h = 1;\n"
|
||||||
|
"}\n");
|
||||||
|
ASSERT_EQUALS("", errout.str());
|
||||||
}
|
}
|
||||||
|
|
||||||
void danglingLifetimeContainerView()
|
void danglingLifetimeContainerView()
|
||||||
|
|
Loading…
Reference in New Issue