Fix 10621: FP arrayIndexOutOfBoundsCond with multiple index checks (#3597)
* Fix 10621: FP arrayIndexOutOfBoundsCond with multiple index checks * Format
This commit is contained in:
parent
19006ab775
commit
a0d633945e
|
@ -897,6 +897,24 @@ static void setTokenValue(Token* tok, ValueFlow::Value value, const Settings* se
|
|||
else if (Token::Match(parent, ":: %name%") && parent->astOperand2() == tok) {
|
||||
setTokenValue(parent, value, settings);
|
||||
}
|
||||
// Calling std::size or std::empty on an array
|
||||
else if (value.isTokValue() && Token::simpleMatch(value.tokvalue, "{") && tok->variable() &&
|
||||
tok->variable()->isArray() && Token::Match(parent->previous(), "%name% (") && astIsRHS(tok)) {
|
||||
std::vector<const Token*> args = getArguments(value.tokvalue);
|
||||
if (const Library::Function* f = settings->library.getFunction(parent->previous())) {
|
||||
if (f->containerYield == Library::Container::Yield::SIZE) {
|
||||
ValueFlow::Value v(value);
|
||||
v.valueType = ValueFlow::Value::ValueType::INT;
|
||||
v.intvalue = args.size();
|
||||
setTokenValue(parent, v, settings);
|
||||
} else if (f->containerYield == Library::Container::Yield::EMPTY) {
|
||||
ValueFlow::Value v(value);
|
||||
v.intvalue = args.empty();
|
||||
v.valueType = ValueFlow::Value::ValueType::INT;
|
||||
setTokenValue(parent, v, settings);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void setTokenValueCast(Token *parent, const ValueType &valueType, const ValueFlow::Value &value, const Settings *settings)
|
||||
|
@ -7840,9 +7858,6 @@ static std::vector<ValueFlow::Value> isOutOfBoundsImpl(const ValueFlow::Value& s
|
|||
return {};
|
||||
if (size.bound == ValueFlow::Value::Bound::Lower)
|
||||
return {};
|
||||
ValueFlow::Value inBoundsValue = inferCondition("<", indexTok, size.intvalue);
|
||||
if (inBoundsValue.isKnown() && inBoundsValue.intvalue != 0)
|
||||
return {};
|
||||
ValueFlow::Value value = inferCondition(">=", indexTok, indexValue->intvalue);
|
||||
if (!value.isKnown())
|
||||
return {};
|
||||
|
@ -7855,6 +7870,9 @@ static std::vector<ValueFlow::Value> isOutOfBoundsImpl(const ValueFlow::Value& s
|
|||
|
||||
std::vector<ValueFlow::Value> ValueFlow::isOutOfBounds(const Value& size, const Token* indexTok, bool possible)
|
||||
{
|
||||
ValueFlow::Value inBoundsValue = inferCondition("<", indexTok, size.intvalue);
|
||||
if (inBoundsValue.isKnown() && inBoundsValue.intvalue != 0)
|
||||
return {};
|
||||
std::vector<ValueFlow::Value> result = isOutOfBoundsImpl(size, indexTok, false);
|
||||
if (!result.empty())
|
||||
return result;
|
||||
|
|
|
@ -178,6 +178,7 @@ private:
|
|||
TEST_CASE(array_index_58); // #7524
|
||||
TEST_CASE(array_index_59); // #10413
|
||||
TEST_CASE(array_index_60); // #10617, #9824
|
||||
TEST_CASE(array_index_61); // #10621
|
||||
TEST_CASE(array_index_multidim);
|
||||
TEST_CASE(array_index_switch_in_for);
|
||||
TEST_CASE(array_index_for_in_for); // FP: #2634
|
||||
|
@ -1730,6 +1731,19 @@ private:
|
|||
errout.str());
|
||||
}
|
||||
|
||||
void array_index_61()
|
||||
{
|
||||
check("int f(int i) {\n"
|
||||
" const int M[] = { 0, 1, 2, 3 };\n"
|
||||
" if (i > 4)\n"
|
||||
" return -1;\n"
|
||||
" if (i < 0 || i == std::size(M))\n"
|
||||
" return 0; \n"
|
||||
" return M[i];\n"
|
||||
"}\n");
|
||||
ASSERT_EQUALS("", errout.str());
|
||||
}
|
||||
|
||||
void array_index_multidim() {
|
||||
check("void f()\n"
|
||||
"{\n"
|
||||
|
|
Loading…
Reference in New Issue