diff --git a/llvm/lib/CodeGen/AsmPrinter/DwarfUnit.h b/llvm/lib/CodeGen/AsmPrinter/DwarfUnit.h --- a/llvm/lib/CodeGen/AsmPrinter/DwarfUnit.h +++ b/llvm/lib/CodeGen/AsmPrinter/DwarfUnit.h @@ -18,6 +18,7 @@ #include "llvm/ADT/Optional.h" #include "llvm/CodeGen/AsmPrinter.h" #include "llvm/CodeGen/DIE.h" +#include "llvm/Target/TargetMachine.h" #include namespace llvm { @@ -79,6 +80,15 @@ template void addAttribute(DIEValueList &Die, dwarf::Attribute Attribute, dwarf::Form Form, T &&Value) { + // For strict DWARF mode, only generate attributes available to current + // DWARF version. + // Attribute 0 is used when emitting form-encoded values in blocks, which + // don't have attributes (only forms) so we cannot detect their DWARF + // version compatibility here and assume they are compatible. + if (Attribute != 0 && Asm->TM.Options.DebugStrictDwarf && + DD->getDwarfVersion() < dwarf::AttributeVersion(Attribute)) + return; + Die.addValue(DIEValueAllocator, DIEValue(Attribute, Form, std::forward(Value))); } diff --git a/llvm/test/DebugInfo/PowerPC/strict-dwarf.ll b/llvm/test/DebugInfo/PowerPC/strict-dwarf.ll --- a/llvm/test/DebugInfo/PowerPC/strict-dwarf.ll +++ b/llvm/test/DebugInfo/PowerPC/strict-dwarf.ll @@ -2,16 +2,30 @@ ; RUN: llvm-dwarfdump -debug-info - | FileCheck %s ; RUN: llc -filetype=obj -mtriple=powerpc64le-unknown-linux-gnu \ ; RUN: -strict-dwarf=true < %s | llvm-dwarfdump -debug-info - | \ -; RUN: FileCheck %s +; RUN: FileCheck %s -check-prefix=STRICT -; FIXME: when -strict-dwarf=true is specified, we should check "STRICT" to tell -; that with DWARF 4, we should not generate DWARF 5 attribute DW_AT_noreturn and -; DW_AT_alignment. +; We also check that with/without -strict-dwarf=true, the location attribute +; is not changed. The location attribute adding will call DwarfUnit::addUInt() +; which contains a attribute 0, we want to make sure the strict-dwarf handling +; is also right for attribute 0. +; For this case, the location attribute adding is for global variable @_ZL3var +; and the call chain to addUInt() is: +; 1: DwarfCompileUnit::addLocationAttribute() +; 2: DwarfUnit::addOpAddress() +; 3: DwarfUnit::addUInt() +; 4: addUInt(Block, (dwarf::Attribute)0, Form, Integer); +; CHECK: DW_AT_name ("var") +; CHECK-NOT: DW_TAG_ ; CHECK: DW_AT_alignment +; CHECK: DW_AT_location (DW_OP_addr 0x0) ; CHECK: DW_AT_noreturn -; STRICT-NOT: DW_AT_noreturn +; +; STRICT: DW_AT_name ("var") ; STRICT-NOT: DW_AT_alignment +; STRICT-NOT: DW_TAG_ +; STRICT: DW_AT_location (DW_OP_addr 0x0) +; STRICT-NOT: DW_AT_noreturn @_ZL3var = internal global i32 0, align 16, !dbg !0