mirror of
https://github.com/llvm/llvm-project.git
synced 2025-04-29 03:46:07 +00:00
Don't allow SBValue::Cast to cast from a smaller type to a larger,
as we don't in general know where the extra data should come from. Differential Revision: https://reviews.llvm.org/D153657
This commit is contained in:
parent
4cf35a85c7
commit
f05e2fb013
@ -614,7 +614,9 @@ public:
|
||||
virtual void SetLiveAddress(lldb::addr_t addr = LLDB_INVALID_ADDRESS,
|
||||
AddressType address_type = eAddressTypeLoad) {}
|
||||
|
||||
virtual lldb::ValueObjectSP Cast(const CompilerType &compiler_type);
|
||||
lldb::ValueObjectSP Cast(const CompilerType &compiler_type);
|
||||
|
||||
virtual lldb::ValueObjectSP DoCast(const CompilerType &compiler_type);
|
||||
|
||||
virtual lldb::ValueObjectSP CastPointerType(const char *name,
|
||||
CompilerType &ast_type);
|
||||
|
@ -106,7 +106,7 @@ public:
|
||||
|
||||
lldb::LanguageType GetPreferredDisplayLanguage() override;
|
||||
|
||||
lldb::ValueObjectSP Cast(const CompilerType &compiler_type) override;
|
||||
lldb::ValueObjectSP DoCast(const CompilerType &compiler_type) override;
|
||||
|
||||
protected:
|
||||
bool UpdateValue() override;
|
||||
|
@ -51,7 +51,7 @@ public:
|
||||
size_t GetPointeeData(DataExtractor &data, uint32_t item_idx = 0,
|
||||
uint32_t item_count = 1) override;
|
||||
|
||||
lldb::ValueObjectSP Cast(const CompilerType &compiler_type) override;
|
||||
lldb::ValueObjectSP DoCast(const CompilerType &compiler_type) override;
|
||||
|
||||
protected:
|
||||
ValueObjectConstResultImpl m_impl;
|
||||
|
@ -60,7 +60,7 @@ public:
|
||||
size_t GetPointeeData(DataExtractor &data, uint32_t item_idx = 0,
|
||||
uint32_t item_count = 1) override;
|
||||
|
||||
lldb::ValueObjectSP Cast(const CompilerType &compiler_type) override;
|
||||
lldb::ValueObjectSP DoCast(const CompilerType &compiler_type) override;
|
||||
|
||||
protected:
|
||||
ValueObjectConstResultImpl m_impl;
|
||||
|
@ -2604,6 +2604,17 @@ FileCheck output:
|
||||
if not obj.Success():
|
||||
error = obj.GetCString()
|
||||
self.fail(self._formatMessage(msg, "'{}' is not success".format(error)))
|
||||
"""Assert that an lldb.SBError is in the "failure" state."""
|
||||
|
||||
def assertFailure(self, obj, error_str = None, msg=None):
|
||||
if obj.Success():
|
||||
self.fail(self._formatMessage(msg, "Error not in a fail state"))
|
||||
|
||||
if error_str == None:
|
||||
return
|
||||
|
||||
error = obj.GetCString()
|
||||
self.assertEqual(error, error_str, msg)
|
||||
|
||||
"""Assert that a command return object is successful"""
|
||||
|
||||
|
@ -2779,8 +2779,30 @@ ValueObjectSP ValueObject::AddressOf(Status &error) {
|
||||
return m_addr_of_valobj_sp;
|
||||
}
|
||||
|
||||
ValueObjectSP ValueObject::DoCast(const CompilerType &compiler_type) {
|
||||
return ValueObjectCast::Create(*this, GetName(), compiler_type);
|
||||
}
|
||||
|
||||
ValueObjectSP ValueObject::Cast(const CompilerType &compiler_type) {
|
||||
return ValueObjectCast::Create(*this, GetName(), compiler_type);
|
||||
// Only allow casts if the original type is equal or larger than the cast
|
||||
// type. We don't know how to fetch more data for all the ConstResult types,
|
||||
// so we can't guarantee this will work:
|
||||
Status error;
|
||||
CompilerType my_type = GetCompilerType();
|
||||
|
||||
ExecutionContextScope *exe_scope
|
||||
= ExecutionContext(GetExecutionContextRef())
|
||||
.GetBestExecutionContextScope();
|
||||
if (compiler_type.GetByteSize(exe_scope)
|
||||
<= GetCompilerType().GetByteSize(exe_scope)) {
|
||||
return DoCast(compiler_type);
|
||||
}
|
||||
error.SetErrorString("Can only cast to a type that is equal to or smaller "
|
||||
"than the orignal type.");
|
||||
|
||||
return ValueObjectConstResult::Create(
|
||||
ExecutionContext(GetExecutionContextRef()).GetBestExecutionContextScope(),
|
||||
error);
|
||||
}
|
||||
|
||||
lldb::ValueObjectSP ValueObject::Clone(ConstString new_name) {
|
||||
|
@ -294,7 +294,7 @@ ValueObjectConstResult::GetDynamicValue(lldb::DynamicValueType use_dynamic) {
|
||||
}
|
||||
|
||||
lldb::ValueObjectSP
|
||||
ValueObjectConstResult::Cast(const CompilerType &compiler_type) {
|
||||
ValueObjectConstResult::DoCast(const CompilerType &compiler_type) {
|
||||
return m_impl.Cast(compiler_type);
|
||||
}
|
||||
|
||||
|
@ -57,6 +57,6 @@ size_t ValueObjectConstResultCast::GetPointeeData(DataExtractor &data,
|
||||
}
|
||||
|
||||
lldb::ValueObjectSP
|
||||
ValueObjectConstResultCast::Cast(const CompilerType &compiler_type) {
|
||||
ValueObjectConstResultCast::DoCast(const CompilerType &compiler_type) {
|
||||
return m_impl.Cast(compiler_type);
|
||||
}
|
||||
|
@ -69,6 +69,6 @@ size_t ValueObjectConstResultChild::GetPointeeData(DataExtractor &data,
|
||||
}
|
||||
|
||||
lldb::ValueObjectSP
|
||||
ValueObjectConstResultChild::Cast(const CompilerType &compiler_type) {
|
||||
ValueObjectConstResultChild::DoCast(const CompilerType &compiler_type) {
|
||||
return m_impl.Cast(compiler_type);
|
||||
}
|
||||
|
@ -607,11 +607,13 @@ lldb_private::formatters::LibcxxSharedPtrSyntheticFrontEnd::GetChildAtIndex(
|
||||
if (idx == 1) {
|
||||
if (auto ptr_sp = valobj_sp->GetChildMemberWithName("__ptr_")) {
|
||||
Status status;
|
||||
auto value_sp = ptr_sp->Dereference(status);
|
||||
auto value_type_sp =
|
||||
valobj_sp->GetCompilerType()
|
||||
.GetTypeTemplateArgument(0).GetPointerType();
|
||||
ValueObjectSP cast_ptr_sp = ptr_sp->Cast(value_type_sp);
|
||||
ValueObjectSP value_sp = cast_ptr_sp->Dereference(status);
|
||||
if (status.Success()) {
|
||||
auto value_type_sp =
|
||||
valobj_sp->GetCompilerType().GetTypeTemplateArgument(0);
|
||||
return value_sp->Cast(value_type_sp);
|
||||
return value_sp;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -157,7 +157,11 @@ lldb::ValueObjectSP lldb_private::formatters::
|
||||
}
|
||||
if (!m_node_type)
|
||||
return nullptr;
|
||||
node_sp = node_sp->Cast(m_node_type);
|
||||
node_sp = m_next_element->Cast(m_node_type.GetPointerType())
|
||||
->Dereference(error);
|
||||
if (!node_sp || error.Fail())
|
||||
return nullptr;
|
||||
|
||||
value_sp = node_sp->GetChildMemberWithName("__value_");
|
||||
hash_sp = node_sp->GetChildMemberWithName("__hash_");
|
||||
if (!value_sp || !hash_sp)
|
||||
|
@ -146,6 +146,19 @@ class ValueAPITestCase(TestBase):
|
||||
self.assertTrue(val_s.GetChildMemberWithName("a").AddressOf(), VALID_VARIABLE)
|
||||
self.assertTrue(val_a.Cast(val_i.GetType()).AddressOf(), VALID_VARIABLE)
|
||||
|
||||
# Test some other cases of the Cast API. We allow casts from one struct type
|
||||
# to another, which is a little weird, but we don't support casting from a
|
||||
# smaller type to a larger as we often wouldn't know how to get the extra data:
|
||||
val_f = target.EvaluateExpression("f")
|
||||
bad_cast = val_s.Cast(val_f.GetType())
|
||||
self.assertFailure(bad_cast.GetError(),
|
||||
"Can only cast to a type that is equal to or smaller than the orignal type.")
|
||||
weird_cast = val_f.Cast(val_s.GetType())
|
||||
self.assertSuccess(weird_cast.GetError(),
|
||||
"Can cast from a larger to a smaller")
|
||||
self.assertEqual(weird_cast.GetChildMemberWithName("a").GetValueAsSigned(0), 33,
|
||||
"Got the right value")
|
||||
|
||||
# Check that lldb.value implements truth testing.
|
||||
self.assertFalse(lldb.value(frame0.FindVariable("bogus")))
|
||||
self.assertTrue(lldb.value(frame0.FindVariable("uinthex")))
|
||||
|
@ -29,6 +29,13 @@ struct MyStruct
|
||||
int b;
|
||||
};
|
||||
|
||||
struct MyBiggerStruct
|
||||
{
|
||||
int a;
|
||||
int b;
|
||||
int c;
|
||||
};
|
||||
|
||||
int main (int argc, char const *argv[])
|
||||
{
|
||||
uint32_t uinthex = 0xE0A35F10;
|
||||
@ -37,6 +44,7 @@ int main (int argc, char const *argv[])
|
||||
int i;
|
||||
MyInt a = 12345;
|
||||
struct MyStruct s = { 11, 22 };
|
||||
struct MyBiggerStruct f = { 33, 44, 55 };
|
||||
int *my_int_ptr = &g_my_int;
|
||||
printf("my_int_ptr points to location %p\n", my_int_ptr);
|
||||
const char **str_ptr = days_of_week;
|
||||
|
Loading…
x
Reference in New Issue
Block a user