]> granicus.if.org Git - clang/commitdiff
[ObjC++] Fix crash when emitting debug info for a block member capturing this.
authorAdrian Prantl <aprantl@apple.com>
Mon, 18 Apr 2016 23:48:16 +0000 (23:48 +0000)
committerAdrian Prantl <aprantl@apple.com>
Mon, 18 Apr 2016 23:48:16 +0000 (23:48 +0000)
rdar://problem/23871824

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

lib/CodeGen/CGDebugInfo.cpp
test/CodeGenObjCXX/debug-info-block-capture-this.mm [new file with mode: 0644]

index ae95dd8ed66fdf72ad88d6db1c8fb878329aee9e..0c61496162a5320cedbcdcb3a6acc64b05405724 100644 (file)
@@ -3262,9 +3262,14 @@ void CGDebugInfo::EmitDeclareOfBlockLiteralArgVariable(const CGBlockInfo &block,
 
     // If we have a null capture, this must be the C++ 'this' capture.
     if (!capture) {
-      const CXXMethodDecl *method =
-          cast<CXXMethodDecl>(blockDecl->getNonClosureContext());
-      QualType type = method->getThisType(C);
+      QualType type;
+      if (auto *Method =
+              cast_or_null<CXXMethodDecl>(blockDecl->getNonClosureContext()))
+        type = Method->getThisType(C);
+      else if (auto *RDecl = dyn_cast<CXXRecordDecl>(blockDecl->getParent()))
+        type = QualType(RDecl->getTypeForDecl(), 0);
+      else
+        llvm_unreachable("unexpected block declcontext");
 
       fields.push_back(createFieldType("this", type, 0, loc, AS_public,
                                        offsetInBits, tunit, tunit));
diff --git a/test/CodeGenObjCXX/debug-info-block-capture-this.mm b/test/CodeGenObjCXX/debug-info-block-capture-this.mm
new file mode 100644 (file)
index 0000000..a1b1206
--- /dev/null
@@ -0,0 +1,19 @@
+// RUN: %clang_cc1 -triple x86_64-apple-darwin -std=c++14 -fblocks -debug-info-kind=standalone -emit-llvm %s -o - | FileCheck %s
+struct test
+{
+    int func() { return 1; }
+    int (^block)() = ^{ return func(); };
+};
+
+int main(int argc, const char * argv[]) {
+    test t;
+    return t.block();
+}
+
+// CHECK: !DICompositeType(tag: DW_TAG_structure_type, name: "__block_literal_1",
+// CHECK-SAME:             elements: ![[ELEMS:.*]])
+// CHECK: ![[ELEMS]] = !{{{.*}}, ![[THIS:[0-9]+]]}
+// CHECK: ![[THIS]] = !DIDerivedType(tag: DW_TAG_member, name: "this",
+// CHECK-SAME:                       baseType: !"_ZTS4test",
+
+