AsmPrinter: Allow null subroutine type
authorDuncan P. N. Exon Smith <dexonsmith@apple.com>
Fri, 28 Aug 2015 21:38:24 +0000 (21:38 +0000)
committerDuncan P. N. Exon Smith <dexonsmith@apple.com>
Fri, 28 Aug 2015 21:38:24 +0000 (21:38 +0000)
Currently the DWARF backend requires that subprograms have a type, and
the type is ignored if it has an empty type array.  The long term
direction here -- see PR23079 -- is instead to skip the type entirely if
there's no valid type.

It turns out we have cases in tree of missing types on subprograms, but
since they're not referenced by compile units, the backend never crashes
on them.  One option would be to add a Verifier check that subprograms
have types, and fix the bitrot.  However, this is a fair bit of churn
(20-30 testcases) that would be reversed anyway by PR23079.

I found this inconsistency because of a WIP patch and upgrade script for
PR23367 that started crashing on test/DebugInfo/2010-10-01-crash.ll.
This commit updates the testcase to reference the subprogram from the
compile unit, and fixes the resulting crash (in line with the direction
of PR23079).  This also updates `DIBuilder` to stop assuming a non-null
pointer for the subroutine types.

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@246333 91177308-0d34-0410-b5e6-96231b3b80d8

include/llvm/IR/DebugInfoMetadata.h
lib/CodeGen/AsmPrinter/DwarfUnit.cpp
lib/IR/DIBuilder.cpp
test/DebugInfo/2010-10-01-crash.ll

index 98d5c2e2f7ccf9e5f6d6549844774cbd985eb9d2..eeacbdbf343a4427d145291d2f04ce24eb0b2511 100644 (file)
@@ -99,6 +99,7 @@ class DITypeRefArray {
   const MDTuple *N = nullptr;
 
 public:
+  DITypeRefArray() = default;
   DITypeRefArray(const MDTuple *N) : N(N) {}
 
   explicit operator bool() const { return get(); }
index d5ed0cd094580b7b730ce006befda71f3b9d816a..d3e0b8b798caffc3750e05cac16acf56b8bd4db3 100644 (file)
@@ -1195,11 +1195,10 @@ void DwarfUnit::applySubprogramAttributes(const DISubprogram *SP, DIE &SPDie,
        Language == dwarf::DW_LANG_ObjC))
     addFlag(SPDie, dwarf::DW_AT_prototyped);
 
-  const DISubroutineType *SPTy = SP->getType();
-  assert(SPTy->getTag() == dwarf::DW_TAG_subroutine_type &&
-         "the type of a subprogram should be a subroutine");
+  DITypeRefArray Args;
+  if (const DISubroutineType *SPTy = SP->getType())
+    Args = SPTy->getTypeArray();
 
-  auto Args = SPTy->getTypeArray();
   // Add a return type. If this is a type like a C/C++ void type we don't add a
   // return type.
   if (Args.size())
index d1257ce78df500310b1a4a75f46da47ffb02b69a..aedddb9833012c11e841f39cc85a1620edb5582b 100644 (file)
@@ -689,8 +689,6 @@ DISubprogram *DIBuilder::createFunction(DIScope *Context, StringRef Name,
                                         unsigned ScopeLine, unsigned Flags,
                                         bool isOptimized, Function *Fn,
                                         MDNode *TParams, MDNode *Decl) {
-  assert(Ty->getTag() == dwarf::DW_TAG_subroutine_type &&
-         "function types should be subroutines");
   auto *Node = getSubprogram(/* IsDistinct = */ isDefinition, VMContext,
                              DIScopeRef::get(getNonCompileUnitScope(Context)),
                              Name, LinkageName, File, LineNo, Ty, isLocalToUnit,
@@ -725,8 +723,6 @@ DIBuilder::createMethod(DIScope *Context, StringRef Name, StringRef LinkageName,
                         bool isLocalToUnit, bool isDefinition, unsigned VK,
                         unsigned VIndex, DIType *VTableHolder, unsigned Flags,
                         bool isOptimized, Function *Fn, MDNode *TParam) {
-  assert(Ty->getTag() == dwarf::DW_TAG_subroutine_type &&
-         "function types should be subroutines");
   assert(getNonCompileUnitScope(Context) &&
          "Methods should have both a Context and a context that isn't "
          "the compile unit.");
index 914e300c3466307b523403fe96e584390ba13afb..6ae48f1c4088e860b5f0f53e6c30b9c37a243b60 100644 (file)
@@ -15,7 +15,7 @@ declare void @llvm.memcpy.p0i8.p0i8.i32(i8* nocapture, i8* nocapture, i32, i32,
 !llvm.module.flags = !{!27}
 !0 = distinct !DISubprogram(name: "CGRectStandardize", linkageName: "CGRectStandardize", line: 54, isLocal: false, isDefinition: true, virtualIndex: 6, isOptimized: false, file: !1, scope: null, function: void (i32*, i32*)* @CGRectStandardize)
 !1 = !DIFile(filename: "GSFusedSilica.m", directory: "/Volumes/Data/Users/sabre/Desktop")
-!2 = distinct !DICompileUnit(language: DW_LANG_ObjC, producer: "clang version 2.9 (trunk 115292)", isOptimized: true, runtimeVersion: 1, emissionKind: 0, file: !25, enums: !26, retainedTypes: !26)
+!2 = distinct !DICompileUnit(language: DW_LANG_ObjC, producer: "clang version 2.9 (trunk 115292)", isOptimized: true, runtimeVersion: 1, emissionKind: 0, file: !25, enums: !26, retainedTypes: !26, subprograms: !{!0})
 !5 = !DIDerivedType(tag: DW_TAG_typedef, name: "CGRect", line: 49, file: !25, baseType: null)
 !23 = !DILocalVariable(name: "rect", line: 53, arg: 2, scope: !0, file: !1, type: !5)
 !24 = !DILocation(line: 53, column: 33, scope: !0)