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="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"/>
|
||||||
<function name="pop_front" action="pop"/>
|
|
||||||
</size>
|
</size>
|
||||||
<access indexOperator="array-like">
|
<access indexOperator="array-like">
|
||||||
<function name="at" yields="at_index"/>
|
<function name="at" yields="at_index"/>
|
||||||
|
@ -8594,6 +8593,9 @@ initializer list (7) string& replace (const_iterator i1, const_iterator i2, init
|
||||||
</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"/>
|
||||||
|
<size>
|
||||||
|
<function name="pop_front" action="pop"/>
|
||||||
|
</size>
|
||||||
</container>
|
</container>
|
||||||
<container id="stdArray" startPattern="std :: array <" inherits="stdContainer" opLessAllowed="true">
|
<container id="stdArray" startPattern="std :: array <" inherits="stdContainer" opLessAllowed="true">
|
||||||
<size templateParameter="1">
|
<size templateParameter="1">
|
||||||
|
|
|
@ -97,6 +97,16 @@ static bool containerYieldsElement(const Library::Container* container, const To
|
||||||
return false;
|
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)
|
static const Token* getContainerIndex(const Library::Container* container, const Token* parent)
|
||||||
{
|
{
|
||||||
if (Token::Match(parent, ". %name% (")) {
|
if (Token::Match(parent, ". %name% (")) {
|
||||||
|
@ -148,8 +158,9 @@ 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 ||
|
||||||
!containerAppendsElement(container, parent)))) {
|
(containerYieldsElement(container, parent) && !containerAppendsElement(container, parent)) ||
|
||||||
|
containerPopsElement(container, parent))) {
|
||||||
std::string indexExpr;
|
std::string indexExpr;
|
||||||
if (indexTok && !indexTok->hasKnownValue())
|
if (indexTok && !indexTok->hasKnownValue())
|
||||||
indexExpr = indexTok->expressionString();
|
indexExpr = indexTok->expressionString();
|
||||||
|
|
|
@ -123,6 +123,7 @@ private:
|
||||||
TEST_CASE(pushback13);
|
TEST_CASE(pushback13);
|
||||||
TEST_CASE(insert1);
|
TEST_CASE(insert1);
|
||||||
TEST_CASE(insert2);
|
TEST_CASE(insert2);
|
||||||
|
TEST_CASE(popback1);
|
||||||
|
|
||||||
TEST_CASE(stlBoundaries1);
|
TEST_CASE(stlBoundaries1);
|
||||||
TEST_CASE(stlBoundaries2);
|
TEST_CASE(stlBoundaries2);
|
||||||
|
@ -3061,6 +3062,31 @@ private:
|
||||||
ASSERT_EQUALS("", errout.str());
|
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() {
|
void stlBoundaries1() {
|
||||||
const std::string stlCont[] = {
|
const std::string stlCont[] = {
|
||||||
"list", "set", "multiset", "map", "multimap"
|
"list", "set", "multiset", "map", "multimap"
|
||||||
|
|
Loading…
Reference in New Issue