Author: Ilia Kuklin
Date: 2026-05-13T16:44:07+05:00
New Revision: aaad6a201f0f13762c45727faacf5347be577a23

URL: 
https://github.com/llvm/llvm-project/commit/aaad6a201f0f13762c45727faacf5347be577a23
DIFF: 
https://github.com/llvm/llvm-project/commit/aaad6a201f0f13762c45727faacf5347be577a23.diff

LOG: [lldb] Fix casting from float in `ValueObject::CastToEnumType` (#191908)

Fix how enum's underlying type sign is retrieved and adjust error
messaging.

Added: 
    

Modified: 
    lldb/source/ValueObject/ValueObject.cpp
    lldb/test/API/commands/frame/var-dil/expr/Casts/TestFrameVarDILCast.py
    lldb/test/API/commands/frame/var-dil/expr/Casts/main.cpp

Removed: 
    


################################################################################
diff  --git a/lldb/source/ValueObject/ValueObject.cpp 
b/lldb/source/ValueObject/ValueObject.cpp
index 802790c09834c..6c28f20d26f77 100644
--- a/lldb/source/ValueObject/ValueObject.cpp
+++ b/lldb/source/ValueObject/ValueObject.cpp
@@ -3338,7 +3338,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) {
@@ -3350,15 +3351,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::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();

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
 }


        
_______________________________________________
lldb-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits

Reply via email to