https://github.com/medismailben updated 
https://github.com/llvm/llvm-project/pull/158759

>From 9744d606c8ddc03aeba105c89647af4c009dac28 Mon Sep 17 00:00:00 2001
From: Med Ismail Bennani <ism...@bennani.ma>
Date: Mon, 15 Sep 2025 18:04:48 -0700
Subject: [PATCH] [lldb/API] Mark SBValue with error as invalid

This patch fixes the return value of `SBValue::IsValid` if `GetError`
returns a failing `SBError`.

That alignes better the expectation that an `SBValue` is invalid if it has
an error.

Signed-off-by: Med Ismail Bennani <ism...@bennani.ma>
---
 lldb/source/API/SBValue.cpp                           |  3 ++-
 .../expression/call-throws/TestCallThatThrows.py      | 11 +++++++----
 .../expression/context-object/TestContextObject.py    | 10 +++++-----
 .../test/API/commands/expression/fixits/TestFixIts.py |  2 +-
 .../commands/expression/options/TestExprOptions.py    |  4 ++--
 .../expression/scoped_enums/TestScopedEnumType.py     |  4 ++--
 .../expression/timeout/TestCallWithTimeout.py         |  2 +-
 .../python_api/sbvalue_is_valid/TestSBValueIsValid.py |  3 +++
 lldb/test/API/python_api/sbvalue_is_valid/main.cpp    |  7 +++++++
 9 files changed, 30 insertions(+), 16 deletions(-)
 create mode 100644 
lldb/test/API/python_api/sbvalue_is_valid/TestSBValueIsValid.py
 create mode 100644 lldb/test/API/python_api/sbvalue_is_valid/main.cpp

diff --git a/lldb/source/API/SBValue.cpp b/lldb/source/API/SBValue.cpp
index e300ecee3f8ac..77cc7d1681829 100644
--- a/lldb/source/API/SBValue.cpp
+++ b/lldb/source/API/SBValue.cpp
@@ -97,7 +97,8 @@ class ValueImpl {
       // they depend on.  So I have no good way to make that check without
       // tracking that in all the ValueObject subclasses.
       TargetSP target_sp = m_valobj_sp->GetTargetSP();
-      return target_sp && target_sp->IsValid();
+      return target_sp && target_sp->IsValid() &&
+             m_valobj_sp->GetError().Success();
     }
   }
 
diff --git 
a/lldb/test/API/commands/expression/call-throws/TestCallThatThrows.py 
b/lldb/test/API/commands/expression/call-throws/TestCallThatThrows.py
index 0090513864cd7..4d5e5a36eb72a 100644
--- a/lldb/test/API/commands/expression/call-throws/TestCallThatThrows.py
+++ b/lldb/test/API/commands/expression/call-throws/TestCallThatThrows.py
@@ -45,7 +45,7 @@ def call_function(self):
         self.orig_frame_pc = frame.GetPC()
 
         value = frame.EvaluateExpression("[my_class callMeIThrow]", options)
-        self.assertTrue(value.IsValid())
+        self.assertFalse(value.IsValid())
         self.assertFalse(value.GetError().Success())
 
         self.check_after_call()
@@ -61,7 +61,8 @@ def call_function(self):
 
         value = frame.EvaluateExpression("[my_class callMeIThrow]", options)
 
-        self.assertTrue(value.IsValid() and not value.GetError().Success())
+        self.assertFalse(value.IsValid())
+        self.assertFalse(value.GetError().Success())
         self.check_after_call()
 
         # Now set the ObjC language breakpoint and make sure that doesn't
@@ -76,7 +77,8 @@ def call_function(self):
 
         value = frame.EvaluateExpression("[my_class callMeIThrow]", options)
 
-        self.assertTrue(value.IsValid() and not value.GetError().Success())
+        self.assertFalse(value.IsValid())
+        self.assertFalse(value.GetError().Success())
         self.check_after_call()
 
         # Now turn off exception trapping, and call a function that catches 
the exceptions,
@@ -95,5 +97,6 @@ def call_function(self):
         options.SetUnwindOnError(False)
         value = frame.EvaluateExpression("[my_class callMeIThrow]", options)
 
-        self.assertTrue(value.IsValid() and not value.GetError().Success())
+        self.assertFalse(value.IsValid())
+        self.assertFalse(value.GetError().Success())
         self.check_after_call()
diff --git 
a/lldb/test/API/commands/expression/context-object/TestContextObject.py 
b/lldb/test/API/commands/expression/context-object/TestContextObject.py
index 1ed629a42c1ee..f3b2c3a503592 100644
--- a/lldb/test/API/commands/expression/context-object/TestContextObject.py
+++ b/lldb/test/API/commands/expression/context-object/TestContextObject.py
@@ -69,7 +69,7 @@ def test_context_object(self):
 
         # Test an expression evaluation
         value = obj_val.EvaluateExpression("1")
-        self.assertTrue(value.IsValid())
+        self.assertFalse(value.IsValid())
         self.assertFalse(value.GetError().Success())
 
         #
@@ -81,7 +81,7 @@ def test_context_object(self):
 
         # Test an expression evaluation
         value = obj_val.EvaluateExpression("1")
-        self.assertTrue(value.IsValid())
+        self.assertFalse(value.IsValid())
         self.assertFalse(value.GetError().Success())
 
         # Test retrieveing of an element's field
@@ -99,7 +99,7 @@ def test_context_object(self):
 
         # Test an expression evaluation
         value = obj_val.EvaluateExpression("1")
-        self.assertTrue(value.IsValid())
+        self.assertFalse(value.IsValid())
         self.assertFalse(value.GetError().Success())
 
         # Test retrieveing of a dereferenced object's field
@@ -117,7 +117,7 @@ def test_context_object(self):
 
         # Test an expression evaluation
         value = obj_val.EvaluateExpression("1")
-        self.assertTrue(value.IsValid())
+        self.assertFalse(value.IsValid())
         self.assertFalse(value.GetError().Success())
 
         #
@@ -129,7 +129,7 @@ def test_context_object(self):
 
         # Test an expression evaluation
         value = obj_val.EvaluateExpression("1")
-        self.assertTrue(value.IsValid())
+        self.assertFalse(value.IsValid())
         self.assertFalse(value.GetError().Success())
 
         # Test retrieveing of a dereferenced object's field
diff --git a/lldb/test/API/commands/expression/fixits/TestFixIts.py 
b/lldb/test/API/commands/expression/fixits/TestFixIts.py
index bfe11f6c6fcb9..6b11477e972ef 100644
--- a/lldb/test/API/commands/expression/fixits/TestFixIts.py
+++ b/lldb/test/API/commands/expression/fixits/TestFixIts.py
@@ -76,7 +76,7 @@ def test_with_target(self):
         # Now turn off the fixits, and the expression should fail:
         options.SetAutoApplyFixIts(False)
         value = frame.EvaluateExpression(two_error_expression, options)
-        self.assertTrue(value.IsValid())
+        self.assertFalse(value.IsValid())
         self.assertTrue(value.GetError().Fail())
         error_string = value.GetError().GetCString()
         self.assertNotEqual(
diff --git a/lldb/test/API/commands/expression/options/TestExprOptions.py 
b/lldb/test/API/commands/expression/options/TestExprOptions.py
index 01899f3b97cf4..0cb5921708d2a 100644
--- a/lldb/test/API/commands/expression/options/TestExprOptions.py
+++ b/lldb/test/API/commands/expression/options/TestExprOptions.py
@@ -56,7 +56,7 @@ def test_expr_options(self):
         # Make sure it fails if language is set to C:
         options.SetLanguage(lldb.eLanguageTypeC)
         val = frame.EvaluateExpression("foo != nullptr", options)
-        self.assertTrue(val.IsValid())
+        self.assertFalse(val.IsValid())
         self.assertFalse(val.GetError().Success())
 
     def test_expr_options_lang(self):
@@ -83,5 +83,5 @@ def test_expr_options_lang(self):
         # Make sure we can't retrieve `id` variable if language is set to ObjC:
         options.SetLanguage(lldb.eLanguageTypeObjC)
         val = frame.EvaluateExpression("id == 0", options)
-        self.assertTrue(val.IsValid())
+        self.assertFalse(val.IsValid())
         self.assertFalse(val.GetError().Success())
diff --git 
a/lldb/test/API/commands/expression/scoped_enums/TestScopedEnumType.py 
b/lldb/test/API/commands/expression/scoped_enums/TestScopedEnumType.py
index 751e8b8428d62..d10fa3a9c5fae 100644
--- a/lldb/test/API/commands/expression/scoped_enums/TestScopedEnumType.py
+++ b/lldb/test/API/commands/expression/scoped_enums/TestScopedEnumType.py
@@ -23,10 +23,10 @@ def test(self):
 
         ## b is not a Foo
         value = frame.EvaluateExpression("b == Foo::FooBar")
-        self.assertTrue(value.IsValid())
+        self.assertFalse(value.IsValid())
         self.assertFalse(value.GetError().Success())
 
         ## integral is not implicitly convertible to a scoped enum
         value = frame.EvaluateExpression("1 == Foo::FooBar")
-        self.assertTrue(value.IsValid())
+        self.assertFalse(value.IsValid())
         self.assertFalse(value.GetError().Success())
diff --git a/lldb/test/API/commands/expression/timeout/TestCallWithTimeout.py 
b/lldb/test/API/commands/expression/timeout/TestCallWithTimeout.py
index de074e8ff7b09..4817b598f175c 100644
--- a/lldb/test/API/commands/expression/timeout/TestCallWithTimeout.py
+++ b/lldb/test/API/commands/expression/timeout/TestCallWithTimeout.py
@@ -38,7 +38,7 @@ def test(self):
         frame = thread.GetFrameAtIndex(0)
 
         value = frame.EvaluateExpression(f"wait_a_while({long_time})", options)
-        self.assertTrue(value.IsValid())
+        self.assertFalse(value.IsValid())
         self.assertFalse(value.GetError().Success())
 
         # Now do the same thing with the command line command, and make sure it
diff --git a/lldb/test/API/python_api/sbvalue_is_valid/TestSBValueIsValid.py 
b/lldb/test/API/python_api/sbvalue_is_valid/TestSBValueIsValid.py
new file mode 100644
index 0000000000000..a3d43c1bdeeb2
--- /dev/null
+++ b/lldb/test/API/python_api/sbvalue_is_valid/TestSBValueIsValid.py
@@ -0,0 +1,3 @@
+import lldbsuite.test.lldbinline as lldbinline
+
+lldbinline.MakeInlineTest(__file__, globals())
diff --git a/lldb/test/API/python_api/sbvalue_is_valid/main.cpp 
b/lldb/test/API/python_api/sbvalue_is_valid/main.cpp
new file mode 100644
index 0000000000000..2584a75f63aca
--- /dev/null
+++ b/lldb/test/API/python_api/sbvalue_is_valid/main.cpp
@@ -0,0 +1,7 @@
+int main() {
+  int i = 42;
+  return 0; //% v1 = self.frame().EvaluateExpression("test"); v2 =
+            //self.frame().EvaluateExpression("i");
+  //% self.assertFalse(v1.IsValid())
+  //% self.assertTrue(v2.IsValid())
+}

_______________________________________________
lldb-commits mailing list
lldb-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits

Reply via email to