Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Fix resolution of certain recursive types.
Summary: If a struct type S has a member T that has a member that is a function that returns a typedef of S* the respective field would be duplicated, which caused an assert down the line in RecordLayoutBuilder. This patch adds a check that removes the possibility of trying to resolve the same type twice within the same callstack. This commit also adds unit tests for these failures. Fixes https://llvm.org/bugs/show_bug.cgi?id=20486. Patch by Cristian Hancila. Test Plan: Run unit tests. Reviewers: clayborg spyffe Subscribers: lldb-commits Differential Revision: http://reviews.llvm.org/D8561 llvm-svn: 234441
- Loading branch information
Showing
7 changed files
with
143 additions
and
1 deletion.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,68 @@ | ||
""" | ||
Test that recursive types are handled correctly. | ||
""" | ||
|
||
import lldb | ||
import lldbutil | ||
import sys | ||
import unittest2 | ||
from lldbtest import * | ||
|
||
class RecursiveTypesTestCase(TestBase): | ||
|
||
mydir = TestBase.compute_mydir(__file__) | ||
|
||
def setUp(self): | ||
# Call super's setUp(). | ||
TestBase.setUp(self) | ||
# disable "There is a running process, kill it and restart?" prompt | ||
self.runCmd("settings set auto-confirm true") | ||
self.addTearDownHook(lambda: self.runCmd("settings clear auto-confirm")) | ||
# Find the line number to break for main.c. | ||
self.line = line_number('recursive_type_main.cpp', | ||
'// Test at this line.') | ||
|
||
self.d1 = {'CXX_SOURCES': 'recursive_type_main.cpp recursive_type_1.cpp'} | ||
self.d2 = {'CXX_SOURCES': 'recursive_type_main.cpp recursive_type_2.cpp'} | ||
|
||
@unittest2.skipUnless(sys.platform.startswith("darwin"), "requires Darwin") | ||
@dsym_test | ||
def test_recursive_dsym_type_1(self): | ||
"""Test that recursive structs are displayed correctly.""" | ||
self.buildDsym(dictionary=self.d1) | ||
self.print_struct() | ||
|
||
@dwarf_test | ||
def test_recursive_dwarf_type_1(self): | ||
"""Test that recursive structs are displayed correctly.""" | ||
self.buildDwarf(dictionary=self.d1) | ||
self.print_struct() | ||
|
||
@unittest2.skipUnless(sys.platform.startswith("darwin"), "requires Darwin") | ||
@dsym_test | ||
def test_recursive_dsym_type_2(self): | ||
"""Test that recursive structs are displayed correctly.""" | ||
self.buildDsym(dictionary=self.d2) | ||
self.print_struct() | ||
|
||
@dwarf_test | ||
def test_recursive_dwarf_type_2(self): | ||
"""Test that recursive structs are displayed correctly.""" | ||
self.buildDwarf(dictionary=self.d2) | ||
self.print_struct() | ||
|
||
def print_struct(self): | ||
self.runCmd("file a.out", CURRENT_EXECUTABLE_SET) | ||
|
||
lldbutil.run_break_set_by_file_and_line (self, "recursive_type_main.cpp", self.line, num_expected_locations=-1, loc_exact=True) | ||
|
||
self.runCmd("run", RUN_SUCCEEDED) | ||
|
||
self.expect("print tpi", RUN_SUCCEEDED) | ||
self.expect("print *tpi", RUN_SUCCEEDED) | ||
|
||
if __name__ == '__main__': | ||
import atexit | ||
lldb.SBDebugger.Initialize() | ||
atexit.register(lambda: lldb.SBDebugger.Terminate()) | ||
unittest2.main() |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,12 @@ | ||
typedef struct t *tp; | ||
typedef tp (*get_tp)(); | ||
|
||
struct s { | ||
get_tp get_tp_p; | ||
}; | ||
|
||
struct t { | ||
struct s *s; | ||
}; | ||
|
||
struct t t; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,10 @@ | ||
typedef struct t *tp; | ||
typedef tp (*get_tp)(); | ||
|
||
struct t { | ||
struct { | ||
get_tp get_tp_p; | ||
}; | ||
}; | ||
|
||
struct t t; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,8 @@ | ||
typedef struct t *tp; | ||
extern struct t t; | ||
|
||
int main() { | ||
tp tpi = &t; | ||
// Test at this line. | ||
return 0; | ||
} |