parent
ce3ba5c015
commit
50c8a0dbe1
|
@ -8574,7 +8574,6 @@ initializer list (7) string& replace (const_iterator i1, const_iterator i2, init
|
|||
<function name="pop_back" action="pop"/>
|
||||
<function name="push_front" action="push"/>
|
||||
<function name="emplace_front" action="push"/>
|
||||
<function name="pop_front" action="pop"/>
|
||||
</size>
|
||||
<access indexOperator="array-like">
|
||||
<function name="at" yields="at_index"/>
|
||||
|
@ -8594,6 +8593,9 @@ initializer list (7) string& replace (const_iterator i1, const_iterator i2, init
|
|||
</container>
|
||||
<container id="stdDeque" startPattern="std :: deque <" inherits="stdVectorDeque">
|
||||
<type unstable="erase insert"/>
|
||||
<size>
|
||||
<function name="pop_front" action="pop"/>
|
||||
</size>
|
||||
</container>
|
||||
<container id="stdArray" startPattern="std :: array <" inherits="stdContainer" opLessAllowed="true">
|
||||
<size templateParameter="1">
|
||||
|
|
|
@ -97,6 +97,16 @@ static bool containerYieldsElement(const Library::Container* container, const To
|
|||
return false;
|
||||
}
|
||||
|
||||
static bool containerPopsElement(const Library::Container* container, const Token* parent)
|
||||
{
|
||||
if (Token::Match(parent, ". %name% (")) {
|
||||
const Library::Container::Action action = container->getAction(parent->strAt(1));
|
||||
if (contains({ Library::Container::Action::POP }, action))
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
static const Token* getContainerIndex(const Library::Container* container, const Token* parent)
|
||||
{
|
||||
if (Token::Match(parent, ". %name% (")) {
|
||||
|
@ -148,8 +158,9 @@ void CheckStl::outOfBounds()
|
|||
continue;
|
||||
if (!value.errorSeverity() && !mSettings->severity.isEnabled(Severity::warning))
|
||||
continue;
|
||||
if (value.intvalue == 0 && (indexTok || (containerYieldsElement(container, parent) &&
|
||||
!containerAppendsElement(container, parent)))) {
|
||||
if (value.intvalue == 0 && (indexTok ||
|
||||
(containerYieldsElement(container, parent) && !containerAppendsElement(container, parent)) ||
|
||||
containerPopsElement(container, parent))) {
|
||||
std::string indexExpr;
|
||||
if (indexTok && !indexTok->hasKnownValue())
|
||||
indexExpr = indexTok->expressionString();
|
||||
|
|
|
@ -123,6 +123,7 @@ private:
|
|||
TEST_CASE(pushback13);
|
||||
TEST_CASE(insert1);
|
||||
TEST_CASE(insert2);
|
||||
TEST_CASE(popback1);
|
||||
|
||||
TEST_CASE(stlBoundaries1);
|
||||
TEST_CASE(stlBoundaries2);
|
||||
|
@ -3061,6 +3062,31 @@ private:
|
|||
ASSERT_EQUALS("", errout.str());
|
||||
}
|
||||
|
||||
void popback1() { // #11553
|
||||
check("void f() {\n"
|
||||
" std::vector<int> v;\n"
|
||||
" v.pop_back();\n"
|
||||
" std::list<int> l;\n"
|
||||
" l.pop_front();\n"
|
||||
"}\n");
|
||||
ASSERT_EQUALS("[test.cpp:3]: (error) Out of bounds access in expression 'v.pop_back()' because 'v' is empty.\n"
|
||||
"[test.cpp:5]: (error) Out of bounds access in expression 'l.pop_front()' because 'l' is empty.\n",
|
||||
errout.str());
|
||||
|
||||
check("void f(std::vector<int>& v) {\n"
|
||||
" if (v.empty()) {}\n"
|
||||
" v.pop_back();\n"
|
||||
"}\n");
|
||||
ASSERT_EQUALS("[test.cpp:2] -> [test.cpp:3]: (warning) Either the condition 'v.empty()' is redundant or expression 'v.pop_back()' cause access out of bounds.\n",
|
||||
errout.str());
|
||||
|
||||
check("void f(std::vector<int>& v) {\n"
|
||||
" v.pop_back();\n"
|
||||
" if (v.empty()) {}\n"
|
||||
"}\n");
|
||||
ASSERT_EQUALS("", errout.str());
|
||||
}
|
||||
|
||||
void stlBoundaries1() {
|
||||
const std::string stlCont[] = {
|
||||
"list", "set", "multiset", "map", "multimap"
|
||||
|
|
Loading…
Reference in New Issue