https://github.com/tgs-sc created https://github.com/llvm/llvm-project/pull/154123
[lldb][DWARFASTParserClang] Added a check for the specialization existence While debugging an application with incorrect dwarf information, where DW_TAG_template_value_parameter were lost, I found that lldb does not check that the corresponding specialization exists. As a result, at the stage when ASTImporter works, the type is completed in such a way that it inherits from itself. And during the calculation of layout, an infinite recursion occurs. To catch this error, I added a corresponding check at the stage of restoring the type from dwarf information. I also added a trivial assert in clang to check that the class does not inherit from itself. >From 25d756bbfb5da66375f09cb71d89159e7521f5af Mon Sep 17 00:00:00 2001 From: Timur Golubovich <timur.golubov...@syntacore.com> Date: Mon, 18 Aug 2025 17:29:01 +0300 Subject: [PATCH] [clang][AST] Added assert to prevent infinite recursion in computing layout [lldb][DWARFASTParserClang] Added a check for the specialization existence While debugging an application with incorrect dwarf information, where DW_TAG_template_value_parameter were lost, I found that lldb does not check that the corresponding specialization exists. As a result, at the stage when ASTImporter works, the type is completed in such a way that it inherits from itself. And during the calculation of layout, an infinite recursion occurs. To catch this error, I added a corresponding check at the stage of restoring the type from dwarf information. I also added a trivial assert in clang to check that the class does not inherit from itself. --- clang/lib/AST/RecordLayoutBuilder.cpp | 2 ++ .../SymbolFile/DWARF/DWARFASTParserClang.cpp | 16 ++++++++++++++++ 2 files changed, 18 insertions(+) diff --git a/clang/lib/AST/RecordLayoutBuilder.cpp b/clang/lib/AST/RecordLayoutBuilder.cpp index 6d819031cbef4..93571543f1c7d 100644 --- a/clang/lib/AST/RecordLayoutBuilder.cpp +++ b/clang/lib/AST/RecordLayoutBuilder.cpp @@ -187,6 +187,8 @@ void EmptySubobjectMap::ComputeEmptySubobjectSizes() { // Check the bases. for (const CXXBaseSpecifier &Base : Class->bases()) { const CXXRecordDecl *BaseDecl = Base.getType()->getAsCXXRecordDecl(); + // Assert to prevent infinite recursion. + assert(BaseDecl != Class && "Class cannot inherit from itself."); CharUnits EmptySize; const ASTRecordLayout &Layout = Context.getASTRecordLayout(BaseDecl); diff --git a/lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.cpp b/lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.cpp index c76d67b47b336..6643751cd237a 100644 --- a/lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.cpp +++ b/lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.cpp @@ -1873,6 +1873,22 @@ DWARFASTParserClang::ParseStructureLikeDIE(const SymbolContext &sc, clang_type = m_ast.CreateClassTemplateSpecializationType(class_specialization_decl); + // Try to find an existing specialization with these template arguments and + // template parameter list. + void *InsertPos = nullptr; + if (!class_template_decl->findSpecialization(template_param_infos.GetArgs(), + InsertPos)) + // Add this specialization to the class template. + class_template_decl->AddSpecialization(class_specialization_decl, + InsertPos); + else { + dwarf->GetObjectFile()->GetModule()->ReportError( + "SymbolFileDWARF({0:p}) - Specialization for " + "clang::ClassTemplateDecl({1:p}) already exists.", + static_cast<void *>(this), static_cast<void *>(class_template_decl)); + return TypeSP(); + } + m_ast.SetMetadata(class_template_decl, metadata); m_ast.SetMetadata(class_specialization_decl, metadata); } _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits