[Lldb-commits] [lldb] [lldb/API] Mark SBValue with error as invalid (PR #158759)
Med Ismail Bennani via lldb-commits
lldb-commits at lists.llvm.org
Mon Sep 15 18:09:46 PDT 2025
https://github.com/medismailben updated https://github.com/llvm/llvm-project/pull/158759
>From b204ad16b8584a796585fb376b5258e3240fa71b Mon Sep 17 00:00:00 2001
From: Med Ismail Bennani <ismail at bennani.ma>
Date: Mon, 15 Sep 2025 18:09:34 -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 <ismail at 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..a6177ccaeee3d
--- /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())
+}
More information about the lldb-commits
mailing list