https://github.com/kuilpd updated 
https://github.com/llvm/llvm-project/pull/217431

>From 2ad48088a09b26ae8fc0bad1313a6674d3ca92d6 Mon Sep 17 00:00:00 2001
From: Ilia Kuklin <[email protected]>
Date: Wed, 19 Aug 2026 21:34:00 +0500
Subject: [PATCH 1/3] [lldb] Redo error handling in ValueObject's
 CastToBasicType and CastToEnumType

---
 lldb/include/lldb/ValueObject/ValueObject.h   |   4 +-
 lldb/source/ValueObject/DILEval.cpp           |  47 ++++++--
 lldb/source/ValueObject/ValueObject.cpp       | 112 +++++++-----------
 .../var-dil/expr/Casts/TestFrameVarDILCast.py |  14 +++
 4 files changed, 94 insertions(+), 83 deletions(-)

diff --git a/lldb/include/lldb/ValueObject/ValueObject.h 
b/lldb/include/lldb/ValueObject/ValueObject.h
index c370993d372b7..5d35c30bcf262 100644
--- a/lldb/include/lldb/ValueObject/ValueObject.h
+++ b/lldb/include/lldb/ValueObject/ValueObject.h
@@ -667,11 +667,11 @@ class ValueObject {
 
   // Take a ValueObject that contains a scalar, enum or pointer type, and
   // cast it to a "basic" type (integer, float or boolean).
-  lldb::ValueObjectSP CastToBasicType(CompilerType type);
+  llvm::Expected<lldb::ValueObjectSP> CastToBasicType(CompilerType type);
 
   // Take a ValueObject that contain an integer, float or enum, and cast it
   // to an enum.
-  lldb::ValueObjectSP CastToEnumType(CompilerType type);
+  llvm::Expected<lldb::ValueObjectSP> CastToEnumType(CompilerType type);
 
   /// If this object represents a C++ class with a vtable, return an object
   /// that represents the virtual function table. If the object isn't a class
diff --git a/lldb/source/ValueObject/DILEval.cpp 
b/lldb/source/ValueObject/DILEval.cpp
index d448444b43eba..c196509850a6a 100644
--- a/lldb/source/ValueObject/DILEval.cpp
+++ b/lldb/source/ValueObject/DILEval.cpp
@@ -88,10 +88,20 @@ Interpreter::UnaryConversion(lldb::ValueObjectSP valobj, 
uint32_t location) {
       if (!uint_bit_size)
         return uint_bit_size.takeError();
       if (bitfield_size < *int_bit_size ||
-          (in_type.IsSigned() && bitfield_size == *int_bit_size))
-        return valobj->CastToBasicType(int_type);
-      if (bitfield_size <= *uint_bit_size)
-        return valobj->CastToBasicType(uint_type);
+          (in_type.IsSigned() && bitfield_size == *int_bit_size)) {
+        auto value_or_err = valobj->CastToBasicType(int_type);
+        if (!value_or_err)
+          return llvm::make_error<DILDiagnosticError>(
+              m_expr, llvm::toString(value_or_err.takeError()), location);
+        return *value_or_err;
+      }
+      if (bitfield_size <= *uint_bit_size) {
+        auto value_or_err = valobj->CastToBasicType(uint_type);
+        if (!value_or_err)
+          return llvm::make_error<DILDiagnosticError>(
+              m_expr, llvm::toString(value_or_err.takeError()), location);
+        return *value_or_err;
+      }
       // Re-create as a const value with the same underlying type
       Scalar scalar;
       bool resolved = valobj->ResolveValue(scalar);
@@ -107,8 +117,13 @@ Interpreter::UnaryConversion(lldb::ValueObjectSP valobj, 
uint32_t location) {
 
   CompilerType promoted_type =
       valobj->GetCompilerType().GetPromotedIntegerType();
-  if (promoted_type)
-    return valobj->CastToBasicType(promoted_type);
+  if (promoted_type) {
+    auto value_or_err = valobj->CastToBasicType(promoted_type);
+    if (!value_or_err)
+      return llvm::make_error<DILDiagnosticError>(
+          m_expr, llvm::toString(value_or_err.takeError()), location);
+    return *value_or_err;
+  }
 
   return valobj;
 }
@@ -1933,14 +1948,26 @@ llvm::Expected<lldb::ValueObjectSP> 
Interpreter::Visit(const CastNode &node) {
   case CastKind::eEnumeration: {
     // FIXME: is this correct for float vector types?
     if (op_type.GetTypeInfo() & lldb::eTypeIsFloat || op_type.IsInteger() ||
-        op_type.IsEnumerationType())
-      return operand->CastToEnumType(target_type);
+        op_type.IsEnumerationType()) {
+      auto value_or_err = operand->CastToEnumType(target_type);
+      if (!value_or_err)
+        return llvm::make_error<DILDiagnosticError>(
+            m_expr, llvm::toString(value_or_err.takeError()),
+            node.GetLocation());
+      return *value_or_err;
+    }
     break;
   }
   case CastKind::eArithmetic: {
     if (op_type.IsPointerType() || op_type.IsNullPtrType() ||
-        op_type.IsScalarType() || op_type.IsEnumerationType())
-      return operand->CastToBasicType(target_type);
+        op_type.IsScalarType() || op_type.IsEnumerationType()) {
+      auto value_or_err = operand->CastToBasicType(target_type);
+      if (!value_or_err)
+        return llvm::make_error<DILDiagnosticError>(
+            m_expr, llvm::toString(value_or_err.takeError()),
+            node.GetLocation());
+      return *value_or_err;
+    }
     break;
   }
   case CastKind::ePointer: {
diff --git a/lldb/source/ValueObject/ValueObject.cpp 
b/lldb/source/ValueObject/ValueObject.cpp
index 5571507a7d545..39516d3359b1a 100644
--- a/lldb/source/ValueObject/ValueObject.cpp
+++ b/lldb/source/ValueObject/ValueObject.cpp
@@ -3190,7 +3190,8 @@ ValueObject::CastBaseToDerivedType(CompilerType type, 
uint64_t offset) {
   return value->Dereference(error);
 }
 
-lldb::ValueObjectSP ValueObject::CastToBasicType(CompilerType type) {
+llvm::Expected<lldb::ValueObjectSP>
+ValueObject::CastToBasicType(CompilerType type) {
   bool is_scalar = GetCompilerType().IsScalarType();
   bool is_enum = GetCompilerType().IsEnumerationType();
   bool is_pointer =
@@ -3200,14 +3201,11 @@ lldb::ValueObjectSP 
ValueObject::CastToBasicType(CompilerType type) {
   ExecutionContext exe_ctx(GetExecutionContextRef());
 
   if (!type.IsScalarType())
-    return ValueObjectConstResult::Create(
-        exe_ctx.GetBestExecutionContextScope(),
-        Status::FromErrorString("target type must be a scalar"));
+    return llvm::createStringError("target type must be a scalar");
 
   if (!is_scalar && !is_enum && !is_pointer)
-    return ValueObjectConstResult::Create(
-        exe_ctx.GetBestExecutionContextScope(),
-        Status::FromErrorString("argument must be a scalar, enum, or 
pointer"));
+    return llvm::createStringError(
+        "argument must be a scalar, enum, or pointer");
 
   lldb::TargetSP target = GetTargetSP();
   uint64_t type_byte_size = 0;
@@ -3220,14 +3218,11 @@ lldb::ValueObjectSP 
ValueObject::CastToBasicType(CompilerType type) {
 
   if (is_pointer) {
     if (!type.IsInteger() && !type.IsBoolean())
-      return ValueObjectConstResult::Create(
-          exe_ctx.GetBestExecutionContextScope(),
-          Status::FromErrorString("target type must be an integer or 
boolean"));
+      return llvm::createStringError(
+          "target type must be an integer or boolean");
     if (!type.IsBoolean() && type_byte_size < val_byte_size)
-      return ValueObjectConstResult::Create(
-          exe_ctx.GetBestExecutionContextScope(),
-          Status::FromErrorString(
-              "target type cannot be smaller than the pointer type"));
+      return llvm::createStringError(
+          "target type cannot be smaller than the pointer type");
   }
 
   if (type.IsBoolean()) {
@@ -3242,11 +3237,9 @@ lldb::ValueObjectSP 
ValueObject::CastToBasicType(CompilerType type) {
             exe_ctx, type.GetTypeSystem().GetSharedPointer(),
             !float_value_or_err->isZero(), "result");
       else
-        return ValueObjectConstResult::Create(
-            exe_ctx.GetBestExecutionContextScope(),
-            Status::FromErrorStringWithFormat(
-                "cannot get value as APFloat: %s",
-                llvm::toString(float_value_or_err.takeError()).c_str()));
+        return llvm::createStringErrorV(
+            "cannot get value as APFloat: {0}",
+            llvm::toString(float_value_or_err.takeError()));
     }
   }
 
@@ -3261,11 +3254,9 @@ lldb::ValueObjectSP 
ValueObject::CastToBasicType(CompilerType type) {
         return ValueObject::CreateValueObjectFromAPInt(exe_ctx, ext, type,
                                                        "result");
       } else
-        return ValueObjectConstResult::Create(
-            exe_ctx.GetBestExecutionContextScope(),
-            Status::FromErrorStringWithFormat(
-                "cannot get value as APSInt: %s",
-                llvm::toString(int_value_or_err.takeError()).c_str()));
+        return llvm::createStringErrorV(
+            "cannot get value as APSInt: {0}",
+            llvm::toString(int_value_or_err.takeError()));
     } else if (is_scalar && is_float) {
       llvm::APSInt integer(type_byte_size * CHAR_BIT, !type.IsSigned());
       bool is_exact;
@@ -3278,13 +3269,13 @@ lldb::ValueObjectSP 
ValueObject::CastToBasicType(CompilerType type) {
         // Casting floating point values that are out of bounds of the target
         // type is undefined behaviour.
         if (status & llvm::APFloatBase::opInvalidOp)
-          return ValueObjectConstResult::Create(
-              exe_ctx.GetBestExecutionContextScope(),
-              Status::FromErrorStringWithFormat(
-                  "invalid type cast detected: %s",
-                  llvm::toString(float_value_or_err.takeError()).c_str()));
+          return llvm::createStringError("invalid cast from float to integer");
         return ValueObject::CreateValueObjectFromAPInt(exe_ctx, integer, type,
                                                        "result");
+      } else {
+        return llvm::createStringErrorV(
+            "cannot get value as APFloat: {0}",
+            llvm::toString(float_value_or_err.takeError()));
       }
     }
   }
@@ -3301,11 +3292,9 @@ lldb::ValueObjectSP 
ValueObject::CastToBasicType(CompilerType type) {
         return ValueObject::CreateValueObjectFromAPFloat(exe_ctx, f, type,
                                                          "result");
       } else {
-        return ValueObjectConstResult::Create(
-            exe_ctx.GetBestExecutionContextScope(),
-            Status::FromErrorStringWithFormat(
-                "cannot get value as APSInt: %s",
-                llvm::toString(int_value_or_err.takeError()).c_str()));
+        return llvm::createStringErrorV(
+            "cannot get value as APSInt: {0}",
+            llvm::toString(int_value_or_err.takeError()));
       }
     } else {
       if (is_integer) {
@@ -3317,11 +3306,9 @@ lldb::ValueObjectSP 
ValueObject::CastToBasicType(CompilerType type) {
           return ValueObject::CreateValueObjectFromAPFloat(exe_ctx, f, type,
                                                            "result");
         } else {
-          return ValueObjectConstResult::Create(
-              exe_ctx.GetBestExecutionContextScope(),
-              Status::FromErrorStringWithFormat(
-                  "cannot get value as APSInt: %s",
-                  llvm::toString(int_value_or_err.takeError()).c_str()));
+          return llvm::createStringErrorV(
+              "cannot get value as APSInt: {0}",
+              llvm::toString(int_value_or_err.takeError()));
         }
       }
       if (is_float) {
@@ -3333,37 +3320,30 @@ lldb::ValueObjectSP 
ValueObject::CastToBasicType(CompilerType type) {
           return ValueObject::CreateValueObjectFromAPFloat(exe_ctx, f, type,
                                                            "result");
         } else {
-          return ValueObjectConstResult::Create(
-              exe_ctx.GetBestExecutionContextScope(),
-              Status::FromErrorStringWithFormat(
-                  "cannot get value as APFloat: %s",
-                  llvm::toString(float_value_or_err.takeError()).c_str()));
+          return llvm::createStringErrorV(
+              "cannot get value as APFloat: {0}",
+              llvm::toString(float_value_or_err.takeError()));
         }
       }
     }
   }
 
-  return ValueObjectConstResult::Create(
-      exe_ctx.GetBestExecutionContextScope(),
-      Status::FromErrorString("Unable to perform requested cast"));
+  return llvm::createStringError("Unable to perform requested cast");
 }
 
-lldb::ValueObjectSP ValueObject::CastToEnumType(CompilerType type) {
+llvm::Expected<lldb::ValueObjectSP>
+ValueObject::CastToEnumType(CompilerType type) {
   bool is_enum = GetCompilerType().IsEnumerationType();
   bool is_integer = GetCompilerType().IsInteger();
   bool is_float = HasFloatingRepresentation(GetCompilerType());
   ExecutionContext exe_ctx(GetExecutionContextRef());
 
   if (!is_enum && !is_integer && !is_float)
-    return ValueObjectConstResult::Create(
-        exe_ctx.GetBestExecutionContextScope(),
-        Status::FromErrorString(
-            "argument must be an integer, a float, or an enum"));
+    return llvm::createStringError(
+        "argument must be an integer, a float, or an enum");
 
   if (!type.IsEnumerationType())
-    return ValueObjectConstResult::Create(
-        exe_ctx.GetBestExecutionContextScope(),
-        Status::FromErrorString("target type must be an enum"));
+    return llvm::createStringError("target type must be an enum");
 
   lldb::TargetSP target = GetTargetSP();
   uint64_t byte_size = 0;
@@ -3382,17 +3362,12 @@ lldb::ValueObjectSP 
ValueObject::CastToEnumType(CompilerType type) {
       // Casting floating point values that are out of bounds of the target
       // type is undefined behaviour.
       if (status & llvm::APFloatBase::opInvalidOp)
-        return ValueObjectConstResult::Create(
-            exe_ctx.GetBestExecutionContextScope(),
-            Status::FromErrorString("invalid cast from float to integer"));
+        return llvm::createStringError("invalid cast from float to integer");
       return ValueObject::CreateValueObjectFromAPInt(exe_ctx, integer, type,
                                                      "result");
     } else
-      return ValueObjectConstResult::Create(
-          exe_ctx.GetBestExecutionContextScope(),
-          Status::FromErrorStringWithFormatv(
-              "cannot get value as APFloat: {0}",
-              llvm::toString(value_or_err.takeError())));
+      return llvm::createStringErrorV("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();
@@ -3401,15 +3376,10 @@ lldb::ValueObjectSP 
ValueObject::CastToEnumType(CompilerType type) {
       return ValueObject::CreateValueObjectFromAPInt(exe_ctx, ext, type,
                                                      "result");
     } else
-      return ValueObjectConstResult::Create(
-          exe_ctx.GetBestExecutionContextScope(),
-          Status::FromErrorStringWithFormat(
-              "cannot get value as APSInt: %s",
-              llvm::toString(value_or_err.takeError()).c_str()));
+      return llvm::createStringErrorV("cannot get value as APSInt: {0}",
+                                      
llvm::toString(value_or_err.takeError()));
   }
-  return ValueObjectConstResult::Create(
-      exe_ctx.GetBestExecutionContextScope(),
-      Status::FromErrorString("Cannot perform requested cast"));
+  return llvm::createStringError("Cannot perform requested cast");
 }
 
 ValueObject::EvaluationPoint::EvaluationPoint() : m_mod_id(), m_exe_ctx_ref() 
{}
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 567981cd670e9..7bde0e91cada8 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
@@ -322,3 +322,17 @@ def test_type_cast(self):
             error=True,
             substrs=["Cast from 'InnerFoo' to 'UnscopedEnum' is not allowed"],
         )
+
+        # Check that failed casts output errors with diagnostics
+        self.expect(
+            "script lldb.frame.GetValueForVariablePath('+(int) finf')",
+            substrs=["<user expression>:1:2: invalid cast from float to 
integer"],
+        )
+        self.expect(
+            "script lldb.frame.GetValueForVariablePath('+(float) *((int *) 
0)')",
+            substrs=["<user expression>:1:2: cannot get value as APSInt"],
+        )
+        self.expect(
+            "script lldb.frame.GetValueForVariablePath('+(UnscopedEnum) 
*((float *) 0)')",
+            substrs=["<user expression>:1:2: cannot get value as APFloat"],
+        )

>From 594b4cc35a82418d103e98ae0598d10addd7dc1a Mon Sep 17 00:00:00 2001
From: Ilia Kuklin <[email protected]>
Date: Fri, 21 Aug 2026 17:34:29 +0500
Subject: [PATCH 2/3] Revert "[lldb] Redo error handling in ValueObject's
 CastToBasicType and CastToEnumType"

This reverts commit 2ad48088a09b26ae8fc0bad1313a6674d3ca92d6.
---
 lldb/include/lldb/ValueObject/ValueObject.h   |   4 +-
 lldb/source/ValueObject/DILEval.cpp           |  47 ++------
 lldb/source/ValueObject/ValueObject.cpp       | 112 +++++++++++-------
 .../var-dil/expr/Casts/TestFrameVarDILCast.py |  14 ---
 4 files changed, 83 insertions(+), 94 deletions(-)

diff --git a/lldb/include/lldb/ValueObject/ValueObject.h 
b/lldb/include/lldb/ValueObject/ValueObject.h
index 5d35c30bcf262..c370993d372b7 100644
--- a/lldb/include/lldb/ValueObject/ValueObject.h
+++ b/lldb/include/lldb/ValueObject/ValueObject.h
@@ -667,11 +667,11 @@ class ValueObject {
 
   // Take a ValueObject that contains a scalar, enum or pointer type, and
   // cast it to a "basic" type (integer, float or boolean).
-  llvm::Expected<lldb::ValueObjectSP> CastToBasicType(CompilerType type);
+  lldb::ValueObjectSP CastToBasicType(CompilerType type);
 
   // Take a ValueObject that contain an integer, float or enum, and cast it
   // to an enum.
-  llvm::Expected<lldb::ValueObjectSP> CastToEnumType(CompilerType type);
+  lldb::ValueObjectSP CastToEnumType(CompilerType type);
 
   /// If this object represents a C++ class with a vtable, return an object
   /// that represents the virtual function table. If the object isn't a class
diff --git a/lldb/source/ValueObject/DILEval.cpp 
b/lldb/source/ValueObject/DILEval.cpp
index c196509850a6a..d448444b43eba 100644
--- a/lldb/source/ValueObject/DILEval.cpp
+++ b/lldb/source/ValueObject/DILEval.cpp
@@ -88,20 +88,10 @@ Interpreter::UnaryConversion(lldb::ValueObjectSP valobj, 
uint32_t location) {
       if (!uint_bit_size)
         return uint_bit_size.takeError();
       if (bitfield_size < *int_bit_size ||
-          (in_type.IsSigned() && bitfield_size == *int_bit_size)) {
-        auto value_or_err = valobj->CastToBasicType(int_type);
-        if (!value_or_err)
-          return llvm::make_error<DILDiagnosticError>(
-              m_expr, llvm::toString(value_or_err.takeError()), location);
-        return *value_or_err;
-      }
-      if (bitfield_size <= *uint_bit_size) {
-        auto value_or_err = valobj->CastToBasicType(uint_type);
-        if (!value_or_err)
-          return llvm::make_error<DILDiagnosticError>(
-              m_expr, llvm::toString(value_or_err.takeError()), location);
-        return *value_or_err;
-      }
+          (in_type.IsSigned() && bitfield_size == *int_bit_size))
+        return valobj->CastToBasicType(int_type);
+      if (bitfield_size <= *uint_bit_size)
+        return valobj->CastToBasicType(uint_type);
       // Re-create as a const value with the same underlying type
       Scalar scalar;
       bool resolved = valobj->ResolveValue(scalar);
@@ -117,13 +107,8 @@ Interpreter::UnaryConversion(lldb::ValueObjectSP valobj, 
uint32_t location) {
 
   CompilerType promoted_type =
       valobj->GetCompilerType().GetPromotedIntegerType();
-  if (promoted_type) {
-    auto value_or_err = valobj->CastToBasicType(promoted_type);
-    if (!value_or_err)
-      return llvm::make_error<DILDiagnosticError>(
-          m_expr, llvm::toString(value_or_err.takeError()), location);
-    return *value_or_err;
-  }
+  if (promoted_type)
+    return valobj->CastToBasicType(promoted_type);
 
   return valobj;
 }
@@ -1948,26 +1933,14 @@ llvm::Expected<lldb::ValueObjectSP> 
Interpreter::Visit(const CastNode &node) {
   case CastKind::eEnumeration: {
     // FIXME: is this correct for float vector types?
     if (op_type.GetTypeInfo() & lldb::eTypeIsFloat || op_type.IsInteger() ||
-        op_type.IsEnumerationType()) {
-      auto value_or_err = operand->CastToEnumType(target_type);
-      if (!value_or_err)
-        return llvm::make_error<DILDiagnosticError>(
-            m_expr, llvm::toString(value_or_err.takeError()),
-            node.GetLocation());
-      return *value_or_err;
-    }
+        op_type.IsEnumerationType())
+      return operand->CastToEnumType(target_type);
     break;
   }
   case CastKind::eArithmetic: {
     if (op_type.IsPointerType() || op_type.IsNullPtrType() ||
-        op_type.IsScalarType() || op_type.IsEnumerationType()) {
-      auto value_or_err = operand->CastToBasicType(target_type);
-      if (!value_or_err)
-        return llvm::make_error<DILDiagnosticError>(
-            m_expr, llvm::toString(value_or_err.takeError()),
-            node.GetLocation());
-      return *value_or_err;
-    }
+        op_type.IsScalarType() || op_type.IsEnumerationType())
+      return operand->CastToBasicType(target_type);
     break;
   }
   case CastKind::ePointer: {
diff --git a/lldb/source/ValueObject/ValueObject.cpp 
b/lldb/source/ValueObject/ValueObject.cpp
index 39516d3359b1a..5571507a7d545 100644
--- a/lldb/source/ValueObject/ValueObject.cpp
+++ b/lldb/source/ValueObject/ValueObject.cpp
@@ -3190,8 +3190,7 @@ ValueObject::CastBaseToDerivedType(CompilerType type, 
uint64_t offset) {
   return value->Dereference(error);
 }
 
-llvm::Expected<lldb::ValueObjectSP>
-ValueObject::CastToBasicType(CompilerType type) {
+lldb::ValueObjectSP ValueObject::CastToBasicType(CompilerType type) {
   bool is_scalar = GetCompilerType().IsScalarType();
   bool is_enum = GetCompilerType().IsEnumerationType();
   bool is_pointer =
@@ -3201,11 +3200,14 @@ ValueObject::CastToBasicType(CompilerType type) {
   ExecutionContext exe_ctx(GetExecutionContextRef());
 
   if (!type.IsScalarType())
-    return llvm::createStringError("target type must be a scalar");
+    return ValueObjectConstResult::Create(
+        exe_ctx.GetBestExecutionContextScope(),
+        Status::FromErrorString("target type must be a scalar"));
 
   if (!is_scalar && !is_enum && !is_pointer)
-    return llvm::createStringError(
-        "argument must be a scalar, enum, or pointer");
+    return ValueObjectConstResult::Create(
+        exe_ctx.GetBestExecutionContextScope(),
+        Status::FromErrorString("argument must be a scalar, enum, or 
pointer"));
 
   lldb::TargetSP target = GetTargetSP();
   uint64_t type_byte_size = 0;
@@ -3218,11 +3220,14 @@ ValueObject::CastToBasicType(CompilerType type) {
 
   if (is_pointer) {
     if (!type.IsInteger() && !type.IsBoolean())
-      return llvm::createStringError(
-          "target type must be an integer or boolean");
+      return ValueObjectConstResult::Create(
+          exe_ctx.GetBestExecutionContextScope(),
+          Status::FromErrorString("target type must be an integer or 
boolean"));
     if (!type.IsBoolean() && type_byte_size < val_byte_size)
-      return llvm::createStringError(
-          "target type cannot be smaller than the pointer type");
+      return ValueObjectConstResult::Create(
+          exe_ctx.GetBestExecutionContextScope(),
+          Status::FromErrorString(
+              "target type cannot be smaller than the pointer type"));
   }
 
   if (type.IsBoolean()) {
@@ -3237,9 +3242,11 @@ ValueObject::CastToBasicType(CompilerType type) {
             exe_ctx, type.GetTypeSystem().GetSharedPointer(),
             !float_value_or_err->isZero(), "result");
       else
-        return llvm::createStringErrorV(
-            "cannot get value as APFloat: {0}",
-            llvm::toString(float_value_or_err.takeError()));
+        return ValueObjectConstResult::Create(
+            exe_ctx.GetBestExecutionContextScope(),
+            Status::FromErrorStringWithFormat(
+                "cannot get value as APFloat: %s",
+                llvm::toString(float_value_or_err.takeError()).c_str()));
     }
   }
 
@@ -3254,9 +3261,11 @@ ValueObject::CastToBasicType(CompilerType type) {
         return ValueObject::CreateValueObjectFromAPInt(exe_ctx, ext, type,
                                                        "result");
       } else
-        return llvm::createStringErrorV(
-            "cannot get value as APSInt: {0}",
-            llvm::toString(int_value_or_err.takeError()));
+        return ValueObjectConstResult::Create(
+            exe_ctx.GetBestExecutionContextScope(),
+            Status::FromErrorStringWithFormat(
+                "cannot get value as APSInt: %s",
+                llvm::toString(int_value_or_err.takeError()).c_str()));
     } else if (is_scalar && is_float) {
       llvm::APSInt integer(type_byte_size * CHAR_BIT, !type.IsSigned());
       bool is_exact;
@@ -3269,13 +3278,13 @@ ValueObject::CastToBasicType(CompilerType type) {
         // Casting floating point values that are out of bounds of the target
         // type is undefined behaviour.
         if (status & llvm::APFloatBase::opInvalidOp)
-          return llvm::createStringError("invalid cast from float to integer");
+          return ValueObjectConstResult::Create(
+              exe_ctx.GetBestExecutionContextScope(),
+              Status::FromErrorStringWithFormat(
+                  "invalid type cast detected: %s",
+                  llvm::toString(float_value_or_err.takeError()).c_str()));
         return ValueObject::CreateValueObjectFromAPInt(exe_ctx, integer, type,
                                                        "result");
-      } else {
-        return llvm::createStringErrorV(
-            "cannot get value as APFloat: {0}",
-            llvm::toString(float_value_or_err.takeError()));
       }
     }
   }
@@ -3292,9 +3301,11 @@ ValueObject::CastToBasicType(CompilerType type) {
         return ValueObject::CreateValueObjectFromAPFloat(exe_ctx, f, type,
                                                          "result");
       } else {
-        return llvm::createStringErrorV(
-            "cannot get value as APSInt: {0}",
-            llvm::toString(int_value_or_err.takeError()));
+        return ValueObjectConstResult::Create(
+            exe_ctx.GetBestExecutionContextScope(),
+            Status::FromErrorStringWithFormat(
+                "cannot get value as APSInt: %s",
+                llvm::toString(int_value_or_err.takeError()).c_str()));
       }
     } else {
       if (is_integer) {
@@ -3306,9 +3317,11 @@ ValueObject::CastToBasicType(CompilerType type) {
           return ValueObject::CreateValueObjectFromAPFloat(exe_ctx, f, type,
                                                            "result");
         } else {
-          return llvm::createStringErrorV(
-              "cannot get value as APSInt: {0}",
-              llvm::toString(int_value_or_err.takeError()));
+          return ValueObjectConstResult::Create(
+              exe_ctx.GetBestExecutionContextScope(),
+              Status::FromErrorStringWithFormat(
+                  "cannot get value as APSInt: %s",
+                  llvm::toString(int_value_or_err.takeError()).c_str()));
         }
       }
       if (is_float) {
@@ -3320,30 +3333,37 @@ ValueObject::CastToBasicType(CompilerType type) {
           return ValueObject::CreateValueObjectFromAPFloat(exe_ctx, f, type,
                                                            "result");
         } else {
-          return llvm::createStringErrorV(
-              "cannot get value as APFloat: {0}",
-              llvm::toString(float_value_or_err.takeError()));
+          return ValueObjectConstResult::Create(
+              exe_ctx.GetBestExecutionContextScope(),
+              Status::FromErrorStringWithFormat(
+                  "cannot get value as APFloat: %s",
+                  llvm::toString(float_value_or_err.takeError()).c_str()));
         }
       }
     }
   }
 
-  return llvm::createStringError("Unable to perform requested cast");
+  return ValueObjectConstResult::Create(
+      exe_ctx.GetBestExecutionContextScope(),
+      Status::FromErrorString("Unable to perform requested cast"));
 }
 
-llvm::Expected<lldb::ValueObjectSP>
-ValueObject::CastToEnumType(CompilerType type) {
+lldb::ValueObjectSP ValueObject::CastToEnumType(CompilerType type) {
   bool is_enum = GetCompilerType().IsEnumerationType();
   bool is_integer = GetCompilerType().IsInteger();
   bool is_float = HasFloatingRepresentation(GetCompilerType());
   ExecutionContext exe_ctx(GetExecutionContextRef());
 
   if (!is_enum && !is_integer && !is_float)
-    return llvm::createStringError(
-        "argument must be an integer, a float, or an enum");
+    return ValueObjectConstResult::Create(
+        exe_ctx.GetBestExecutionContextScope(),
+        Status::FromErrorString(
+            "argument must be an integer, a float, or an enum"));
 
   if (!type.IsEnumerationType())
-    return llvm::createStringError("target type must be an enum");
+    return ValueObjectConstResult::Create(
+        exe_ctx.GetBestExecutionContextScope(),
+        Status::FromErrorString("target type must be an enum"));
 
   lldb::TargetSP target = GetTargetSP();
   uint64_t byte_size = 0;
@@ -3362,12 +3382,17 @@ ValueObject::CastToEnumType(CompilerType type) {
       // Casting floating point values that are out of bounds of the target
       // type is undefined behaviour.
       if (status & llvm::APFloatBase::opInvalidOp)
-        return llvm::createStringError("invalid cast from float to integer");
+        return ValueObjectConstResult::Create(
+            exe_ctx.GetBestExecutionContextScope(),
+            Status::FromErrorString("invalid cast from float to integer"));
       return ValueObject::CreateValueObjectFromAPInt(exe_ctx, integer, type,
                                                      "result");
     } else
-      return llvm::createStringErrorV("cannot get value as APFloat: {0}",
-                                      
llvm::toString(value_or_err.takeError()));
+      return ValueObjectConstResult::Create(
+          exe_ctx.GetBestExecutionContextScope(),
+          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();
@@ -3376,10 +3401,15 @@ ValueObject::CastToEnumType(CompilerType type) {
       return ValueObject::CreateValueObjectFromAPInt(exe_ctx, ext, type,
                                                      "result");
     } else
-      return llvm::createStringErrorV("cannot get value as APSInt: {0}",
-                                      
llvm::toString(value_or_err.takeError()));
+      return ValueObjectConstResult::Create(
+          exe_ctx.GetBestExecutionContextScope(),
+          Status::FromErrorStringWithFormat(
+              "cannot get value as APSInt: %s",
+              llvm::toString(value_or_err.takeError()).c_str()));
   }
-  return llvm::createStringError("Cannot perform requested cast");
+  return ValueObjectConstResult::Create(
+      exe_ctx.GetBestExecutionContextScope(),
+      Status::FromErrorString("Cannot perform requested cast"));
 }
 
 ValueObject::EvaluationPoint::EvaluationPoint() : m_mod_id(), m_exe_ctx_ref() 
{}
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 7bde0e91cada8..567981cd670e9 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
@@ -322,17 +322,3 @@ def test_type_cast(self):
             error=True,
             substrs=["Cast from 'InnerFoo' to 'UnscopedEnum' is not allowed"],
         )
-
-        # Check that failed casts output errors with diagnostics
-        self.expect(
-            "script lldb.frame.GetValueForVariablePath('+(int) finf')",
-            substrs=["<user expression>:1:2: invalid cast from float to 
integer"],
-        )
-        self.expect(
-            "script lldb.frame.GetValueForVariablePath('+(float) *((int *) 
0)')",
-            substrs=["<user expression>:1:2: cannot get value as APSInt"],
-        )
-        self.expect(
-            "script lldb.frame.GetValueForVariablePath('+(UnscopedEnum) 
*((float *) 0)')",
-            substrs=["<user expression>:1:2: cannot get value as APFloat"],
-        )

>From 15909773d9e30ca4d6a9f92fcbc8d263395e74d0 Mon Sep 17 00:00:00 2001
From: Ilia Kuklin <[email protected]>
Date: Fri, 21 Aug 2026 18:04:12 +0500
Subject: [PATCH 3/3] [lldb] Handle errors of failed casts in DIL

---
 lldb/source/ValueObject/DILEval.cpp           | 47 ++++++++++++++-----
 lldb/source/ValueObject/ValueObject.cpp       |  9 +++-
 .../var-dil/expr/Casts/TestFrameVarDILCast.py | 38 +++++++++++++++
 3 files changed, 81 insertions(+), 13 deletions(-)

diff --git a/lldb/source/ValueObject/DILEval.cpp 
b/lldb/source/ValueObject/DILEval.cpp
index d448444b43eba..2995abb1bec2b 100644
--- a/lldb/source/ValueObject/DILEval.cpp
+++ b/lldb/source/ValueObject/DILEval.cpp
@@ -88,10 +88,20 @@ Interpreter::UnaryConversion(lldb::ValueObjectSP valobj, 
uint32_t location) {
       if (!uint_bit_size)
         return uint_bit_size.takeError();
       if (bitfield_size < *int_bit_size ||
-          (in_type.IsSigned() && bitfield_size == *int_bit_size))
-        return valobj->CastToBasicType(int_type);
-      if (bitfield_size <= *uint_bit_size)
-        return valobj->CastToBasicType(uint_type);
+          (in_type.IsSigned() && bitfield_size == *int_bit_size)) {
+        auto result = valobj->CastToBasicType(int_type);
+        if (result->GetError().Fail())
+          return llvm::make_error<DILDiagnosticError>(
+              m_expr, result->GetError().AsCString(), location);
+        return result;
+      }
+      if (bitfield_size <= *uint_bit_size) {
+        auto result = valobj->CastToBasicType(uint_type);
+        if (result->GetError().Fail())
+          return llvm::make_error<DILDiagnosticError>(
+              m_expr, result->GetError().AsCString(), location);
+        return result;
+      }
       // Re-create as a const value with the same underlying type
       Scalar scalar;
       bool resolved = valobj->ResolveValue(scalar);
@@ -107,8 +117,13 @@ Interpreter::UnaryConversion(lldb::ValueObjectSP valobj, 
uint32_t location) {
 
   CompilerType promoted_type =
       valobj->GetCompilerType().GetPromotedIntegerType();
-  if (promoted_type)
-    return valobj->CastToBasicType(promoted_type);
+  if (promoted_type) {
+    auto result = valobj->CastToBasicType(promoted_type);
+    if (result->GetError().Fail())
+      return llvm::make_error<DILDiagnosticError>(
+          m_expr, result->GetError().AsCString(), location);
+    return result;
+  }
 
   return valobj;
 }
@@ -1929,18 +1944,19 @@ llvm::Expected<lldb::ValueObjectSP> 
Interpreter::Visit(const CastNode &node) {
                                                   node.GetLocation());
   }
 
+  lldb::ValueObjectSP result;
   switch (cast_kind) {
   case CastKind::eEnumeration: {
     // FIXME: is this correct for float vector types?
     if (op_type.GetTypeInfo() & lldb::eTypeIsFloat || op_type.IsInteger() ||
         op_type.IsEnumerationType())
-      return operand->CastToEnumType(target_type);
+      result = operand->CastToEnumType(target_type);
     break;
   }
   case CastKind::eArithmetic: {
     if (op_type.IsPointerType() || op_type.IsNullPtrType() ||
         op_type.IsScalarType() || op_type.IsEnumerationType())
-      return operand->CastToBasicType(target_type);
+      result = operand->CastToBasicType(target_type);
     break;
   }
   case CastKind::ePointer: {
@@ -1950,15 +1966,24 @@ llvm::Expected<lldb::ValueObjectSP> 
Interpreter::Visit(const CastNode &node) {
                                               : 
operand->GetValueAsUnsigned(0));
     llvm::StringRef name = "result";
     ExecutionContext exe_ctx(m_target.get(), false);
-    return ValueObject::CreateValueObjectFromAddress(name, addr, exe_ctx,
-                                                     target_type,
-                                                     /* do_deref */ false);
+    result = ValueObject::CreateValueObjectFromAddress(name, addr, exe_ctx,
+                                                       target_type,
+                                                       /* do_deref */ false);
+    break;
   }
   case CastKind::eNone: {
     return lldb::ValueObjectSP();
   }
   } // switch
 
+  if (result) {
+    // If cast failed, retrieve the error message from the result.
+    if (result->GetError().Fail())
+      return llvm::make_error<DILDiagnosticError>(
+          m_expr, result->GetError().AsCString(), node.GetLocation());
+    return result;
+  }
+
   std::string errMsg =
       llvm::formatv("unable to cast from '{0}' to '{1}'",
                     op_type.TypeDescription(), target_type.TypeDescription());
diff --git a/lldb/source/ValueObject/ValueObject.cpp 
b/lldb/source/ValueObject/ValueObject.cpp
index 5571507a7d545..b55ef2dd3b0d1 100644
--- a/lldb/source/ValueObject/ValueObject.cpp
+++ b/lldb/source/ValueObject/ValueObject.cpp
@@ -3281,10 +3281,15 @@ lldb::ValueObjectSP 
ValueObject::CastToBasicType(CompilerType type) {
           return ValueObjectConstResult::Create(
               exe_ctx.GetBestExecutionContextScope(),
               Status::FromErrorStringWithFormat(
-                  "invalid type cast detected: %s",
-                  llvm::toString(float_value_or_err.takeError()).c_str()));
+                  "invalid cast from float to integer"));
         return ValueObject::CreateValueObjectFromAPInt(exe_ctx, integer, type,
                                                        "result");
+      } else {
+        return ValueObjectConstResult::Create(
+            exe_ctx.GetBestExecutionContextScope(),
+            Status::FromErrorStringWithFormat(
+                "cannot get value as APFloat: %s",
+                llvm::toString(float_value_or_err.takeError()).c_str()));
       }
     }
   }
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 567981cd670e9..9f56149d94456 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
@@ -322,3 +322,41 @@ def test_type_cast(self):
             error=True,
             substrs=["Cast from 'InnerFoo' to 'UnscopedEnum' is not allowed"],
         )
+
+        # Check that failed casts output errors with diagnostics
+        self.expect(
+            "script lldb.frame.GetValueForVariablePath('+(bool) *((float *) 
0)')",
+            substrs=["<user expression>:1:2: cannot get value as APFloat"],
+        )
+        self.expect(
+            "script lldb.frame.GetValueForVariablePath('+(int) *((int *) 0)')",
+            substrs=["<user expression>:1:2: cannot get value as APSInt"],
+        )
+        self.expect(
+            "script lldb.frame.GetValueForVariablePath('+(int) finf')",
+            substrs=["<user expression>:1:2: invalid cast from float to 
integer"],
+        )
+        self.expect(
+            "script lldb.frame.GetValueForVariablePath('+(int) *((float *) 
0)')",
+            substrs=["<user expression>:1:2: cannot get value as APFloat"],
+        )
+        self.expect(
+            "script lldb.frame.GetValueForVariablePath('+(float) *((int *) 
0)')",
+            substrs=["<user expression>:1:2: cannot get value as APSInt"],
+        )
+        self.expect(
+            "script lldb.frame.GetValueForVariablePath('+(float) *((float *) 
0)')",
+            substrs=["<user expression>:1:2: cannot get value as APFloat"],
+        )
+        self.expect(
+            "script lldb.frame.GetValueForVariablePath('+(UnscopedEnum) 
finf')",
+            substrs=["<user expression>:1:2: invalid cast from float to 
integer"],
+        )
+        self.expect(
+            "script lldb.frame.GetValueForVariablePath('+(UnscopedEnum) 
*((float *) 0)')",
+            substrs=["<user expression>:1:2: cannot get value as APFloat"],
+        )
+        self.expect(
+            "script lldb.frame.GetValueForVariablePath('+(UnscopedEnum) *((int 
*) 0)')",
+            substrs=["<user expression>:1:2: cannot get value as APSInt"],
+        )

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

Reply via email to