[CodeGen] Don't create fake FunctionDecls when generating block/byref
authorAkira Hatanaka <ahatanaka@apple.com>
Thu, 24 Jun 2021 18:45:52 +0000 (11:45 -0700)
committerAkira Hatanaka <ahatanaka@apple.com>
Thu, 24 Jun 2021 18:45:52 +0000 (11:45 -0700)
copy/dispose helper functions

We found out that these fake functions would cause clang to crash if the
changes proposed in https://reviews.llvm.org/D98799 were made.

The original patch was reverted in f681fd927e883301658dcac9a78109ee0aba12a8
because debug locations were missing in the body of the block byref
helper functions. This patch fixes the bug by calling CreateArtificial
after the calls to StartFunction.

Differential Revision: https://reviews.llvm.org/D104082

clang/lib/CodeGen/CGBlocks.cpp
clang/test/CodeGenCXX/debug-info-blocks.cpp
clang/test/CodeGenObjC/block-byref-debuginfo.m
clang/test/CodeGenObjC/debug-info-block-helper.m
clang/test/CodeGenObjC/debug-info-blocks.m

index 9956d12..769501a 100644 (file)
@@ -1948,21 +1948,13 @@ CodeGenFunction::GenerateCopyHelperFunction(const CGBlockInfo &blockInfo) {
   if (CGM.supportsCOMDAT())
     Fn->setComdat(CGM.getModule().getOrInsertComdat(FuncName));
 
-  IdentifierInfo *II = &C.Idents.get(FuncName);
-
   SmallVector<QualType, 2> ArgTys;
   ArgTys.push_back(C.VoidPtrTy);
   ArgTys.push_back(C.VoidPtrTy);
-  QualType FunctionTy = C.getFunctionType(ReturnTy, ArgTys, {});
 
-  FunctionDecl *FD = FunctionDecl::Create(
-      C, C.getTranslationUnitDecl(), SourceLocation(), SourceLocation(), II,
-      FunctionTy, nullptr, SC_Static, false, false);
   setBlockHelperAttributesVisibility(blockInfo.CapturesNonExternalType, Fn, FI,
                                      CGM);
-  // This is necessary to avoid inheriting the previous line number.
-  FD->setImplicit();
-  StartFunction(FD, ReturnTy, Fn, FI, args);
+  StartFunction(GlobalDecl(), ReturnTy, Fn, FI, args);
   auto AL = ApplyDebugLocation::CreateArtificial(*this);
 
   llvm::Type *structPtrTy = blockInfo.StructureType->getPointerTo();
@@ -2143,21 +2135,12 @@ CodeGenFunction::GenerateDestroyHelperFunction(const CGBlockInfo &blockInfo) {
   if (CGM.supportsCOMDAT())
     Fn->setComdat(CGM.getModule().getOrInsertComdat(FuncName));
 
-  IdentifierInfo *II = &C.Idents.get(FuncName);
-
   SmallVector<QualType, 1> ArgTys;
   ArgTys.push_back(C.VoidPtrTy);
-  QualType FunctionTy = C.getFunctionType(ReturnTy, ArgTys, {});
-
-  FunctionDecl *FD = FunctionDecl::Create(
-      C, C.getTranslationUnitDecl(), SourceLocation(), SourceLocation(), II,
-      FunctionTy, nullptr, SC_Static, false, false);
 
   setBlockHelperAttributesVisibility(blockInfo.CapturesNonExternalType, Fn, FI,
                                      CGM);
-  // This is necessary to avoid inheriting the previous line number.
-  FD->setImplicit();
-  StartFunction(FD, ReturnTy, Fn, FI, args);
+  StartFunction(GlobalDecl(), ReturnTy, Fn, FI, args);
   markAsIgnoreThreadCheckingAtRuntime(Fn);
 
   auto AL = ApplyDebugLocation::CreateArtificial(*this);
@@ -2395,21 +2378,15 @@ generateByrefCopyHelper(CodeGenFunction &CGF, const BlockByrefInfo &byrefInfo,
     llvm::Function::Create(LTy, llvm::GlobalValue::InternalLinkage,
                            "__Block_byref_object_copy_", &CGF.CGM.getModule());
 
-  IdentifierInfo *II
-    = &Context.Idents.get("__Block_byref_object_copy_");
-
   SmallVector<QualType, 2> ArgTys;
   ArgTys.push_back(Context.VoidPtrTy);
   ArgTys.push_back(Context.VoidPtrTy);
-  QualType FunctionTy = Context.getFunctionType(ReturnTy, ArgTys, {});
-
-  FunctionDecl *FD = FunctionDecl::Create(
-      Context, Context.getTranslationUnitDecl(), SourceLocation(),
-      SourceLocation(), II, FunctionTy, nullptr, SC_Static, false, false);
 
   CGF.CGM.SetInternalFunctionAttributes(GlobalDecl(), Fn, FI);
 
-  CGF.StartFunction(FD, ReturnTy, Fn, FI, args);
+  CGF.StartFunction(GlobalDecl(), ReturnTy, Fn, FI, args);
+    // Create a scope with an artificial location for the body of this function.
+  auto AL = ApplyDebugLocation::CreateArtificial(CGF);
 
   if (generator.needsCopy()) {
     llvm::Type *byrefPtrType = byrefInfo.Type->getPointerTo(0);
@@ -2471,20 +2448,14 @@ generateByrefDisposeHelper(CodeGenFunction &CGF,
                            "__Block_byref_object_dispose_",
                            &CGF.CGM.getModule());
 
-  IdentifierInfo *II
-    = &Context.Idents.get("__Block_byref_object_dispose_");
-
   SmallVector<QualType, 1> ArgTys;
   ArgTys.push_back(Context.VoidPtrTy);
-  QualType FunctionTy = Context.getFunctionType(R, ArgTys, {});
-
-  FunctionDecl *FD = FunctionDecl::Create(
-      Context, Context.getTranslationUnitDecl(), SourceLocation(),
-      SourceLocation(), II, FunctionTy, nullptr, SC_Static, false, false);
 
   CGF.CGM.SetInternalFunctionAttributes(GlobalDecl(), Fn, FI);
 
-  CGF.StartFunction(FD, R, Fn, FI, args);
+  CGF.StartFunction(GlobalDecl(), R, Fn, FI, args);
+    // Create a scope with an artificial location for the body of this function.
+  auto AL = ApplyDebugLocation::CreateArtificial(CGF);
 
   if (generator.needsDispose()) {
     Address addr = CGF.GetAddrOfLocalVar(&Src);
index 7eea3ce..e22594c 100644 (file)
@@ -12,9 +12,7 @@ void test() {
   ^{ (void)a; };
 }
 
-// CHECK: !DISubprogram(name: "__Block_byref_object_copy_",
-// CHECK-SAME:          line: 11,
+// CHECK: !DISubprogram(linkageName: "__Block_byref_object_copy_",
 // CHECK-SAME:          DISPFlagLocalToUnit | DISPFlagDefinition
-// CHECK: !DISubprogram(name: "__Block_byref_object_dispose_",
-// CHECK-SAME:          line: 11,
+// CHECK: !DISubprogram(linkageName: "__Block_byref_object_dispose_",
 // CHECK-SAME:          DISPFlagLocalToUnit | DISPFlagDefinition
index a145b28..15ff53e 100644 (file)
@@ -1,5 +1,8 @@
 // RUN: %clang_cc1 -fblocks -fobjc-arc -fobjc-runtime-has-weak -debug-info-kind=limited -triple x86_64-apple-darwin -emit-llvm %s -o - | FileCheck %s
 
+// CHECK: define internal void @__Block_byref_object_copy_({{.*}} !dbg ![[BYREF_COPY_SP:.*]] {
+// CHECK: getelementptr inbounds {{.*}}, !dbg ![[BYREF_COPY_LOC:.*]]
+
 // CHECK: !DILocalVariable(name: "foo", {{.*}}type: ![[FOOTY:[0-9]+]])
 // CHECK: ![[FOOTY]] = {{.*}}!DICompositeType({{.*}}, name: "Foo"
 
 
 // CHECK: !DILocalVariable(name: "foo", {{.*}}type: ![[FOOTY]])
 
+// CHECK: ![[BYREF_COPY_SP]] = distinct !DISubprogram(linkageName: "__Block_byref_object_copy_",
+// CHECK: ![[BYREF_COPY_LOC]] = !DILocation(line: 0, scope: ![[BYREF_COPY_SP]])
 
 struct Foo {
   unsigned char *data;
 };
+
+struct Foo2 {
+  id f0;
+};
+
+void (^bptr)(void);
+
 int func() {
   __attribute__((__blocks__(byref))) struct Foo foo;
   ^{ foo.data = 0; }();
+  __block struct Foo2 foo2;
+  bptr = ^{ foo2.f0 =0; };
   return 0;
 }
index 1d37ea4..9149628 100644 (file)
@@ -2,7 +2,7 @@
 // RUN: %clang_cc1 -emit-llvm -fblocks -debug-info-kind=limited -triple x86_64-apple-darwin10 -fobjc-runtime=macosx-fragile-10.5 %s -o - | FileCheck %s
 extern void foo(void(^)(void));
 
-// CHECK: !DISubprogram(name: "__destroy_helper_block_8_32o40r48r"
+// CHECK: !DISubprogram(linkageName: "__destroy_helper_block_8_32o40r48r"
 
 @interface NSObject {
   struct objc_object *isa;
index 257045b..64392e2 100644 (file)
@@ -25,9 +25,9 @@
 // CHECK: ret {{.*}}, !dbg ![[DESTROY_LINE]]
 
 // CHECK-DAG: [[DBG_LINE]] = !DILocation(line: 0, scope: ![[COPY_SP:[0-9]+]])
-// CHECK-DAG: [[COPY_SP]] = distinct !DISubprogram(name: "__copy_helper_block_
+// CHECK-DAG: [[COPY_SP]] = distinct !DISubprogram(linkageName: "__copy_helper_block_
 // CHECK-DAG: [[DESTROY_LINE]] = !DILocation(line: 0, scope: ![[DESTROY_SP:[0-9]+]])
-// CHECK-DAG: [[DESTROY_SP]] = distinct !DISubprogram(name: "__destroy_helper_block_
+// CHECK-DAG: [[DESTROY_SP]] = distinct !DISubprogram(linkageName: "__destroy_helper_block_
 typedef unsigned int NSUInteger;
 
 @protocol NSObject