llvmorg-github-actions[bot] wrote:

<!--LLVM PR SUMMARY COMMENT-->

@llvm/pr-subscribers-lldb

Author: Konstantin Bolshakov (konstantinbo)

<details>
<summary>Changes</summary>

This fixes #<!-- -->207704

Assisted-by: Github Copilot (Claude Opus 4.8)

---
Full diff: https://github.com/llvm/llvm-project/pull/207705.diff


2 Files Affected:

- (modified) lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.cpp 
(+20-15) 
- (modified) lldb/unittests/SymbolFile/DWARF/DWARFASTParserClangTests.cpp 
(+26-3) 


``````````diff
diff --git a/lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.cpp 
b/lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.cpp
index 0506b7d4da40f..f6deb3abd3881 100644
--- a/lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.cpp
+++ b/lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.cpp
@@ -1882,22 +1882,27 @@ TypeSP DWARFASTParserClang::ParseStructureLikeDIE(
         m_ast.CreateClassTemplateSpecializationDecl(
             containing_decl_ctx, GetOwningClangModule(die), 
class_template_decl,
             tag_decl_kind, template_param_infos);
-    if (!class_specialization_decl) {
-      if (log) {
-        dwarf->GetObjectFile()->GetModule()->LogMessage(
-            log,
-            "SymbolFileDWARF({0:p}) - Failed to create specialization for "
-            "clang::ClassTemplateDecl({1}, {2:p}).",
-            this, llvm::StringRef(attrs.name), class_template_decl);
-      }
-      return TypeSP();
+    if (class_specialization_decl) {
+      clang_type =
+          
m_ast.CreateClassTemplateSpecializationType(class_specialization_decl);
+
+      m_ast.SetMetadata(class_template_decl, metadata);
+      m_ast.SetMetadata(class_specialization_decl, metadata);
+    } else if (log) {
+      // A specialization with identical template arguments already exists.
+      // This happens with malformed/duplicated DWARF, e.g. GCC emits several
+      // reduced copies of a std::tuple<...> instantiation whose only template
+      // child is an empty DW_TAG_GNU_template_parameter_pack, so every copy
+      // collapses to the same (empty) argument list. Failing to parse the type
+      // here would leave members that reference it (such as unique_ptr's _M_t)
+      // with a null type and crash data formatters. Instead, fall through and
+      // build a plain (non-template) record type below.
+      dwarf->GetObjectFile()->GetModule()->LogMessage(
+          log,
+          "SymbolFileDWARF({0:p}) - Specialization for 
clang::ClassTemplateDecl"
+          "({1}, {2:p}) already exists; falling back to a non-template 
record.",
+          this, llvm::StringRef(attrs.name), class_template_decl);
     }
-
-    clang_type =
-        m_ast.CreateClassTemplateSpecializationType(class_specialization_decl);
-
-    m_ast.SetMetadata(class_template_decl, metadata);
-    m_ast.SetMetadata(class_specialization_decl, metadata);
   }
 
   if (!clang_type) {
diff --git a/lldb/unittests/SymbolFile/DWARF/DWARFASTParserClangTests.cpp 
b/lldb/unittests/SymbolFile/DWARF/DWARFASTParserClangTests.cpp
index a95d6ecfab790..66b220aa8dc98 100644
--- a/lldb/unittests/SymbolFile/DWARF/DWARFASTParserClangTests.cpp
+++ b/lldb/unittests/SymbolFile/DWARF/DWARFASTParserClangTests.cpp
@@ -622,8 +622,15 @@ TEST_F(DWARFASTParserClangTests, 
TestDefaultTemplateParamParsing) {
 }
 
 TEST_F(DWARFASTParserClangTests, TestSpecDeclExistsError) {
-  // Tests that parsing a ClassTemplateSpecializationDecl that already exists
-  // is handled gracefully.
+  // Tests that parsing a second class DIE whose template arguments collapse to
+  // an already-existing ClassTemplateSpecializationDecl is handled gracefully.
+  // The malformed input drops DW_TAG_template_value_parameter entries, which
+  // makes two distinct specializations look structurally identical. Rather 
than
+  // failing to parse the second type (which would leave members referring to 
it
+  // with a null type and crash data formatters), the parser falls back to a
+  // plain, non-template record type. Critically, neither resulting type may 
end
+  // up inheriting from itself, which used to cause infinite recursion during
+  // layout.
   auto BufferOrError = llvm::MemoryBuffer::getFile(
       GetInputFilePath("DW_AT_spec_decl_exists-test.yaml"), /*IsText=*/true);
   ASSERT_TRUE(BufferOrError);
@@ -643,7 +650,23 @@ TEST_F(DWARFASTParserClangTests, TestSpecDeclExistsError) {
 
   ASSERT_EQ(specializations.size(), 2U);
   ASSERT_NE(specializations[0], nullptr);
-  ASSERT_EQ(specializations[1], nullptr);
+  ASSERT_NE(specializations[1], nullptr);
+
+  // Completing each type must not recurse infinitely, and no type may inherit
+  // from itself.
+  for (auto const &type_sp : specializations) {
+    CompilerType ct = type_sp->GetFullCompilerType();
+    auto const *record = llvm::dyn_cast_or_null<clang::CXXRecordDecl>(
+        ClangUtil::GetAsTagDecl(ct));
+    ASSERT_NE(record, nullptr);
+    if (!record->hasDefinition())
+      continue;
+    for (clang::CXXBaseSpecifier const &base : record->bases()) {
+      clang::CXXRecordDecl const *base_decl =
+          base.getType()->getAsCXXRecordDecl();
+      EXPECT_NE(base_decl, record);
+    }
+  }
 }
 
 TEST_F(DWARFASTParserClangTests, TestUniqueDWARFASTTypeMap_CppInsertMapFind) {

``````````

</details>


https://github.com/llvm/llvm-project/pull/207705
_______________________________________________
lldb-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits

Reply via email to