[Lldb-commits] [lldb] [lldb] Fix casting from float in `ValueObject::CastToEnumType` (PR #191908)
Ilia Kuklin via lldb-commits
lldb-commits at lists.llvm.org
Sat Apr 18 12:10:53 PDT 2026
https://github.com/kuilpd updated https://github.com/llvm/llvm-project/pull/191908
>From 50d706fa04a6f7546f5e1500eee924380d0562fb Mon Sep 17 00:00:00 2001
From: Ilia Kuklin <ikuklin at accesssoftek.com>
Date: Tue, 14 Apr 2026 04:09:42 +0500
Subject: [PATCH 1/2] [lldb] Fix casting from float in
`ValueObject::CastToEnumType`
---
lldb/source/ValueObject/ValueObject.cpp | 11 ++++++-----
.../var-dil/expr/Casts/TestFrameVarDILCast.py | 15 +++++++++++++++
.../commands/frame/var-dil/expr/Casts/main.cpp | 6 ++++++
3 files changed, 27 insertions(+), 5 deletions(-)
diff --git a/lldb/source/ValueObject/ValueObject.cpp b/lldb/source/ValueObject/ValueObject.cpp
index 37210055af6e9..641d9210ff08c 100644
--- a/lldb/source/ValueObject/ValueObject.cpp
+++ b/lldb/source/ValueObject/ValueObject.cpp
@@ -3322,7 +3322,8 @@ lldb::ValueObjectSP ValueObject::CastToEnumType(CompilerType type) {
byte_size = temp.value();
if (is_float) {
- llvm::APSInt integer(byte_size * CHAR_BIT, !type.IsSigned());
+ llvm::APSInt integer(byte_size * CHAR_BIT,
+ !type.IsEnumerationIntegerTypeSigned());
bool is_exact;
auto value_or_err = GetValueAsAPFloat();
if (value_or_err) {
@@ -3334,15 +3335,15 @@ lldb::ValueObjectSP ValueObject::CastToEnumType(CompilerType type) {
if (status & llvm::APFloatBase::opInvalidOp)
return ValueObjectConstResult::Create(
exe_ctx.GetBestExecutionContextScope(),
- Status::FromErrorStringWithFormat(
- "invalid type cast detected: %s",
- llvm::toString(value_or_err.takeError()).c_str()));
+ Status::FromErrorString("invalid cast from float to integer"));
return ValueObject::CreateValueObjectFromAPInt(exe_ctx, integer, type,
"result");
} else
return ValueObjectConstResult::Create(
exe_ctx.GetBestExecutionContextScope(),
- Status::FromErrorString("cannot get value as APFloat"));
+ Status::FromErrorStringWithFormat(
+ "cannot get value as APFloat: %s",
+ llvm::toString(value_or_err.takeError()).c_str()));
} else {
// Get the value as APSInt and extend or truncate it to the requested size.
auto value_or_err = GetValueAsAPSInt();
diff --git a/lldb/test/API/commands/frame/var-dil/expr/Casts/TestFrameVarDILCast.py b/lldb/test/API/commands/frame/var-dil/expr/Casts/TestFrameVarDILCast.py
index 50affd4ccb03e..77dabbfa800fb 100644
--- a/lldb/test/API/commands/frame/var-dil/expr/Casts/TestFrameVarDILCast.py
+++ b/lldb/test/API/commands/frame/var-dil/expr/Casts/TestFrameVarDILCast.py
@@ -292,3 +292,18 @@ def test_type_cast(self):
legacy = frame.GetValueForVariablePath("(char)a", lldb.eDILModeLegacy)
self.assertFailure(simple.GetError())
self.assertFailure(legacy.GetError())
+
+ # Check enum casting
+ self.expect_var_path("(UnscopedEnum) 0", value="kZero")
+ self.expect_var_path("(UnscopedEnum) ((char) 1)", value="kOne")
+ self.expect_var_path("(UnscopedEnum) 1.5", value="kOne")
+ self.expect_var_path("(UnscopedEnum) enum_one8", value="kOne")
+ self.expect_var_path("(UnscopedEnumInt8) 1ULL", value="kOne8")
+ self.expect_var_path("(UnscopedEnumInt8) -1.5", value="kMinusOne8")
+ self.expect_var_path("(UnscopedEnumInt8) 1.5", value="kOne8")
+ self.expect_var_path("(UnscopedEnumInt8) enum_one", value="kOne8")
+ self.expect(
+ "frame variable '(UnscopedEnum) ifoo'",
+ error=True,
+ substrs=["Cast from 'InnerFoo' to 'UnscopedEnum' is not allowed"],
+ )
diff --git a/lldb/test/API/commands/frame/var-dil/expr/Casts/main.cpp b/lldb/test/API/commands/frame/var-dil/expr/Casts/main.cpp
index 60722f34cde98..e29acbbc9bd36 100644
--- a/lldb/test/API/commands/frame/var-dil/expr/Casts/main.cpp
+++ b/lldb/test/API/commands/frame/var-dil/expr/Casts/main.cpp
@@ -22,6 +22,9 @@ class Foo {};
// Global variable
bool myGlobalName = true;
+enum UnscopedEnum { kZero, kOne, kTwo };
+enum UnscopedEnumInt8 : int8_t { kMinusOne8 = -1, kZero8, kOne8 };
+
int main(int argc, char **argv) {
int a = 1;
int *ap = &a;
@@ -81,5 +84,8 @@ int main(int argc, char **argv) {
struct myGlobalName secondStruct = {42, false};
+ auto enum_one = UnscopedEnum::kOne;
+ auto enum_one8 = UnscopedEnumInt8::kOne8;
+
return 0; // Set a breakpoint here
}
>From e5d74577446894ce386cdefbf1e4f0d5c4db3108 Mon Sep 17 00:00:00 2001
From: Ilia Kuklin <ikuklin at accesssoftek.com>
Date: Sun, 19 Apr 2026 00:09:12 +0500
Subject: [PATCH 2/2] Switch to formatv
---
lldb/source/ValueObject/ValueObject.cpp | 6 +++---
1 file changed, 3 insertions(+), 3 deletions(-)
diff --git a/lldb/source/ValueObject/ValueObject.cpp b/lldb/source/ValueObject/ValueObject.cpp
index 641d9210ff08c..87c913ca819d6 100644
--- a/lldb/source/ValueObject/ValueObject.cpp
+++ b/lldb/source/ValueObject/ValueObject.cpp
@@ -3341,9 +3341,9 @@ lldb::ValueObjectSP ValueObject::CastToEnumType(CompilerType type) {
} else
return ValueObjectConstResult::Create(
exe_ctx.GetBestExecutionContextScope(),
- Status::FromErrorStringWithFormat(
- "cannot get value as APFloat: %s",
- llvm::toString(value_or_err.takeError()).c_str()));
+ Status::FromErrorStringWithFormatv(
+ "cannot get value as APFloat: {0}",
+ llvm::toString(value_or_err.takeError())));
} else {
// Get the value as APSInt and extend or truncate it to the requested size.
auto value_or_err = GetValueAsAPSInt();
More information about the lldb-commits
mailing list