diff --git a/llvm/lib/IR/Verifier.cpp b/llvm/lib/IR/Verifier.cpp index 42158ef681e534..4cb18fc3ed9464 100644 --- a/llvm/lib/IR/Verifier.cpp +++ b/llvm/lib/IR/Verifier.cpp @@ -553,8 +553,6 @@ class Verifier : public InstVisitor, VerifierSupport { void verifyFunctionAttrs(FunctionType *FT, AttributeList Attrs, const Value *V, bool IsIntrinsic); void verifyFunctionMetadata(ArrayRef> MDs); - template - void verifyODRTypeAsScopeOperand(const MDNode &MD, T * = nullptr); void visitConstantExprsRecursively(const Constant *EntryC); void visitConstantExpr(const ConstantExpr *CE); @@ -864,19 +862,6 @@ void Verifier::visitNamedMDNode(const NamedMDNode &NMD) { } } -template -void Verifier::verifyODRTypeAsScopeOperand(const MDNode &MD, T *) { - if (isa(MD)) { - if (auto *N = dyn_cast_or_null(cast(MD).getScope())) - // Of all the supported tags for DICompositeType(see visitDICompositeType) - // we know that enum type cannot be a scope. - AssertDI(N->getTag() != dwarf::DW_TAG_enumeration_type, - "enum type is not a scope; check enum type ODR " - "violation", - N, &MD); - } -} - void Verifier::visitMDNode(const MDNode &MD, AreDebugLocsAllowed AllowLocs) { // Only visit each node once. Metadata can be mutually recursive, so this // avoids infinite recursion here, as well as being an optimization. @@ -886,12 +871,6 @@ void Verifier::visitMDNode(const MDNode &MD, AreDebugLocsAllowed AllowLocs) { Assert(&MD.getContext() == &Context, "MDNode context does not match Module context!", &MD); - // Makes sure when a scope operand is a ODR type, the ODR type uniquing does - // not create invalid debug metadata. - // TODO: check that the non-ODR-type scope operand is valid. - verifyODRTypeAsScopeOperand(MD); - verifyODRTypeAsScopeOperand(MD); - switch (MD.getMetadataID()) { default: llvm_unreachable("Invalid MDNode subclass"); diff --git a/llvm/test/DebugInfo/dbg-rust-valid-enum-as-scope.ll b/llvm/test/DebugInfo/dbg-rust-valid-enum-as-scope.ll new file mode 100644 index 00000000000000..b6a53bd4c4597f --- /dev/null +++ b/llvm/test/DebugInfo/dbg-rust-valid-enum-as-scope.ll @@ -0,0 +1,74 @@ +; RUN: %llc_dwarf -filetype=obj -o - %s | llvm-dwarfdump -| FileCheck --implicit-check-not=DW_TAG --implicit-check-not=NULL %s +; CHECK: DW_TAG_compile_unit +; CHECK: DW_AT_language (DW_LANG_Rust) +; CHECK: DW_TAG_namespace +; CHECK: DW_TAG_enumeration_type +; CHECK: DW_AT_name ("E") +; CHECK: DW_TAG_enumerator +; CHECK: DW_TAG_enumerator +; CHECK: DW_TAG_subprogram +; CHECK: DW_AT_name ("f") +; CHECK: DW_TAG_formal_parameter +; CHECK: NULL +; CHECK: NULL +; CHECK: NULL +; CHECK: DW_TAG_pointer_type +; CHECK: NULL + +; This file comes from rustc output, with the input program +; pub enum E { A, B } +; impl E { +; pub fn f(&self) {} +; } +; compiled with `rustc --crate-type=lib a.rs --emit llvm-ir -g` and +; copying the resulting `a.ll` file to here. This was done with rustc +; at nightly from 2021-09-28 (git 8f8092cc3), but rustc 1.57 should +; produce similar or identical output. + +; ModuleID = 'a.a146b597-cgu.0' +source_filename = "a.a146b597-cgu.0" +target datalayout = "e-m:o-p270:32:32-p271:32:32-p272:64:64-i64:64-f80:128-n8:16:32:64-S128" +target triple = "x86_64-apple-macosx10.7.0" + +; a::E::f +; Function Attrs: uwtable +define void @_ZN1a1E1f17h4fcb50ce732fb2a7E(i8* align 1 dereferenceable(1) %self) unnamed_addr #0 !dbg !13 { +start: + %self.dbg.spill = alloca i8*, align 8 + store i8* %self, i8** %self.dbg.spill, align 8 + call void @llvm.dbg.declare(metadata i8** %self.dbg.spill, metadata !19, metadata !DIExpression()), !dbg !21 + ret void, !dbg !22 +} + +; Function Attrs: nofree nosync nounwind readnone speculatable willreturn +declare void @llvm.dbg.declare(metadata, metadata, metadata) #1 + +attributes #0 = { uwtable "frame-pointer"="all" "probe-stack"="__rust_probestack" "target-cpu"="core2" } +attributes #1 = { nofree nosync nounwind readnone speculatable willreturn } + +!llvm.module.flags = !{!0, !1, !2} +!llvm.dbg.cu = !{!3} + +!0 = !{i32 7, !"PIC Level", i32 2} +!1 = !{i32 2, !"Dwarf Version", i32 2} +!2 = !{i32 2, !"Debug Info Version", i32 3} +!3 = distinct !DICompileUnit(language: DW_LANG_Rust, file: !4, producer: "clang LLVM (rustc version 1.57.0-nightly (8f8092cc3 2021-09-28))", isOptimized: false, runtimeVersion: 0, emissionKind: FullDebug, enums: !5) +!4 = !DIFile(filename: "a.rs/@/a.a146b597-cgu.0", directory: "/Users/augie") +!5 = !{!6} +!6 = !DICompositeType(tag: DW_TAG_enumeration_type, name: "E", scope: !8, file: !7, baseType: !9, size: 8, align: 8, flags: DIFlagEnumClass, elements: !10) +!7 = !DIFile(filename: "", directory: "") +!8 = !DINamespace(name: "a", scope: null) +!9 = !DIBasicType(name: "u8", size: 8, encoding: DW_ATE_unsigned) +!10 = !{!11, !12} +!11 = !DIEnumerator(name: "A", value: 0) +!12 = !DIEnumerator(name: "B", value: 1) +!13 = distinct !DISubprogram(name: "f", linkageName: "_ZN1a1E1f17h4fcb50ce732fb2a7E", scope: !6, file: !14, line: 3, type: !15, scopeLine: 3, flags: DIFlagPrototyped, spFlags: DISPFlagDefinition, unit: !3, templateParams: !20, retainedNodes: !18) +!14 = !DIFile(filename: "a.rs", directory: "/Users/augie", checksumkind: CSK_MD5, checksum: "ab4ce84c27ef6fd0be1ef78e8131faa8") +!15 = !DISubroutineType(types: !16) +!16 = !{null, !17} +!17 = !DIDerivedType(tag: DW_TAG_pointer_type, name: "&E", baseType: !6, size: 64, align: 64, dwarfAddressSpace: 0) +!18 = !{!19} +!19 = !DILocalVariable(name: "self", arg: 1, scope: !13, file: !14, line: 3, type: !17) +!20 = !{} +!21 = !DILocation(line: 3, column: 14, scope: !13) +!22 = !DILocation(line: 3, column: 23, scope: !13) diff --git a/llvm/test/Verifier/dbg-invalid-enum-as-scope.ll b/llvm/test/Verifier/dbg-invalid-enum-as-scope.ll deleted file mode 100644 index 4053d4aede2e23..00000000000000 --- a/llvm/test/Verifier/dbg-invalid-enum-as-scope.ll +++ /dev/null @@ -1,16 +0,0 @@ -; RUN: llvm-as -disable-output <%s 2>&1 | FileCheck %s -; CHECK: enum type is not a scope; check enum type ODR violation -; CHECK: warning: ignoring invalid debug info - -!llvm.module.flags = !{!0} -!0 = !{i32 2, !"Debug Info Version", i32 3} -!llvm.dbg.cu = !{!1} -!1 = distinct !DICompileUnit(language: DW_LANG_C99, file: !2, producer: "clang", isOptimized: false, runtimeVersion: 0, emissionKind: FullDebug, retainedTypes: !13, enums: !3) -!2 = !DIFile(filename: "file.c", directory: "dir") -!3 = !{!4} -!4 = distinct !DICompositeType(tag: DW_TAG_enumeration_type, name: "Stage", file: !2, line: 3, baseType: !10, size: 32, elements: !11, identifier: "_ZTS5Stage") -!6 = !DIDerivedType(tag: DW_TAG_member, name: "Var", scope: !4, file: !2, line: 5, baseType: !10) -!10 = !DIBasicType(name: "unsigned int", size: 32, encoding: DW_ATE_unsigned) -!11 = !{!12} -!12 = !DIEnumerator(name: "A1", value: 0, isUnsigned: true) -!13 = !{!6}