[llvm] r264657 - Add an IR Verifier check for orphaned DICompileUnits.

Adrian Prantl via llvm-commits llvm-commits at lists.llvm.org
Mon Mar 28 14:06:26 PDT 2016


Author: adrian
Date: Mon Mar 28 16:06:26 2016
New Revision: 264657

URL: http://llvm.org/viewvc/llvm-project?rev=264657&view=rev
Log:
Add an IR Verifier check for orphaned DICompileUnits.
A DICompileUnit that is not listed in llvm.dbg.cu will cause assertion
failures and/or crashes in the backend. The Verifier should reject this.

rdar://problem/25369499

Added:
    llvm/trunk/test/Verifier/dbg-orphaned-compileunit.ll
Modified:
    llvm/trunk/lib/IR/Verifier.cpp
    llvm/trunk/test/Assembler/dicompileunit.ll
    llvm/trunk/test/Transforms/LoopIdiom/debug-line.ll
    llvm/trunk/tools/bugpoint/CrashDebugger.cpp

Modified: llvm/trunk/lib/IR/Verifier.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/IR/Verifier.cpp?rev=264657&r1=264656&r2=264657&view=diff
==============================================================================
--- llvm/trunk/lib/IR/Verifier.cpp (original)
+++ llvm/trunk/lib/IR/Verifier.cpp Mon Mar 28 16:06:26 2016
@@ -196,6 +196,9 @@ class Verifier : public InstVisitor<Veri
   /// \brief Keep track of the metadata nodes that have been checked already.
   SmallPtrSet<const Metadata *, 32> MDNodes;
 
+  /// Track all DICompileUnits visited.
+  SmallPtrSet<const Metadata *, 2> CUVisited;
+
   /// \brief Track unresolved string-based type references.
   SmallDenseMap<const MDString *, const MDNode *, 32> UnresolvedTypeRefs;
 
@@ -302,7 +305,9 @@ public:
     visitModuleFlags(M);
     visitModuleIdents(M);
 
-    // Verify type referneces last.
+    verifyCompileUnits();
+
+    // Verify type references last.
     verifyTypeRefs();
 
     return !Broken;
@@ -444,12 +449,15 @@ private:
   void verifyFrameRecoverIndices();
   void verifySiblingFuncletUnwinds();
 
-  // Module-level debug info verification...
+  /// @{
+  /// Module-level debug info verification...
   void verifyTypeRefs();
+  void verifyCompileUnits();
   template <class MapTy>
   void verifyBitPieceExpression(const DbgInfoIntrinsic &I,
                                 const MapTy &TypeRefs);
   void visitUnresolvedTypeRef(const MDString *S, const MDNode *N);
+  /// @}
 };
 } // End anonymous namespace
 
@@ -969,6 +977,7 @@ void Verifier::visitDICompileUnit(const
       Assert(Op && isa<DIMacroNode>(Op), "invalid macro ref", &N, Op);
     }
   }
+  CUVisited.insert(&N);
 }
 
 void Verifier::visitDISubprogram(const DISubprogram &N) {
@@ -4251,6 +4260,18 @@ void Verifier::visitUnresolvedTypeRef(co
   Assert(false, "unresolved type ref", S, N);
 }
 
+void Verifier::verifyCompileUnits() {
+  auto *CUs = M->getNamedMetadata("llvm.dbg.cu");
+  SmallPtrSet<const Metadata *, 2> Listed;
+  if (CUs)
+    Listed.insert(CUs->op_begin(), CUs->op_end());
+  Assert(
+      std::all_of(CUVisited.begin(), CUVisited.end(),
+                  [&Listed](const Metadata *CU) { return Listed.count(CU); }),
+      "All DICompileUnits must be listed in llvm.dbg.cu");
+  CUVisited.clear();
+}
+
 void Verifier::verifyTypeRefs() {
   auto *CUs = M->getNamedMetadata("llvm.dbg.cu");
   if (!CUs)

Modified: llvm/trunk/test/Assembler/dicompileunit.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Assembler/dicompileunit.ll?rev=264657&r1=264656&r2=264657&view=diff
==============================================================================
--- llvm/trunk/test/Assembler/dicompileunit.ll (original)
+++ llvm/trunk/test/Assembler/dicompileunit.ll Mon Mar 28 16:06:26 2016
@@ -1,8 +1,11 @@
 ; RUN: llvm-as < %s | llvm-dis | llvm-as | llvm-dis | FileCheck %s
 ; RUN: verify-uselistorder %s
 
+; Force a specific numbering.
 ; CHECK: !named = !{!0, !1, !2, !3, !4, !5, !6, !7, !8, !9}
 !named = !{!0, !1, !2, !3, !4, !5, !6, !7, !8, !9}
+; CHECK: !llvm.dbg.cu = !{!8, !9}
+!llvm.dbg.cu = !{!8, !9}
 
 !0 = distinct !{}
 !1 = !DIFile(filename: "path/to/file", directory: "/path/to/dir")
@@ -24,3 +27,5 @@
 !9 = distinct !DICompileUnit(language: 12, file: !1, producer: "",
                              isOptimized: false, flags: "", runtimeVersion: 0,
                              splitDebugFilename: "", emissionKind: 0)
+!llvm.module.flags = !{!10}
+!10 = !{i32 2, !"Debug Info Version", i32 3}

Modified: llvm/trunk/test/Transforms/LoopIdiom/debug-line.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Transforms/LoopIdiom/debug-line.ll?rev=264657&r1=264656&r2=264657&view=diff
==============================================================================
--- llvm/trunk/test/Transforms/LoopIdiom/debug-line.ll (original)
+++ llvm/trunk/test/Transforms/LoopIdiom/debug-line.ll Mon Mar 28 16:06:26 2016
@@ -28,11 +28,11 @@ declare void @llvm.dbg.declare(metadata,
 declare void @llvm.dbg.value(metadata, i64, metadata, metadata) nounwind readnone
 
 !llvm.module.flags = !{!19}
-!llvm.dbg.sp = !{!0}
+!llvm.dbg.cu = !{!2}
 
 !0 = distinct !DISubprogram(name: "foo", line: 2, isLocal: false, isDefinition: true, virtualIndex: 6, flags: DIFlagPrototyped, isOptimized: false, file: !18, scope: !1, type: !3)
 !1 = !DIFile(filename: "li.c", directory: "/private/tmp")
-!2 = distinct !DICompileUnit(language: DW_LANG_C99, producer: "clang version 2.9 (trunk 127165:127174)", isOptimized: true, emissionKind: 0, file: !18, enums: !9, retainedTypes: !9)
+!2 = distinct !DICompileUnit(language: DW_LANG_C99, producer: "clang version 2.9 (trunk 127165:127174)", isOptimized: true, emissionKind: 0, file: !18, enums: !9, subprograms: !{!0}, retainedTypes: !9)
 !3 = !DISubroutineType(types: !4)
 !4 = !{null}
 !5 = !DILocalVariable(name: "a", line: 2, arg: 1, scope: !0, file: !1, type: !6)

Added: llvm/trunk/test/Verifier/dbg-orphaned-compileunit.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Verifier/dbg-orphaned-compileunit.ll?rev=264657&view=auto
==============================================================================
--- llvm/trunk/test/Verifier/dbg-orphaned-compileunit.ll (added)
+++ llvm/trunk/test/Verifier/dbg-orphaned-compileunit.ll Mon Mar 28 16:06:26 2016
@@ -0,0 +1,10 @@
+; RUN: not llvm-as -disable-output <%s 2>&1 | FileCheck %s
+; CHECK:      assembly parsed, but does not verify
+; CHECK-NEXT: All DICompileUnits must be listed in llvm.dbg.cu
+
+!named = !{!1}
+!llvm.module.flags = !{!0}
+!0 = !{i32 2, !"Debug Info Version", i32 3}
+!llvm.dbg.cu = !{}
+!1 = distinct !DICompileUnit(file: !2, language: DW_LANG_Fortran77)
+!2 = !DIFile(filename: "test.f", directory: "")

Modified: llvm/trunk/tools/bugpoint/CrashDebugger.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/tools/bugpoint/CrashDebugger.cpp?rev=264657&r1=264656&r2=264657&view=diff
==============================================================================
--- llvm/trunk/tools/bugpoint/CrashDebugger.cpp (original)
+++ llvm/trunk/tools/bugpoint/CrashDebugger.cpp Mon Mar 28 16:06:26 2016
@@ -552,7 +552,9 @@ bool ReduceCrashingNamedMD::TestNamedMDs
   std::vector<NamedMDNode *> ToDelete;
   ToDelete.reserve(M->named_metadata_size() - Names.size());
   for (auto &NamedMD : M->named_metadata())
-    if (!Names.count(NamedMD.getName()))
+    // Always keep a nonempty llvm.dbg.cu because the Verifier would complain.
+    if (!Names.count(NamedMD.getName()) &&
+        (!(NamedMD.getName() == "llvm.dbg.cu" && NamedMD.getNumOperands() > 0)))
       ToDelete.push_back(&NamedMD);
 
   for (auto *NamedMD : ToDelete)




More information about the llvm-commits mailing list