Fix 11250: FN: bufferAccessOutOfBounds (comma operator: int x = (3,4) ) (#4636)
* Fix 11250: FN: bufferAccessOutOfBounds (comma operator: int x = (3,4) ) * Format
This commit is contained in:
parent
e01c463ff8
commit
e2f398f81a
|
@ -98,6 +98,18 @@ const Token* findAstNode(const Token* ast, const TFunc& pred)
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
template<class TFunc>
|
||||||
|
const Token* findParent(const Token* tok, const TFunc& pred)
|
||||||
|
{
|
||||||
|
if (!tok)
|
||||||
|
return nullptr;
|
||||||
|
const Token* parent = tok->astParent();
|
||||||
|
while (parent && !pred(parent)) {
|
||||||
|
parent = parent->astParent();
|
||||||
|
}
|
||||||
|
return parent;
|
||||||
|
}
|
||||||
|
|
||||||
const Token* findExpression(const nonneg int exprid,
|
const Token* findExpression(const nonneg int exprid,
|
||||||
const Token* start,
|
const Token* start,
|
||||||
const Token* end,
|
const Token* end,
|
||||||
|
|
|
@ -1160,7 +1160,7 @@ static ValueFlow::Value executeImpl(const Token* expr, ProgramMemory& pm, const
|
||||||
const ValueFlow::Value* value = nullptr;
|
const ValueFlow::Value* value = nullptr;
|
||||||
if (!expr)
|
if (!expr)
|
||||||
return unknown;
|
return unknown;
|
||||||
else if (expr->hasKnownIntValue() && !expr->isAssignmentOp()) {
|
else if (expr->hasKnownIntValue() && !expr->isAssignmentOp() && expr->str() != ",") {
|
||||||
return expr->values().front();
|
return expr->values().front();
|
||||||
} else if ((value = expr->getKnownValue(ValueFlow::Value::ValueType::FLOAT)) ||
|
} else if ((value = expr->getKnownValue(ValueFlow::Value::ValueType::FLOAT)) ||
|
||||||
(value = expr->getKnownValue(ValueFlow::Value::ValueType::ITERATOR_START)) ||
|
(value = expr->getKnownValue(ValueFlow::Value::ValueType::ITERATOR_START)) ||
|
||||||
|
|
|
@ -598,6 +598,17 @@ static void setTokenValue(Token* tok,
|
||||||
if (!parent)
|
if (!parent)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
if (Token::simpleMatch(parent, ",") && astIsRHS(tok)) {
|
||||||
|
const Token* callParent = findParent(parent, [](const Token* p) {
|
||||||
|
return !Token::simpleMatch(p, ",");
|
||||||
|
});
|
||||||
|
// Ensure that the comma isnt a function call
|
||||||
|
if (!callParent || (!Token::Match(callParent->previous(), "%name%|> (") && !Token::simpleMatch(callParent, "{"))) {
|
||||||
|
setTokenValue(parent, std::move(value), settings);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (Token::simpleMatch(parent, "=") && astIsRHS(tok) && !value.isLifetimeValue()) {
|
if (Token::simpleMatch(parent, "=") && astIsRHS(tok) && !value.isLifetimeValue()) {
|
||||||
setTokenValue(parent, value, settings);
|
setTokenValue(parent, value, settings);
|
||||||
return;
|
return;
|
||||||
|
|
|
@ -71,6 +71,7 @@ private:
|
||||||
|
|
||||||
TEST_CASE(valueFlowCalculations);
|
TEST_CASE(valueFlowCalculations);
|
||||||
TEST_CASE(valueFlowSizeof);
|
TEST_CASE(valueFlowSizeof);
|
||||||
|
TEST_CASE(valueFlowComma);
|
||||||
|
|
||||||
TEST_CASE(valueFlowErrorPath);
|
TEST_CASE(valueFlowErrorPath);
|
||||||
|
|
||||||
|
@ -1365,6 +1366,31 @@ private:
|
||||||
ASSERT_EQUALS(sizeof(std::int32_t) * 10 * 20, values.back().intvalue);
|
ASSERT_EQUALS(sizeof(std::int32_t) * 10 * 20, values.back().intvalue);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void valueFlowComma()
|
||||||
|
{
|
||||||
|
const char* code;
|
||||||
|
std::list<ValueFlow::Value> values;
|
||||||
|
|
||||||
|
code = "void f(int i) {\n"
|
||||||
|
" int x = (i, 4);\n"
|
||||||
|
" return x;\n"
|
||||||
|
"}\n";
|
||||||
|
ASSERT_EQUALS(true, testValueOfXKnown(code, 3U, 4));
|
||||||
|
|
||||||
|
code = "void f(int i) {\n"
|
||||||
|
" int x = (4, i);\n"
|
||||||
|
" return x;\n"
|
||||||
|
"}\n";
|
||||||
|
ASSERT_EQUALS(false, testValueOfX(code, 3U, 4));
|
||||||
|
|
||||||
|
code = "void f() {\n"
|
||||||
|
" int x = g(3, 4);\n"
|
||||||
|
" return x;\n"
|
||||||
|
"}\n";
|
||||||
|
values = tokenValues(code, ",");
|
||||||
|
ASSERT_EQUALS(0U, values.size());
|
||||||
|
}
|
||||||
|
|
||||||
void valueFlowErrorPath() {
|
void valueFlowErrorPath() {
|
||||||
const char *code;
|
const char *code;
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue