Hi clayborg,

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.

Fixes https://llvm.org/bugs/show_bug.cgi?id=20486.

Patch by Cristian Hancila.

http://reviews.llvm.org/D8561

Files:
  include/lldb/Expression/ClangASTSource.h
  source/Expression/ClangASTSource.cpp
  source/Symbol/ClangASTImporter.cpp

EMAIL PREFERENCES
  http://reviews.llvm.org/settings/panel/emailpreferences/
Index: include/lldb/Expression/ClangASTSource.h
===================================================================
--- include/lldb/Expression/ClangASTSource.h
+++ include/lldb/Expression/ClangASTSource.h
@@ -51,6 +51,7 @@
         m_lookups_enabled (false),
         m_target (target),
         m_ast_context (NULL),
+        m_active_lexical_decls (),
         m_active_lookups ()
     {
         m_ast_importer = m_target->GetClangASTImporter();
@@ -416,6 +417,7 @@
     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;
 };
 
Index: source/Expression/ClangASTSource.cpp
===================================================================
--- source/Expression/ClangASTSource.cpp
+++ source/Expression/ClangASTSource.cpp
@@ -189,6 +189,11 @@
         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);
+
     if (!m_ast_importer->CompleteTagDecl (tag_decl))
     {
         // We couldn't complete the type.  Maybe there's a definition
@@ -211,7 +216,10 @@
                             static_cast<int>(namespace_map->size()));
 
             if (!namespace_map)
+            {
+                m_active_lexical_decls.erase(tag_decl);
                 return;
+            }
 
             for (ClangASTImporter::NamespaceMap::iterator i = namespace_map->begin(), e = namespace_map->end();
                  i != e && !found;
@@ -302,6 +310,7 @@
         ASTDumper dumper((Decl*)tag_decl);
         dumper.ToLog(log, "      [CTD] ");
     }
+    m_active_lexical_decls.erase(tag_decl);
 }
 
 void
@@ -400,6 +409,11 @@
     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);
+
     static unsigned int invocation_id = 0;
     unsigned int current_id = invocation_id++;
 
@@ -428,7 +442,10 @@
     ASTContext *original_ctx = NULL;
 
     if (!m_ast_importer->ResolveDeclOrigin(context_decl, &original_decl, &original_ctx))
+    {
+        m_active_lexical_decls.erase(context_decl);
         return ELR_Failure;
+    }
 
     if (log)
     {
@@ -462,7 +479,10 @@
     const DeclContext *original_decl_context = dyn_cast<DeclContext>(original_decl);
 
     if (!original_decl_context)
+    {
+        m_active_lexical_decls.erase(context_decl);
         return ELR_Failure;
+    }
 
     for (TagDecl::decl_iterator iter = original_decl_context->decls_begin();
          iter != original_decl_context->decls_end();
@@ -509,6 +529,7 @@
         }
     }
 
+    m_active_lexical_decls.erase(context_decl);
     return ELR_AlreadyLoaded;
 }
 
Index: source/Symbol/ClangASTImporter.cpp
===================================================================
--- source/Symbol/ClangASTImporter.cpp
+++ source/Symbol/ClangASTImporter.cpp
@@ -286,7 +286,15 @@
     
     if (const TagType *tag_type = type->getAs<TagType>())
     {
-        return CompleteTagDecl(tag_type->getDecl());
+        auto tag_decl = tag_type->getDecl();
+        if (tag_decl->getDefinition() || tag_decl->isBeingDefined())
+        {
+            return true;
+        }
+        tag_decl->startDefinition();
+        bool result = CompleteTagDecl(tag_decl);
+        tag_decl->setCompleteDefinition(true);
+        return result;
     }
     if (const ObjCObjectType *objc_object_type = type->getAs<ObjCObjectType>())
     {
_______________________________________________
lldb-commits mailing list
[email protected]
http://lists.cs.uiuc.edu/mailman/listinfo/lldb-commits

Reply via email to