Skip to content

Commit 96d4a96

Browse files
Fix #14774 FP bufferAccessOutOfBounds: Wrong size for sizeof( ref ) (#8572)
1 parent 47aaa76 commit 96d4a96

2 files changed

Lines changed: 31 additions & 5 deletions

File tree

lib/vf_common.cpp

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -160,11 +160,13 @@ namespace ValueFlow
160160
value.setKnown();
161161
setTokenValue(tok, std::move(value), settings);
162162
} else if (Token::simpleMatch(tok, "sizeof (")) {
163-
if (tok->next()->astOperand2() && !tok->next()->astOperand2()->isLiteral() && tok->next()->astOperand2()->valueType() &&
164-
(tok->next()->astOperand2()->valueType()->pointer == 0 || // <- TODO this is a bailout, abort when there are array->pointer conversions
165-
(tok->next()->astOperand2()->variable() && !tok->next()->astOperand2()->variable()->isArray())) &&
166-
!tok->next()->astOperand2()->valueType()->isEnum()) { // <- TODO this is a bailout, handle enum with non-int types
167-
const size_t sz = tok->next()->astOperand2()->valueType()->getSizeOf(settings, ValueType::Accuracy::ExactOrZero, ValueType::SizeOf::Pointer);
163+
const Token* const obj = tok->next()->astOperand2();
164+
if (obj && !obj->isLiteral() && obj->valueType() &&
165+
(obj->valueType()->pointer == 0 || // <- TODO this is a bailout, abort when there are array->pointer conversions
166+
(obj->variable() && !obj->variable()->isArray())) &&
167+
!obj->valueType()->isEnum()) { // <- TODO this is a bailout, handle enum with non-int types
168+
const auto ptrPointee = obj->valueType()->pointer > 0 ? ValueType::SizeOf::Pointer : ValueType::SizeOf::Pointee;
169+
const size_t sz = obj->valueType()->getSizeOf(settings, ValueType::Accuracy::ExactOrZero, ptrPointee);
168170
if (sz) {
169171
Value value(sz);
170172
value.setKnown();

test/testvalueflow.cpp

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1396,6 +1396,30 @@ class TestValueFlow : public TestFixture {
13961396
ASSERT_EQUALS(1U, values.size());
13971397
ASSERT_EQUALS(4, values.back().intvalue);
13981398

1399+
code = "char& r = i;\n"
1400+
"sizeof(r);";
1401+
values = tokenValues(code, "( r");
1402+
ASSERT_EQUALS(1U, values.size());
1403+
ASSERT_EQUALS(1, values.back().intvalue);
1404+
1405+
code = "char* p;\n"
1406+
"sizeof(p);";
1407+
values = tokenValues(code, "( p");
1408+
ASSERT_EQUALS(1U, values.size());
1409+
ASSERT_EQUALS(settings.platform.sizeof_pointer, values.back().intvalue);
1410+
1411+
code = "char*& pr = p;\n"
1412+
"sizeof(pr);";
1413+
values = tokenValues(code, "( pr");
1414+
ASSERT_EQUALS(1U, values.size());
1415+
ASSERT_EQUALS(settings.platform.sizeof_pointer, values.back().intvalue);
1416+
1417+
code = "struct { char& r; char* p; } s{ x, y };\n"
1418+
"sizeof(s);\n";
1419+
values = tokenValues(code, "( s");
1420+
ASSERT_EQUALS(1U, values.size());
1421+
ASSERT_EQUALS(2 * settings.platform.sizeof_pointer, values.back().intvalue);
1422+
13991423
#define CHECK3(A, B, C) \
14001424
do { \
14011425
code = "void f() {\n" \

0 commit comments

Comments
 (0)