Skip to content

Commit e450f98

Browse files
authored
[lldb] Fix Scalar::GetData for non-multiple-of-8-bits values (#90846)
It was aligning the byte size down. Now it aligns up. This manifested itself as SBTypeStaticField::GetConstantValue returning a zero-sized value for `bool` fields (because clang represents bool as a 1-bit value). I've changed the code for float Scalars as well, although I'm not aware of floating point values that are not multiples of 8 bits.
1 parent b03e7a5 commit e450f98

File tree

4 files changed

+46
-2
lines changed

4 files changed

+46
-2
lines changed

lldb/source/Utility/Scalar.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -134,9 +134,9 @@ size_t Scalar::GetByteSize() const {
134134
case e_void:
135135
break;
136136
case e_int:
137-
return (m_integer.getBitWidth() / 8);
137+
return (m_integer.getBitWidth() + 7) / 8;
138138
case e_float:
139-
return m_float.bitcastToAPInt().getBitWidth() / 8;
139+
return (m_float.bitcastToAPInt().getBitWidth() + 7) / 8;
140140
}
141141
return 0;
142142
}

lldb/test/API/python_api/type/TestTypeList.py

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -52,6 +52,19 @@ def _find_static_field_in_Task_pointer(self, task_pointer):
5252
self.DebugSBValue(value)
5353
self.assertEqual(value.GetValueAsSigned(), 47)
5454

55+
static_constexpr_bool_field = task_type.GetStaticFieldWithName(
56+
"static_constexpr_bool_field"
57+
)
58+
self.assertTrue(static_constexpr_bool_field)
59+
self.assertEqual(
60+
static_constexpr_bool_field.GetName(), "static_constexpr_bool_field"
61+
)
62+
self.assertEqual(static_constexpr_bool_field.GetType().GetName(), "const bool")
63+
64+
value = static_constexpr_bool_field.GetConstantValue(self.target())
65+
self.DebugSBValue(value)
66+
self.assertEqual(value.GetValueAsUnsigned(), 1)
67+
5568
static_mutable_field = task_type.GetStaticFieldWithName("static_mutable_field")
5669
self.assertTrue(static_mutable_field)
5770
self.assertEqual(static_mutable_field.GetName(), "static_mutable_field")

lldb/test/API/python_api/type/main.cpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@ class Task {
2828
union U {
2929
} u;
3030
static constexpr long static_constexpr_field = 47;
31+
static constexpr bool static_constexpr_bool_field = true;
3132
static int static_mutable_field;
3233
Task(int i, Task *n):
3334
id(i),

lldb/unittests/Utility/ScalarTest.cpp

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,8 +13,11 @@
1313
#include "lldb/Utility/Scalar.h"
1414
#include "lldb/Utility/Status.h"
1515
#include "lldb/Utility/StreamString.h"
16+
#include "lldb/lldb-enumerations.h"
17+
#include "llvm/ADT/APSInt.h"
1618
#include "llvm/Testing/Support/Error.h"
1719

20+
#include <algorithm>
1821
#include <cmath>
1922

2023
using namespace lldb_private;
@@ -163,6 +166,33 @@ TEST(ScalarTest, GetBytes) {
163166
ASSERT_EQ(0, memcmp(f, Storage, sizeof(f)));
164167
}
165168

169+
TEST(ScalarTest, GetData) {
170+
auto get_data = [](llvm::APSInt v) {
171+
DataExtractor data;
172+
Scalar(v).GetData(data);
173+
return data.GetData().vec();
174+
};
175+
176+
auto vec = [](std::initializer_list<uint8_t> l) {
177+
std::vector<uint8_t> v(l.begin(), l.end());
178+
if (endian::InlHostByteOrder() == lldb::eByteOrderLittle)
179+
std::reverse(v.begin(), v.end());
180+
return v;
181+
};
182+
183+
EXPECT_THAT(
184+
get_data(llvm::APSInt::getMaxValue(/*numBits=*/1, /*Unsigned=*/true)),
185+
vec({0x01}));
186+
187+
EXPECT_THAT(
188+
get_data(llvm::APSInt::getMaxValue(/*numBits=*/8, /*Unsigned=*/true)),
189+
vec({0xff}));
190+
191+
EXPECT_THAT(
192+
get_data(llvm::APSInt::getMaxValue(/*numBits=*/9, /*Unsigned=*/true)),
193+
vec({0x01, 0xff}));
194+
}
195+
166196
TEST(ScalarTest, SetValueFromData) {
167197
uint8_t a[] = {1, 2, 3, 4};
168198
Scalar s;

0 commit comments

Comments
 (0)