[Lldb-commits] [lldb] r234441 - Fix resolution of certain recursive types.
Stephane Sezer
sas at cd80.net
Wed Apr 8 14:52:45 PDT 2015
Author: sas
Date: Wed Apr 8 16:52:45 2015
New Revision: 234441
URL: http://llvm.org/viewvc/llvm-project?rev=234441&view=rev
Log:
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
Added:
lldb/trunk/test/types/TestRecursiveTypes.py
lldb/trunk/test/types/recursive_type_1.cpp
lldb/trunk/test/types/recursive_type_2.cpp
lldb/trunk/test/types/recursive_type_main.cpp
Modified:
lldb/trunk/include/lldb/Expression/ClangASTSource.h
lldb/trunk/source/Expression/ClangASTSource.cpp
lldb/trunk/source/Symbol/ClangASTImporter.cpp
Modified: lldb/trunk/include/lldb/Expression/ClangASTSource.h
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/include/lldb/Expression/ClangASTSource.h?rev=234441&r1=234440&r2=234441&view=diff
==============================================================================
--- lldb/trunk/include/lldb/Expression/ClangASTSource.h (original)
+++ lldb/trunk/include/lldb/Expression/ClangASTSource.h Wed Apr 8 16:52:45 2015
@@ -51,6 +51,7 @@ public:
m_lookups_enabled (false),
m_target (target),
m_ast_context (NULL),
+ m_active_lexical_decls (),
m_active_lookups ()
{
m_ast_importer = m_target->GetClangASTImporter();
@@ -404,6 +405,7 @@ protected:
const lldb::TargetSP m_target; ///< The target to use in finding variables and types.
clang::ASTContext *m_ast_context; ///< The AST context requests are coming in for.
ClangASTImporter *m_ast_importer; ///< The target's AST importer.
+ std::set<const clang::Decl *> m_active_lexical_decls;
std::set<const char *> m_active_lookups;
};
Modified: lldb/trunk/source/Expression/ClangASTSource.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Expression/ClangASTSource.cpp?rev=234441&r1=234440&r2=234441&view=diff
==============================================================================
--- lldb/trunk/source/Expression/ClangASTSource.cpp (original)
+++ lldb/trunk/source/Expression/ClangASTSource.cpp Wed Apr 8 16:52:45 2015
@@ -30,6 +30,31 @@
using namespace clang;
using namespace lldb_private;
+//------------------------------------------------------------------
+// Scoped class that will remove an active lexical decl from the set
+// when it goes out of scope.
+//------------------------------------------------------------------
+namespace {
+ class ScopedLexicalDeclEraser
+ {
+ public:
+ ScopedLexicalDeclEraser(std::set<const clang::Decl *> &decls,
+ const clang::Decl *decl)
+ : m_active_lexical_decls(decls), m_decl(decl)
+ {
+ }
+
+ ~ScopedLexicalDeclEraser()
+ {
+ m_active_lexical_decls.erase(m_decl);
+ }
+
+ private:
+ std::set<const clang::Decl *> &m_active_lexical_decls;
+ const clang::Decl *m_decl;
+ };
+}
+
ClangASTSource::~ClangASTSource()
{
m_ast_importer->ForgetDestination(m_ast_context);
@@ -191,6 +216,12 @@ ClangASTSource::CompleteType (TagDecl *t
dumper.ToLog(log, " [CTD] ");
}
+ auto iter = m_active_lexical_decls.find(tag_decl);
+ if (iter != m_active_lexical_decls.end())
+ return;
+ m_active_lexical_decls.insert(tag_decl);
+ ScopedLexicalDeclEraser eraser(m_active_lexical_decls, tag_decl);
+
if (!m_ast_importer->CompleteTagDecl (tag_decl))
{
// We couldn't complete the type. Maybe there's a definition
@@ -402,6 +433,12 @@ ClangASTSource::FindExternalLexicalDecls
if (!context_decl)
return ELR_Failure;
+ auto iter = m_active_lexical_decls.find(context_decl);
+ if (iter != m_active_lexical_decls.end())
+ return ELR_Failure;
+ m_active_lexical_decls.insert(context_decl);
+ ScopedLexicalDeclEraser eraser(m_active_lexical_decls, context_decl);
+
static unsigned int invocation_id = 0;
unsigned int current_id = invocation_id++;
Modified: lldb/trunk/source/Symbol/ClangASTImporter.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Symbol/ClangASTImporter.cpp?rev=234441&r1=234440&r2=234441&view=diff
==============================================================================
--- lldb/trunk/source/Symbol/ClangASTImporter.cpp (original)
+++ lldb/trunk/source/Symbol/ClangASTImporter.cpp Wed Apr 8 16:52:45 2015
@@ -286,7 +286,12 @@ ClangASTImporter::RequireCompleteType (c
if (const TagType *tag_type = type->getAs<TagType>())
{
- return CompleteTagDecl(tag_type->getDecl());
+ TagDecl *tag_decl = tag_type->getDecl();
+
+ if (tag_decl->getDefinition() || tag_decl->isBeingDefined())
+ return true;
+
+ return CompleteTagDecl(tag_decl);
}
if (const ObjCObjectType *objc_object_type = type->getAs<ObjCObjectType>())
{
Added: lldb/trunk/test/types/TestRecursiveTypes.py
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/test/types/TestRecursiveTypes.py?rev=234441&view=auto
==============================================================================
--- lldb/trunk/test/types/TestRecursiveTypes.py (added)
+++ lldb/trunk/test/types/TestRecursiveTypes.py Wed Apr 8 16:52:45 2015
@@ -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()
Added: lldb/trunk/test/types/recursive_type_1.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/test/types/recursive_type_1.cpp?rev=234441&view=auto
==============================================================================
--- lldb/trunk/test/types/recursive_type_1.cpp (added)
+++ lldb/trunk/test/types/recursive_type_1.cpp Wed Apr 8 16:52:45 2015
@@ -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;
Added: lldb/trunk/test/types/recursive_type_2.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/test/types/recursive_type_2.cpp?rev=234441&view=auto
==============================================================================
--- lldb/trunk/test/types/recursive_type_2.cpp (added)
+++ lldb/trunk/test/types/recursive_type_2.cpp Wed Apr 8 16:52:45 2015
@@ -0,0 +1,10 @@
+typedef struct t *tp;
+typedef tp (*get_tp)();
+
+struct t {
+ struct {
+ get_tp get_tp_p;
+ };
+};
+
+struct t t;
Added: lldb/trunk/test/types/recursive_type_main.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/test/types/recursive_type_main.cpp?rev=234441&view=auto
==============================================================================
--- lldb/trunk/test/types/recursive_type_main.cpp (added)
+++ lldb/trunk/test/types/recursive_type_main.cpp Wed Apr 8 16:52:45 2015
@@ -0,0 +1,8 @@
+typedef struct t *tp;
+extern struct t t;
+
+int main() {
+ tp tpi = &t;
+ // Test at this line.
+ return 0;
+}
More information about the lldb-commits
mailing list