Author: Jim Ingham Date: 2023-06-26T16:02:01-07:00 New Revision: f05e2fb013f0e2504471a9899dba7d70cc58a63d
URL: https://github.com/llvm/llvm-project/commit/f05e2fb013f0e2504471a9899dba7d70cc58a63d DIFF: https://github.com/llvm/llvm-project/commit/f05e2fb013f0e2504471a9899dba7d70cc58a63d.diff LOG: 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 Added: Modified: lldb/include/lldb/Core/ValueObject.h lldb/include/lldb/Core/ValueObjectConstResult.h lldb/include/lldb/Core/ValueObjectConstResultCast.h lldb/include/lldb/Core/ValueObjectConstResultChild.h lldb/packages/Python/lldbsuite/test/lldbtest.py lldb/source/Core/ValueObject.cpp lldb/source/Core/ValueObjectConstResult.cpp lldb/source/Core/ValueObjectConstResultCast.cpp lldb/source/Core/ValueObjectConstResultChild.cpp lldb/source/Plugins/Language/CPlusPlus/LibCxx.cpp lldb/source/Plugins/Language/CPlusPlus/LibCxxUnorderedMap.cpp lldb/test/API/python_api/value/TestValueAPI.py lldb/test/API/python_api/value/main.c Removed: ################################################################################ diff --git a/lldb/include/lldb/Core/ValueObject.h b/lldb/include/lldb/Core/ValueObject.h index 2f2b212e238ca..2d8036ab07871 100644 --- a/lldb/include/lldb/Core/ValueObject.h +++ b/lldb/include/lldb/Core/ValueObject.h @@ -614,7 +614,9 @@ class ValueObject { 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); diff --git a/lldb/include/lldb/Core/ValueObjectConstResult.h b/lldb/include/lldb/Core/ValueObjectConstResult.h index 4edd495216061..d61df859bebce 100644 --- a/lldb/include/lldb/Core/ValueObjectConstResult.h +++ b/lldb/include/lldb/Core/ValueObjectConstResult.h @@ -106,7 +106,7 @@ class ValueObjectConstResult : public ValueObject { lldb::LanguageType GetPreferredDisplayLanguage() override; - lldb::ValueObjectSP Cast(const CompilerType &compiler_type) override; + lldb::ValueObjectSP DoCast(const CompilerType &compiler_type) override; protected: bool UpdateValue() override; diff --git a/lldb/include/lldb/Core/ValueObjectConstResultCast.h b/lldb/include/lldb/Core/ValueObjectConstResultCast.h index 5467ce3db403f..efcbe0dc6a0bd 100644 --- a/lldb/include/lldb/Core/ValueObjectConstResultCast.h +++ b/lldb/include/lldb/Core/ValueObjectConstResultCast.h @@ -51,7 +51,7 @@ class ValueObjectConstResultCast : public ValueObjectCast { 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; diff --git a/lldb/include/lldb/Core/ValueObjectConstResultChild.h b/lldb/include/lldb/Core/ValueObjectConstResultChild.h index 26bd9f337a595..7e9da14e8e97f 100644 --- a/lldb/include/lldb/Core/ValueObjectConstResultChild.h +++ b/lldb/include/lldb/Core/ValueObjectConstResultChild.h @@ -60,7 +60,7 @@ class ValueObjectConstResultChild : public ValueObjectChild { 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; diff --git a/lldb/packages/Python/lldbsuite/test/lldbtest.py b/lldb/packages/Python/lldbsuite/test/lldbtest.py index a712f6b2b2a56..2bff1a7067cb3 100644 --- a/lldb/packages/Python/lldbsuite/test/lldbtest.py +++ b/lldb/packages/Python/lldbsuite/test/lldbtest.py @@ -2604,6 +2604,17 @@ def assertSuccess(self, obj, msg=None): 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""" diff --git a/lldb/source/Core/ValueObject.cpp b/lldb/source/Core/ValueObject.cpp index 9ff980db96d23..d60a1d6f7a105 100644 --- a/lldb/source/Core/ValueObject.cpp +++ b/lldb/source/Core/ValueObject.cpp @@ -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) { diff --git a/lldb/source/Core/ValueObjectConstResult.cpp b/lldb/source/Core/ValueObjectConstResult.cpp index 17a725dcc7dd8..693da1a551f8e 100644 --- a/lldb/source/Core/ValueObjectConstResult.cpp +++ b/lldb/source/Core/ValueObjectConstResult.cpp @@ -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); } diff --git a/lldb/source/Core/ValueObjectConstResultCast.cpp b/lldb/source/Core/ValueObjectConstResultCast.cpp index e70d055ac57c5..fceb2635f876f 100644 --- a/lldb/source/Core/ValueObjectConstResultCast.cpp +++ b/lldb/source/Core/ValueObjectConstResultCast.cpp @@ -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); } diff --git a/lldb/source/Core/ValueObjectConstResultChild.cpp b/lldb/source/Core/ValueObjectConstResultChild.cpp index 0fd81410ae54f..36bf11a0b73af 100644 --- a/lldb/source/Core/ValueObjectConstResultChild.cpp +++ b/lldb/source/Core/ValueObjectConstResultChild.cpp @@ -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); } diff --git a/lldb/source/Plugins/Language/CPlusPlus/LibCxx.cpp b/lldb/source/Plugins/Language/CPlusPlus/LibCxx.cpp index 666b467a88813..de4f23bf95c33 100644 --- a/lldb/source/Plugins/Language/CPlusPlus/LibCxx.cpp +++ b/lldb/source/Plugins/Language/CPlusPlus/LibCxx.cpp @@ -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; } } } diff --git a/lldb/source/Plugins/Language/CPlusPlus/LibCxxUnorderedMap.cpp b/lldb/source/Plugins/Language/CPlusPlus/LibCxxUnorderedMap.cpp index 50e8650327ec3..14776cdf80815 100644 --- a/lldb/source/Plugins/Language/CPlusPlus/LibCxxUnorderedMap.cpp +++ b/lldb/source/Plugins/Language/CPlusPlus/LibCxxUnorderedMap.cpp @@ -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) diff --git a/lldb/test/API/python_api/value/TestValueAPI.py b/lldb/test/API/python_api/value/TestValueAPI.py index dc68eb6c5748d..b5d065e5d26d8 100644 --- a/lldb/test/API/python_api/value/TestValueAPI.py +++ b/lldb/test/API/python_api/value/TestValueAPI.py @@ -146,6 +146,19 @@ def test(self): 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"))) diff --git a/lldb/test/API/python_api/value/main.c b/lldb/test/API/python_api/value/main.c index c2e0dc8c12ddc..bf00aba076618 100644 --- a/lldb/test/API/python_api/value/main.c +++ b/lldb/test/API/python_api/value/main.c @@ -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; _______________________________________________ lldb-commits mailing list lldb-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits