STL: Better out of bounds checking for empty containers when index is unknown

This commit is contained in:
Daniel Marjamäki 2019-03-29 15:20:17 +01:00
parent 51b0ab0e77
commit 54bea2847a
2 changed files with 15 additions and 4 deletions

View File

@ -76,13 +76,16 @@ void CheckStl::outOfBounds()
if (Token::Match(tok, "%name% . %name% (") && container->getYield(tok->strAt(2)) == Library::Container::Yield::START_ITERATOR) {
const Token *parent = tok->tokAt(3)->astParent();
const Token *other = nullptr;
if (Token::simpleMatch(parent, "+") && parent->astOperand1() && parent->astOperand1()->hasKnownIntValue())
other = parent->astOperand1();
else if (Token::simpleMatch(parent, "+") && parent->astOperand2() && parent->astOperand2()->hasKnownIntValue())
if (Token::simpleMatch(parent, "+") && parent->astOperand1() == tok->tokAt(3))
other = parent->astOperand2();
if (other && other->getKnownIntValue() > value.intvalue) {
else if (Token::simpleMatch(parent, "+") && parent->astOperand2() == tok->tokAt(3))
other = parent->astOperand1();
if (other && other->hasKnownIntValue() && other->getKnownIntValue() > value.intvalue) {
outOfBoundsError(parent, tok->str(), &value, other->expressionString(), &other->values().back());
continue;
} else if (other && !other->hasKnownIntValue() && value.isKnown() && value.intvalue==0) {
outOfBoundsError(parent, tok->str(), &value, other->expressionString(), nullptr);
continue;
}
}
if (!container->arrayLike_indexOp && !container->stdStringLike)
@ -124,6 +127,8 @@ void CheckStl::outOfBoundsError(const Token *tok, const std::string &containerNa
else if (containerSize->intvalue == 0) {
if (containerSize->condition)
errmsg = ValueFlow::eitherTheConditionIsRedundant(containerSize->condition) + " or expression '" + expression + "' cause access out of bounds.";
else if (indexValue == nullptr && !index.empty())
errmsg = "Out of bounds access in expression '" + expression + "' because '$symbol' is empty and '" + index + "' may be non-zero.";
else
errmsg = "Out of bounds access in expression '" + expression + "' because '$symbol' is empty.";
} else if (indexValue) {

View File

@ -280,6 +280,12 @@ private:
" x = s.begin() + 1;\n"
"}\n");
ASSERT_EQUALS("test.cpp:3:error:Out of bounds access in expression 's.begin()+1' because 's' is empty.\n", errout.str());
checkNormal("void f(int x) {\n"
" std::string s;\n"
" x = s.begin() + x;\n"
"}\n");
ASSERT_EQUALS("test.cpp:3:error:Out of bounds access in expression 's.begin()+x' because 's' is empty and 'x' may be non-zero.\n", errout.str());
}
void outOfBoundsIndexExpression() {