Fix 9546: properly check that the bound is the size (#2475)

Previously, as the check was done on the token and not on the ast,
`i <= v.size()` and `i <= v.size() - 2` would both raise the same
warning.

This patch fixes this, but this mean the check is only done when the
condition if `i <= v.size()`. Any other (more complex) condition is
ignore, and so we have false negative for instance with
 `i <= v.size() + 1`.
This commit is contained in:
Ken-Patrick Lehrmann 2020-01-05 16:24:25 +01:00 committed by Daniel Marjamäki
parent bc17b9a1be
commit 5f73e1cb32
2 changed files with 21 additions and 1 deletions

View File

@ -869,7 +869,11 @@ void CheckStl::stlOutOfBounds()
for (const Token *cond : conds) { for (const Token *cond : conds) {
const Token *vartok; const Token *vartok;
const Token *containerToken; const Token *containerToken;
if (Token::Match(cond, "<= %var% . %name% ( )") && Token::Match(cond->astOperand1(), "%var%")) { // check in the ast that cond is of the form "%var% <= %var% . %name% ( )"
if (cond->str() == "<=" && Token::Match(cond->astOperand1(), "%var%") &&
cond->astOperand2()->str() == "(" && cond->astOperand2()->astOperand1()->str() == "." &&
Token::Match(cond->astOperand2()->astOperand1()->astOperand1(), "%var%") &&
Token::Match(cond->astOperand2()->astOperand1()->astOperand2(), "%name%")) {
vartok = cond->astOperand1(); vartok = cond->astOperand1();
containerToken = cond->next(); containerToken = cond->next();
} else { } else {

View File

@ -1425,6 +1425,13 @@ private:
" for (B b : D()) {}\n" // Don't crash on range-based for-loop " for (B b : D()) {}\n" // Don't crash on range-based for-loop
"}"); "}");
ASSERT_EQUALS("", errout.str()); ASSERT_EQUALS("", errout.str());
check("void foo(std::vector<int> foo) {\n"
" for (unsigned int ii = 0; ii <= foo.size() + 1; ++ii) {\n"
" foo.at(ii) = 0;\n"
" }\n"
"}");
TODO_ASSERT_EQUALS("[test.cpp:3]: (error) When ii==foo.size(), foo.at(ii) is out of bounds.\n", "", errout.str());
} }
void STLSizeNoErr() { void STLSizeNoErr() {
@ -1477,6 +1484,15 @@ private:
"}"); "}");
ASSERT_EQUALS("", errout.str()); ASSERT_EQUALS("", errout.str());
} }
{
check("void foo(std::vector<int> foo) {\n"
" for (unsigned int ii = 0; ii <= foo.size() - 1; ++ii) {\n"
" foo.at(ii) = 0;\n"
" }\n"
"}");
ASSERT_EQUALS("", errout.str());
}
} }
void negativeIndex() { void negativeIndex() {