Author: Raphael Isemann Date: 2026-07-10T15:33:44+01:00 New Revision: a465ef6968f30abacde4f2d526b98b206b9a149f
URL: https://github.com/llvm/llvm-project/commit/a465ef6968f30abacde4f2d526b98b206b9a149f DIFF: https://github.com/llvm/llvm-project/commit/a465ef6968f30abacde4f2d526b98b206b9a149f.diff LOG: [lldb][test] Add a new test for recursive types (#208449) This is a new modern test for recursive types that self-reference themselves via function pointers. This replaces the test logic from `API/types` test that is about to be deleted. See also #208402 assisted-by: claude Added: lldb/test/API/lang/cpp/recursive_types/function-ptrs/Makefile lldb/test/API/lang/cpp/recursive_types/function-ptrs/TestRecursiveTypesFuncPtrs.py lldb/test/API/lang/cpp/recursive_types/function-ptrs/main.cpp lldb/test/API/lang/cpp/recursive_types/function-ptrs/recursive_types.cpp Modified: Removed: ################################################################################ diff --git a/lldb/test/API/lang/cpp/recursive_types/function-ptrs/Makefile b/lldb/test/API/lang/cpp/recursive_types/function-ptrs/Makefile new file mode 100644 index 0000000000000..c7ccc4a6851e1 --- /dev/null +++ b/lldb/test/API/lang/cpp/recursive_types/function-ptrs/Makefile @@ -0,0 +1,3 @@ +CXX_SOURCES := main.cpp recursive_types.cpp + +include Makefile.rules diff --git a/lldb/test/API/lang/cpp/recursive_types/function-ptrs/TestRecursiveTypesFuncPtrs.py b/lldb/test/API/lang/cpp/recursive_types/function-ptrs/TestRecursiveTypesFuncPtrs.py new file mode 100644 index 0000000000000..9a2824c8f163d --- /dev/null +++ b/lldb/test/API/lang/cpp/recursive_types/function-ptrs/TestRecursiveTypesFuncPtrs.py @@ -0,0 +1,27 @@ +""" +Test that LLDB can complete and evaluate recursive types without infinitely +recursing. Each type reaches itself through a function pointer that returns a +pointer to the type. +""" + +import lldb +from lldbsuite.test.decorators import * +from lldbsuite.test.lldbtest import * +from lldbsuite.test import lldbutil + + +class TestCase(TestBase): + def test(self): + self.build_and_run() + + # Recursion through the named struct 's1'. Completing 't1' and walking + # one level into its members must not recurse infinitely. + self.expect_var_path("p1", type="t1_ptr") + self.expect_expr("p1", result_type="t1_ptr") + self.expect_expr("*p1", result_type="t1") + self.expect_expr("p1->s", result_type="s1 *") + + # Recursion through an anonymous struct member. + self.expect_var_path("p2", type="t2_ptr") + self.expect_expr("p2", result_type="t2_ptr") + self.expect_expr("*p2", result_type="t2") diff --git a/lldb/test/API/lang/cpp/recursive_types/function-ptrs/main.cpp b/lldb/test/API/lang/cpp/recursive_types/function-ptrs/main.cpp new file mode 100644 index 0000000000000..a23440914574c --- /dev/null +++ b/lldb/test/API/lang/cpp/recursive_types/function-ptrs/main.cpp @@ -0,0 +1,16 @@ +// The recursive types are only forward-declared here; their full (recursive) +// definition lives in recursive_types.cpp. This forces LLDB to complete the +// types from the other translation unit when evaluating the test expressions. +struct t1; +typedef t1 *t1_ptr; +struct t2; +typedef t2 *t2_ptr; + +extern t1 global_t1; +extern t2 global_t2; + +int main() { + t1_ptr p1 = &global_t1; + t2_ptr p2 = &global_t2; + return 0; // break here +} diff --git a/lldb/test/API/lang/cpp/recursive_types/function-ptrs/recursive_types.cpp b/lldb/test/API/lang/cpp/recursive_types/function-ptrs/recursive_types.cpp new file mode 100644 index 0000000000000..031fc7108604f --- /dev/null +++ b/lldb/test/API/lang/cpp/recursive_types/function-ptrs/recursive_types.cpp @@ -0,0 +1,32 @@ +// Definitions of two recursive types. Each type reaches itself through a +// function pointer that returns a pointer to the type, which historically made +// LLDB recurse infinitely while completing the type. +// +// These definitions live in their own translation unit (separate from main.cpp) +// so that LLDB has to complete the recursive type from this unit's debug info. + +// Variant 1: 't1' reaches itself through a named struct 's1' holding a function +// pointer that returns a pointer to 't1'. +struct t1; +typedef t1 *t1_ptr; +typedef t1_ptr (*get_t1)(); +struct s1 { + get_t1 get_t1_p; +}; +struct t1 { + s1 *s; +}; + +// Variant 2: 't2' reaches itself through an anonymous struct holding a function +// pointer that returns a pointer to 't2'. +struct t2; +typedef t2 *t2_ptr; +typedef t2_ptr (*get_t2)(); +struct t2 { + struct { + get_t2 get_t2_p; + }; +}; + +t1 global_t1; +t2 global_t2; _______________________________________________ lldb-commits mailing list [email protected] https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits
