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();
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();
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);
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;
}
--- /dev/null
+C_SOURCES := main.c
+
+include Makefile.rules
--- /dev/null
+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")
+
--- /dev/null
+int main (int argc, char const *argv[]) {
+ char *char_ptr = "Some pointer here";
+ void *void_ptr = &char_ptr;
+
+ return 0; // Break at this line
+}