[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