[Lldb-commits] [lldb] [LLDB] Add assignment to DIL. (PR #190223)

via lldb-commits lldb-commits at lists.llvm.org
Wed Jun 3 08:49:32 PDT 2026


================
@@ -1227,87 +1227,83 @@ llvm::Expected<bool> ValueObject::GetValueAsBool() {
   return llvm::createStringError("type cannot be converted to bool");
 }
 
-void ValueObject::SetValueFromInteger(const llvm::APInt &value, Status &error,
-                                      bool can_update_var) {
+llvm::Error ValueObject::SetValueFromInteger(const llvm::APInt &value,
+                                             bool can_update_var) {
   // Verify the current object is an integer object
   CompilerType val_type = GetCompilerType();
   if (!val_type.IsInteger() && !val_type.IsUnscopedEnumerationType() &&
       !HasFloatingRepresentation(val_type) && !val_type.IsPointerType() &&
-      !val_type.IsScalarType()) {
-    error =
-        Status::FromErrorString("current value object is not an scalar object");
-    return;
-  }
+      !val_type.IsScalarType())
+    return llvm::createStringError(
+        "current value object is not an scalar object");
 
   // Verify, if current object is associated with a program variable, that
   // we are allowing updating program variables in this case.
-  if (GetVariable() && !can_update_var) {
-    error = Status::FromErrorString(
+  if (GetVariable() && !can_update_var)
+    return llvm::createStringError(
         "Not allowed to update program variables in this case.");
-    return;
-  }
+
+  // Make sure we're not trying to assign to a constant.
+  if (GetIsConstant())
+    return llvm::createStringError(
+        "current value is not assignable (a constant)");
 
   // Verify the proposed new value is the right size.
   lldb::TargetSP target = GetTargetSP();
   uint64_t byte_size = 0;
-  if (auto temp =
-          llvm::expectedToOptional(GetCompilerType().GetByteSize(target.get())))
-    byte_size = temp.value();
-  if (value.getBitWidth() != byte_size * CHAR_BIT) {
-    error = Status::FromErrorString(
-        "illegal argument: new value should be of the same size");
-    return;
+  // Exclude size check when assigning an integer 1 or 0 to a boolean.
+  if (!val_type.IsBoolean() || (!value.isOne() && !value.isZero())) {
+    byte_size = llvm::expectedToOptional(GetByteSize()).value_or(0);
+    if (value.getBitWidth() > byte_size * CHAR_BIT) {
+      // The type is too big, but maybe the value itself is small enough?
+      uint64_t u_max = (1 << (byte_size * CHAR_BIT)) - 1;
+      if (*(value.getRawData()) > u_max)
+        return llvm::createStringError(
+            "illegal argument: new value is too big");
+    }
   }
 
+  Status error;
   lldb::DataExtractorSP data_sp = std::make_shared<DataExtractor>(
       reinterpret_cast<const void *>(value.getRawData()), byte_size,
       target->GetArchitecture().GetByteOrder(),
       static_cast<uint8_t>(target->GetArchitecture().GetAddressByteSize()));
   SetData(*data_sp, error);
+  return error.takeError();
 }
 
-void ValueObject::SetValueFromInteger(lldb::ValueObjectSP new_val_sp,
-                                      Status &error, bool can_update_var) {
+llvm::Error ValueObject::SetValueFromInteger(lldb::ValueObjectSP new_val_sp,
+                                             bool can_update_var) {
   // Verify the current object is an integer object
   CompilerType val_type = GetCompilerType();
   if (!val_type.IsInteger() && !val_type.IsUnscopedEnumerationType() &&
       !HasFloatingRepresentation(val_type) && !val_type.IsPointerType() &&
-      !val_type.IsScalarType()) {
-    error =
-        Status::FromErrorString("current value object is not an scalar object");
-    return;
-  }
+      !val_type.IsScalarType())
+    return llvm::createStringError(
+        "current value object is not an scalar object");
 
   // Verify, if current object is associated with a program variable, that
   // we are allowing updating program variables in this case.
-  if (GetVariable() && !can_update_var) {
-    error = Status::FromErrorString(
+  if (GetVariable() && !can_update_var)
+    return llvm::createStringError(
         "Not allowed to update program variables in this case.");
-    return;
-  }
 
   // Verify the proposed new value is the right type.
   CompilerType new_val_type = new_val_sp->GetCompilerType();
-  if (!new_val_type.IsInteger() && !HasFloatingRepresentation(new_val_type) &&
-      !new_val_type.IsPointerType()) {
-    error = Status::FromErrorString(
-        "illegal argument: new value should be of the same size");
-    return;
-  }
+  if (!new_val_type.IsInteger() && !new_val_type.IsUnscopedEnumerationType() &&
+      !HasFloatingRepresentation(new_val_type) && !new_val_type.IsPointerType())
+    return llvm::createStringError(
+        "illegal argument: new value is not a scalar object");
----------------
cmtice wrote:

It should make sense to the user; this method is only called when trying to update the value of a ValueObject.  I can't imagine such a use where the user would not understand what is meant by "new value".

https://github.com/llvm/llvm-project/pull/190223


More information about the lldb-commits mailing list