[Lldb-commits] [lldb] f05e2fb - Don't allow SBValue::Cast to cast from a smaller type to a larger,
Jim Ingham via lldb-commits
lldb-commits at lists.llvm.org
Mon Jun 26 16:02:09 PDT 2023
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;
More information about the lldb-commits
mailing list