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
