diff --git a/lldb/source/Core/ValueObject.cpp b/lldb/source/Core/ValueObject.cpp --- a/lldb/source/Core/ValueObject.cpp +++ b/lldb/source/Core/ValueObject.cpp @@ -1859,7 +1859,7 @@ if (!IsDynamic() && m_dynamic_value == nullptr) { CalculateDynamicValue(use_dynamic); } - if (m_dynamic_value) + if (m_dynamic_value && m_dynamic_value->GetError().Success()) return m_dynamic_value->GetSP(); else return ValueObjectSP(); diff --git a/lldb/source/Core/ValueObjectConstResult.cpp b/lldb/source/Core/ValueObjectConstResult.cpp --- a/lldb/source/Core/ValueObjectConstResult.cpp +++ b/lldb/source/Core/ValueObjectConstResult.cpp @@ -287,7 +287,7 @@ if (process && process->IsPossibleDynamicValue(*this)) m_dynamic_value = new ValueObjectDynamicValue(*this, use_dynamic); } - if (m_dynamic_value) + if (m_dynamic_value && m_dynamic_value->GetError().Success()) return m_dynamic_value->GetSP(); } return ValueObjectSP(); diff --git a/lldb/source/Core/ValueObjectDynamicValue.cpp b/lldb/source/Core/ValueObjectDynamicValue.cpp --- a/lldb/source/Core/ValueObjectDynamicValue.cpp +++ b/lldb/source/Core/ValueObjectDynamicValue.cpp @@ -187,17 +187,19 @@ m_type_impl.Clear(); } - // If we don't have a dynamic type, then make ourselves just a echo of our - // parent. Or we could return false, and make ourselves an echo of our - // parent? + // If we don't have a dynamic type, set ourselves to be invalid and return + // false. We used to try to produce a dynamic ValueObject that behaved "like" + // its parent, but that failed for ValueObjectConstResult, which is too + // complex a beast to try to emulate. If we return an invalid ValueObject, + // clients will end up getting the static value instead, which behaves + // correctly. if (!found_dynamic_type) { if (m_dynamic_type_info) SetValueDidChange(true); ClearDynamicTypeInformation(); m_dynamic_type_info.Clear(); - m_value = m_parent->GetValue(); - m_error = m_value.GetValueAsData(&exe_ctx, m_data, GetModule().get()); - return m_error.Success(); + m_error.SetErrorString("no dynamic type found"); + return false; } Value old_value(m_value); diff --git a/lldb/source/Plugins/LanguageRuntime/CPlusPlus/ItaniumABI/ItaniumABILanguageRuntime.cpp b/lldb/source/Plugins/LanguageRuntime/CPlusPlus/ItaniumABI/ItaniumABILanguageRuntime.cpp --- a/lldb/source/Plugins/LanguageRuntime/CPlusPlus/ItaniumABI/ItaniumABILanguageRuntime.cpp +++ b/lldb/source/Plugins/LanguageRuntime/CPlusPlus/ItaniumABI/ItaniumABILanguageRuntime.cpp @@ -583,7 +583,11 @@ ValueObjectSP exception = ValueObject::CreateValueObjectFromData( "exception", exception_isw.GetAsData(m_process->GetByteOrder()), exe_ctx, voidstar); - exception = exception->GetDynamicValue(eDynamicDontRunTarget); + ValueObjectSP dyn_exception + = exception->GetDynamicValue(eDynamicDontRunTarget); + // If we succeed in making a dynamic value, return that: + if (dyn_exception) + return dyn_exception; return exception; } diff --git a/lldb/test/API/python_api/value/addr_of_void_star/Makefile b/lldb/test/API/python_api/value/addr_of_void_star/Makefile new file mode 100644 --- /dev/null +++ b/lldb/test/API/python_api/value/addr_of_void_star/Makefile @@ -0,0 +1,3 @@ +C_SOURCES := main.c + +include Makefile.rules diff --git a/lldb/test/API/python_api/value/addr_of_void_star/TestValueAPIAddressOfVoidStar.py b/lldb/test/API/python_api/value/addr_of_void_star/TestValueAPIAddressOfVoidStar.py new file mode 100644 --- /dev/null +++ b/lldb/test/API/python_api/value/addr_of_void_star/TestValueAPIAddressOfVoidStar.py @@ -0,0 +1,38 @@ +import lldb +from lldbsuite.test.decorators import * +from lldbsuite.test.lldbtest import * +from lldbsuite.test import lldbutil + +class ValueAPIVoidStarTestCase(TestBase): + + def test(self): + self.build() + + target, process, thread, _ = lldbutil.run_to_source_breakpoint(self, + "Break at this line", + lldb.SBFileSpec("main.c")) + frame = thread.GetFrameAtIndex(0) + + # Verify that the expression result for a void * behaves the same way as the + # variable value. + + var_val = frame.FindVariable("void_ptr") + self.assertSuccess(var_val.GetError(), "Var version made correctly") + + expr_val = frame.EvaluateExpression("void_ptr") + self.assertSuccess(expr_val.GetError(), "Expr version succeeds") + + # The pointer values should be equal: + self.assertEqual(var_val.unsigned, expr_val.unsigned, "Values are equal") + + # Both versions should have valid AddressOf, and they should be the same. + + val_addr_of = var_val.AddressOf() + self.assertNotEqual(val_addr_of, lldb.LLDB_INVALID_ADDRESS, "Var addr of right") + + expr_addr_of = expr_val.AddressOf() + self.assertNotEqual(expr_addr_of, lldb.LLDB_INVALID_ADDRESS, "Expr addr of right") + + # The AddressOf values should also be equal. + self.assertEqual(expr_addr_of.unsigned, val_addr_of.unsigned, "Addr of equal") + diff --git a/lldb/test/API/python_api/value/addr_of_void_star/main.c b/lldb/test/API/python_api/value/addr_of_void_star/main.c new file mode 100644 --- /dev/null +++ b/lldb/test/API/python_api/value/addr_of_void_star/main.c @@ -0,0 +1,6 @@ +int main (int argc, char const *argv[]) { + char *char_ptr = "Some pointer here"; + void *void_ptr = &char_ptr; + + return 0; // Break at this line +}