We recently had an issue where a user declared a `Class::free` function which then got picked up by accident by the expression evaluator when calling `::free`. This was due to a too lax filter in the DWARFIndex (which was fixed by https://reviews.llvm.org/D73191 ). This broke the Objective-C utility expression that is trying to update the Objective-C class list (which is calling `:;free`). This adds a regression test for situations where we have a bunch of functions defined that share the name of the global functions that this utility function calls. None of them are actually conflicting with the global functions we are trying to call (they are all in namespaces, objects or classes). Reviewed By: JDevlieghere Differential Revision: https://reviews.llvm.org/D107776
43 lines
1.7 KiB
Python
43 lines
1.7 KiB
Python
import lldb
|
|
from lldbsuite.test.decorators import *
|
|
from lldbsuite.test.lldbtest import *
|
|
from lldbsuite.test import lldbutil
|
|
|
|
class TestCase(TestBase):
|
|
|
|
mydir = TestBase.compute_mydir(__file__)
|
|
|
|
def test(self):
|
|
"""
|
|
Tests that running the utility expression that retrieves the Objective-C
|
|
class list works even when user-code contains functions with apparently
|
|
conflicting identifiers (e.g. 'free') but that are not in the global
|
|
scope.
|
|
|
|
This is *not* supposed to test what happens when there are actual
|
|
conflicts such as when a user somehow defined their own '::free'
|
|
function.
|
|
"""
|
|
|
|
self.build()
|
|
lldbutil.run_to_source_breakpoint(self, "// break here", lldb.SBFileSpec("main.mm"))
|
|
|
|
# First check our side effect variable is in its initial state.
|
|
self.expect_expr("called_function", result_summary='"none"')
|
|
|
|
# Get the (dynamic) type of our 'id' variable so that our Objective-C
|
|
# runtime information is updated.
|
|
str_val = self.expect_expr("str")
|
|
dyn_val = str_val.GetDynamicValue(lldb.eDynamicCanRunTarget)
|
|
dyn_type = dyn_val.GetTypeName()
|
|
|
|
# Check our side effect variable which should still be in its initial
|
|
# state if none of our trap functions were called.
|
|
# If this is failing, then LLDB called one of the trap functions.
|
|
self.expect_expr("called_function", result_summary='"none"')
|
|
|
|
# Double check that our dynamic type is correct. This is done last
|
|
# as the assert message from above is the more descriptive one (it
|
|
# contains the unintentionally called function).
|
|
self.assertEqual(dyn_type, "__NSCFConstantString *")
|