Skip to content

Commit

Permalink
[lldb] Fix Scalar::GetData for non-multiple-of-8-bits values (#90846)
Browse files Browse the repository at this point in the history
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.
  • Loading branch information
labath committed May 3, 2024
1 parent b03e7a5 commit e450f98
Show file tree
Hide file tree
Showing 4 changed files with 46 additions and 2 deletions.
4 changes: 2 additions & 2 deletions lldb/source/Utility/Scalar.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -134,9 +134,9 @@ size_t Scalar::GetByteSize() const {
case e_void:
break;
case e_int:
return (m_integer.getBitWidth() / 8);
return (m_integer.getBitWidth() + 7) / 8;
case e_float:
return m_float.bitcastToAPInt().getBitWidth() / 8;
return (m_float.bitcastToAPInt().getBitWidth() + 7) / 8;
}
return 0;
}
Expand Down
13 changes: 13 additions & 0 deletions lldb/test/API/python_api/type/TestTypeList.py
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,19 @@ def _find_static_field_in_Task_pointer(self, task_pointer):
self.DebugSBValue(value)
self.assertEqual(value.GetValueAsSigned(), 47)

static_constexpr_bool_field = task_type.GetStaticFieldWithName(
"static_constexpr_bool_field"
)
self.assertTrue(static_constexpr_bool_field)
self.assertEqual(
static_constexpr_bool_field.GetName(), "static_constexpr_bool_field"
)
self.assertEqual(static_constexpr_bool_field.GetType().GetName(), "const bool")

value = static_constexpr_bool_field.GetConstantValue(self.target())
self.DebugSBValue(value)
self.assertEqual(value.GetValueAsUnsigned(), 1)

static_mutable_field = task_type.GetStaticFieldWithName("static_mutable_field")
self.assertTrue(static_mutable_field)
self.assertEqual(static_mutable_field.GetName(), "static_mutable_field")
Expand Down
1 change: 1 addition & 0 deletions lldb/test/API/python_api/type/main.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ class Task {
union U {
} u;
static constexpr long static_constexpr_field = 47;
static constexpr bool static_constexpr_bool_field = true;
static int static_mutable_field;
Task(int i, Task *n):
id(i),
Expand Down
30 changes: 30 additions & 0 deletions lldb/unittests/Utility/ScalarTest.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -13,8 +13,11 @@
#include "lldb/Utility/Scalar.h"
#include "lldb/Utility/Status.h"
#include "lldb/Utility/StreamString.h"
#include "lldb/lldb-enumerations.h"
#include "llvm/ADT/APSInt.h"
#include "llvm/Testing/Support/Error.h"

#include <algorithm>
#include <cmath>

using namespace lldb_private;
Expand Down Expand Up @@ -163,6 +166,33 @@ TEST(ScalarTest, GetBytes) {
ASSERT_EQ(0, memcmp(f, Storage, sizeof(f)));
}

TEST(ScalarTest, GetData) {
auto get_data = [](llvm::APSInt v) {
DataExtractor data;
Scalar(v).GetData(data);
return data.GetData().vec();
};

auto vec = [](std::initializer_list<uint8_t> l) {
std::vector<uint8_t> v(l.begin(), l.end());
if (endian::InlHostByteOrder() == lldb::eByteOrderLittle)
std::reverse(v.begin(), v.end());
return v;
};

EXPECT_THAT(
get_data(llvm::APSInt::getMaxValue(/*numBits=*/1, /*Unsigned=*/true)),
vec({0x01}));

EXPECT_THAT(
get_data(llvm::APSInt::getMaxValue(/*numBits=*/8, /*Unsigned=*/true)),
vec({0xff}));

EXPECT_THAT(
get_data(llvm::APSInt::getMaxValue(/*numBits=*/9, /*Unsigned=*/true)),
vec({0x01, 0xff}));
}

TEST(ScalarTest, SetValueFromData) {
uint8_t a[] = {1, 2, 3, 4};
Scalar s;
Expand Down

0 comments on commit e450f98

Please sign in to comment.