Fix 11088: False positive: Array index out of bounds (function pointer parameter is array) (#5200)
This commit is contained in:
parent
a0c4e20e2d
commit
63b7e6a283
|
@ -636,6 +636,36 @@ static std::unordered_map<std::string, BuiltinLibraryFunction> createBuiltinLibr
|
||||||
v.tokvalue = nullptr;
|
v.tokvalue = nullptr;
|
||||||
return v;
|
return v;
|
||||||
};
|
};
|
||||||
|
functions["strcmp"] = [](const std::vector<ValueFlow::Value>& args) {
|
||||||
|
if (args.size() != 2)
|
||||||
|
return ValueFlow::Value::unknown();
|
||||||
|
const ValueFlow::Value& lhs = args[0];
|
||||||
|
if (!(lhs.isTokValue() && lhs.tokvalue->tokType() == Token::eString))
|
||||||
|
return ValueFlow::Value::unknown();
|
||||||
|
const ValueFlow::Value& rhs = args[1];
|
||||||
|
if (!(rhs.isTokValue() && rhs.tokvalue->tokType() == Token::eString))
|
||||||
|
return ValueFlow::Value::unknown();
|
||||||
|
ValueFlow::Value v(getStringLiteral(lhs.tokvalue->str()).compare(getStringLiteral(rhs.tokvalue->str())));
|
||||||
|
ValueFlow::combineValueProperties(lhs, rhs, v);
|
||||||
|
return v;
|
||||||
|
};
|
||||||
|
functions["strncmp"] = [](const std::vector<ValueFlow::Value>& args) {
|
||||||
|
if (args.size() != 3)
|
||||||
|
return ValueFlow::Value::unknown();
|
||||||
|
const ValueFlow::Value& lhs = args[0];
|
||||||
|
if (!(lhs.isTokValue() && lhs.tokvalue->tokType() == Token::eString))
|
||||||
|
return ValueFlow::Value::unknown();
|
||||||
|
const ValueFlow::Value& rhs = args[1];
|
||||||
|
if (!(rhs.isTokValue() && rhs.tokvalue->tokType() == Token::eString))
|
||||||
|
return ValueFlow::Value::unknown();
|
||||||
|
const ValueFlow::Value& len = args[2];
|
||||||
|
if (!len.isIntValue())
|
||||||
|
return ValueFlow::Value::unknown();
|
||||||
|
ValueFlow::Value v(getStringLiteral(lhs.tokvalue->str())
|
||||||
|
.compare(0, len.intvalue, getStringLiteral(rhs.tokvalue->str()), 0, len.intvalue));
|
||||||
|
ValueFlow::combineValueProperties(lhs, rhs, v);
|
||||||
|
return v;
|
||||||
|
};
|
||||||
functions["sin"] = [](const std::vector<ValueFlow::Value>& args) {
|
functions["sin"] = [](const std::vector<ValueFlow::Value>& args) {
|
||||||
if (args.size() != 1)
|
if (args.size() != 1)
|
||||||
return ValueFlow::Value::unknown();
|
return ValueFlow::Value::unknown();
|
||||||
|
@ -1164,6 +1194,7 @@ static ValueFlow::Value executeImpl(const Token* expr, ProgramMemory& pm, const
|
||||||
if (expr->hasKnownIntValue() && !expr->isAssignmentOp() && expr->str() != ",")
|
if (expr->hasKnownIntValue() && !expr->isAssignmentOp() && expr->str() != ",")
|
||||||
return expr->values().front();
|
return expr->values().front();
|
||||||
if ((value = expr->getKnownValue(ValueFlow::Value::ValueType::FLOAT)) ||
|
if ((value = expr->getKnownValue(ValueFlow::Value::ValueType::FLOAT)) ||
|
||||||
|
(value = expr->getKnownValue(ValueFlow::Value::ValueType::TOK)) ||
|
||||||
(value = expr->getKnownValue(ValueFlow::Value::ValueType::ITERATOR_START)) ||
|
(value = expr->getKnownValue(ValueFlow::Value::ValueType::ITERATOR_START)) ||
|
||||||
(value = expr->getKnownValue(ValueFlow::Value::ValueType::ITERATOR_END)) ||
|
(value = expr->getKnownValue(ValueFlow::Value::ValueType::ITERATOR_END)) ||
|
||||||
(value = expr->getKnownValue(ValueFlow::Value::ValueType::CONTAINER_SIZE))) {
|
(value = expr->getKnownValue(ValueFlow::Value::ValueType::CONTAINER_SIZE))) {
|
||||||
|
|
|
@ -176,6 +176,7 @@ private:
|
||||||
TEST_CASE(array_index_71); // #11461
|
TEST_CASE(array_index_71); // #11461
|
||||||
TEST_CASE(array_index_72); // #11784
|
TEST_CASE(array_index_72); // #11784
|
||||||
TEST_CASE(array_index_73); // #11530
|
TEST_CASE(array_index_73); // #11530
|
||||||
|
TEST_CASE(array_index_74); // #11088
|
||||||
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
|
||||||
|
@ -1952,6 +1953,21 @@ private:
|
||||||
ASSERT_EQUALS("", errout.str());
|
ASSERT_EQUALS("", errout.str());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// #11088
|
||||||
|
void array_index_74()
|
||||||
|
{
|
||||||
|
check("void foo(const char *keys) {\n"
|
||||||
|
" const char *prefix = \"<Shift+\";\n"
|
||||||
|
" const size_t prefix_len = strlen(prefix);\n"
|
||||||
|
" if (strncmp(keys, prefix, prefix_len)) { return; }\n"
|
||||||
|
" if (keys[prefix_len] == '>') {}\n"
|
||||||
|
"}\n"
|
||||||
|
"void bar() {\n"
|
||||||
|
" foo(\"q\");\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