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) {
|
else if (Token::Match(parent, ":: %name%") && parent->astOperand2() == tok) {
|
||||||
setTokenValue(parent, value, settings);
|
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)
|
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 {};
|
return {};
|
||||||
if (size.bound == ValueFlow::Value::Bound::Lower)
|
if (size.bound == ValueFlow::Value::Bound::Lower)
|
||||||
return {};
|
return {};
|
||||||
ValueFlow::Value inBoundsValue = inferCondition("<", indexTok, size.intvalue);
|
|
||||||
if (inBoundsValue.isKnown() && inBoundsValue.intvalue != 0)
|
|
||||||
return {};
|
|
||||||
ValueFlow::Value value = inferCondition(">=", indexTok, indexValue->intvalue);
|
ValueFlow::Value value = inferCondition(">=", indexTok, indexValue->intvalue);
|
||||||
if (!value.isKnown())
|
if (!value.isKnown())
|
||||||
return {};
|
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)
|
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);
|
std::vector<ValueFlow::Value> result = isOutOfBoundsImpl(size, indexTok, false);
|
||||||
if (!result.empty())
|
if (!result.empty())
|
||||||
return result;
|
return result;
|
||||||
|
|
|
@ -178,6 +178,7 @@ private:
|
||||||
TEST_CASE(array_index_58); // #7524
|
TEST_CASE(array_index_58); // #7524
|
||||||
TEST_CASE(array_index_59); // #10413
|
TEST_CASE(array_index_59); // #10413
|
||||||
TEST_CASE(array_index_60); // #10617, #9824
|
TEST_CASE(array_index_60); // #10617, #9824
|
||||||
|
TEST_CASE(array_index_61); // #10621
|
||||||
TEST_CASE(array_index_multidim);
|
TEST_CASE(array_index_multidim);
|
||||||
TEST_CASE(array_index_switch_in_for);
|
TEST_CASE(array_index_switch_in_for);
|
||||||
TEST_CASE(array_index_for_in_for); // FP: #2634
|
TEST_CASE(array_index_for_in_for); // FP: #2634
|
||||||
|
@ -1730,6 +1731,19 @@ private:
|
||||||
errout.str());
|
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() {
|
void array_index_multidim() {
|
||||||
check("void f()\n"
|
check("void f()\n"
|
||||||
"{\n"
|
"{\n"
|
||||||
|
|
Loading…
Reference in New Issue