diff --git a/llvm/lib/CodeGen/AsmPrinter/CodeViewDebug.cpp b/llvm/lib/CodeGen/AsmPrinter/CodeViewDebug.cpp index e57ed24a45065..2ebccee6aa68c 100644 --- a/llvm/lib/CodeGen/AsmPrinter/CodeViewDebug.cpp +++ b/llvm/lib/CodeGen/AsmPrinter/CodeViewDebug.cpp @@ -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(Node); - DISourceLanguageName Lang = CU->getSourceLanguage(); + + TheCU = cast(Node); + DISourceLanguageName Lang = TheCU->getSourceLanguage(); CurrentSourceLanguage = Lang.hasVersionedName() ? MapDWARFLanguageToCVLang( @@ -639,7 +644,7 @@ void CodeViewDebug::beginModule(Module *M) { : MapDWARFLanguageToCVLang( static_cast(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(TheCPU)); - NamedMDNode *CUs = MMI->getModule()->getNamedMetadata("llvm.dbg.cu"); - const MDNode *Node = *CUs->operands().begin(); - const auto *CU = cast(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) { diff --git a/llvm/lib/CodeGen/AsmPrinter/CodeViewDebug.h b/llvm/lib/CodeGen/AsmPrinter/CodeViewDebug.h index c2b878e52e1c3..7fd2cec8c74f2 100644 --- a/llvm/lib/CodeGen/AsmPrinter/CodeViewDebug.h +++ b/llvm/lib/CodeGen/AsmPrinter/CodeViewDebug.h @@ -98,6 +98,8 @@ class LLVM_LIBRARY_VISIBILITY CodeViewDebug : public DebugHandlerBase { /// 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; diff --git a/llvm/test/DebugInfo/X86/codeview-empty-dbg-cu-crash.ll b/llvm/test/DebugInfo/X86/codeview-empty-dbg-cu-crash.ll new file mode 100644 index 0000000000000..51435b10fdc2a --- /dev/null +++ b/llvm/test/DebugInfo/X86/codeview-empty-dbg-cu-crash.ll @@ -0,0 +1,39 @@ +; RUN: llc -mtriple=x86_64-pc-windows-msvc < %s | FileCheck %s + +; CHECK: .file "" +; 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}