CodeGen: Fix CodeView crashes with empty llvm.dbg.cu (#163286)

This commit is contained in:
Matt Arsenault
2025-11-12 14:59:42 -08:00
committed by GitHub
parent bdf3f24ec0
commit 2e489f77ba
3 changed files with 52 additions and 7 deletions

View File

@@ -628,10 +628,15 @@ void CodeViewDebug::beginModule(Module *M) {
// When emitting only compiler information, we may have only NoDebug CUs,
// which would be skipped by debug_compile_units_begin.
NamedMDNode *CUs = MMI->getModule()->getNamedMetadata("llvm.dbg.cu");
if (CUs->operands().empty()) {
Asm = nullptr;
return;
}
Node = *CUs->operands().begin();
}
const auto *CU = cast<DICompileUnit>(Node);
DISourceLanguageName Lang = CU->getSourceLanguage();
TheCU = cast<DICompileUnit>(Node);
DISourceLanguageName Lang = TheCU->getSourceLanguage();
CurrentSourceLanguage =
Lang.hasVersionedName()
? MapDWARFLanguageToCVLang(
@@ -639,7 +644,7 @@ void CodeViewDebug::beginModule(Module *M) {
: MapDWARFLanguageToCVLang(
static_cast<dwarf::SourceLanguage>(Lang.getName()));
if (!M->getCodeViewFlag() ||
CU->getEmissionKind() == DICompileUnit::NoDebug) {
TheCU->getEmissionKind() == DICompileUnit::NoDebug) {
Asm = nullptr;
return;
}
@@ -900,11 +905,10 @@ void CodeViewDebug::emitCompilerInformation() {
OS.AddComment("CPUType");
OS.emitInt16(static_cast<uint64_t>(TheCPU));
NamedMDNode *CUs = MMI->getModule()->getNamedMetadata("llvm.dbg.cu");
const MDNode *Node = *CUs->operands().begin();
const auto *CU = cast<DICompileUnit>(Node);
StringRef CompilerVersion = "0";
if (TheCU)
CompilerVersion = TheCU->getProducer();
StringRef CompilerVersion = CU->getProducer();
Version FrontVer = parseVersion(CompilerVersion);
OS.AddComment("Frontend version");
for (int N : FrontVer.Part) {

View File

@@ -98,6 +98,8 @@ private:
/// The codeview CPU type used by the translation unit.
codeview::CPUType TheCPU;
const DICompileUnit *TheCU = nullptr;
/// The AsmPrinter used for emitting compiler metadata. When only compiler
/// info is being emitted, DebugHandlerBase::Asm may be null.
AsmPrinter *CompilerInfoAsm = nullptr;

View File

@@ -0,0 +1,39 @@
; RUN: llc -mtriple=x86_64-pc-windows-msvc < %s | FileCheck %s
; CHECK: .file "<stdin>"
; CHECK-NEXT: .section .debug$S,"dr"
; CHECK-NEXT: .p2align 2, 0x0
; CHECK-NEXT: .long 4 # Debug section magic
; CHECK-NEXT: .long 241
; CHECK-NEXT: .long .Ltmp1-.Ltmp0 # Subsection size
; CHECK-NEXT: .Ltmp0:
; CHECK-NEXT: .short .Ltmp3-.Ltmp2 # Record length
; CHECK-NEXT: .Ltmp2:
; CHECK-NEXT: .short 4353 # Record kind: S_OBJNAME
; CHECK-NEXT: .long 0 # Signature
; CHECK-NEXT: .byte 0 # Object name
; CHECK-NEXT: .p2align 2, 0x0
; CHECK-NEXT: .Ltmp3:
; CHECK-NEXT: .short .Ltmp5-.Ltmp4 # Record length
; CHECK-NEXT: .Ltmp4:
; CHECK-NEXT: .short 4412 # Record kind: S_COMPILE3
; CHECK-NEXT: .long 3 # Flags and language
; CHECK-NEXT: .short 208 # CPUType
; CHECK-NEXT: .short 0 # Frontend version
; CHECK-NEXT: .short 0
; CHECK-NEXT: .short 0
; CHECK-NEXT: .short 0
; CHECK-NEXT: .short 22000 # Backend version
; CHECK-NEXT: .short 0
; CHECK-NEXT: .short 0
; CHECK-NEXT: .short 0
; CHECK-NEXT: .asciz "0" # Null-terminated compiler version string
; CHECK-NEXT: .p2align 2, 0x0
; CHECK-NEXT: .Ltmp5:
; CHECK-NEXT: .Ltmp1:
; CHECK-NEXT: .p2align 2, 0x0
!llvm.dbg.cu = !{}
!llvm.module.flags = !{!0}
!0 = !{i32 2, !"Debug Info Version", i32 3}