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
