Skip to content

Commit e2f398f

Browse files
authored
Fix 11250: FN: bufferAccessOutOfBounds (comma operator: int x = (3,4) ) (#4636)
* Fix 11250: FN: bufferAccessOutOfBounds (comma operator: int x = (3,4) ) * Format
1 parent e01c463 commit e2f398f

4 files changed

Lines changed: 50 additions & 1 deletion

File tree

lib/astutils.h

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -98,6 +98,18 @@ const Token* findAstNode(const Token* ast, const TFunc& pred)
9898
return result;
9999
}
100100

101+
template<class TFunc>
102+
const Token* findParent(const Token* tok, const TFunc& pred)
103+
{
104+
if (!tok)
105+
return nullptr;
106+
const Token* parent = tok->astParent();
107+
while (parent && !pred(parent)) {
108+
parent = parent->astParent();
109+
}
110+
return parent;
111+
}
112+
101113
const Token* findExpression(const nonneg int exprid,
102114
const Token* start,
103115
const Token* end,

lib/programmemory.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1160,7 +1160,7 @@ static ValueFlow::Value executeImpl(const Token* expr, ProgramMemory& pm, const
11601160
const ValueFlow::Value* value = nullptr;
11611161
if (!expr)
11621162
return unknown;
1163-
else if (expr->hasKnownIntValue() && !expr->isAssignmentOp()) {
1163+
else if (expr->hasKnownIntValue() && !expr->isAssignmentOp() && expr->str() != ",") {
11641164
return expr->values().front();
11651165
} else if ((value = expr->getKnownValue(ValueFlow::Value::ValueType::FLOAT)) ||
11661166
(value = expr->getKnownValue(ValueFlow::Value::ValueType::ITERATOR_START)) ||

lib/valueflow.cpp

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -598,6 +598,17 @@ static void setTokenValue(Token* tok,
598598
if (!parent)
599599
return;
600600

601+
if (Token::simpleMatch(parent, ",") && astIsRHS(tok)) {
602+
const Token* callParent = findParent(parent, [](const Token* p) {
603+
return !Token::simpleMatch(p, ",");
604+
});
605+
// Ensure that the comma isnt a function call
606+
if (!callParent || (!Token::Match(callParent->previous(), "%name%|> (") && !Token::simpleMatch(callParent, "{"))) {
607+
setTokenValue(parent, std::move(value), settings);
608+
return;
609+
}
610+
}
611+
601612
if (Token::simpleMatch(parent, "=") && astIsRHS(tok) && !value.isLifetimeValue()) {
602613
setTokenValue(parent, value, settings);
603614
return;

test/testvalueflow.cpp

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -71,6 +71,7 @@ class TestValueFlow : public TestFixture {
7171

7272
TEST_CASE(valueFlowCalculations);
7373
TEST_CASE(valueFlowSizeof);
74+
TEST_CASE(valueFlowComma);
7475

7576
TEST_CASE(valueFlowErrorPath);
7677

@@ -1365,6 +1366,31 @@ class TestValueFlow : public TestFixture {
13651366
ASSERT_EQUALS(sizeof(std::int32_t) * 10 * 20, values.back().intvalue);
13661367
}
13671368

1369+
void valueFlowComma()
1370+
{
1371+
const char* code;
1372+
std::list<ValueFlow::Value> values;
1373+
1374+
code = "void f(int i) {\n"
1375+
" int x = (i, 4);\n"
1376+
" return x;\n"
1377+
"}\n";
1378+
ASSERT_EQUALS(true, testValueOfXKnown(code, 3U, 4));
1379+
1380+
code = "void f(int i) {\n"
1381+
" int x = (4, i);\n"
1382+
" return x;\n"
1383+
"}\n";
1384+
ASSERT_EQUALS(false, testValueOfX(code, 3U, 4));
1385+
1386+
code = "void f() {\n"
1387+
" int x = g(3, 4);\n"
1388+
" return x;\n"
1389+
"}\n";
1390+
values = tokenValues(code, ",");
1391+
ASSERT_EQUALS(0U, values.size());
1392+
}
1393+
13681394
void valueFlowErrorPath() {
13691395
const char *code;
13701396

0 commit comments

Comments
 (0)