[PATCH] D101502: [ObjC][ARC] Don't enter the cleanup scope if the initializer expression isn't an ExprWithCleanups
Akira Hatanaka via Phabricator via cfe-commits
cfe-commits at lists.llvm.org
Wed Apr 28 17:56:35 PDT 2021
ahatanak created this revision.
ahatanak added reviewers: rjmccall, erik.pilkington.
ahatanak added a project: clang.
ahatanak requested review of this revision.
This patch fixes a bug where a temporary ObjC pointer is released before the end of the full expression.
This fixes PR50043.
rdar://77030453
Repository:
rG LLVM Github Monorepo
https://reviews.llvm.org/D101502
Files:
clang/lib/CodeGen/CGDecl.cpp
clang/test/CodeGenObjCXX/arc-blocks.mm
clang/test/CodeGenObjCXX/arc.mm
Index: clang/test/CodeGenObjCXX/arc.mm
===================================================================
--- clang/test/CodeGenObjCXX/arc.mm
+++ clang/test/CodeGenObjCXX/arc.mm
@@ -334,3 +334,17 @@
// CHECK: [[T0:%.*]] = load i8**, i8*** [[X]]
// CHECK-NEXT: call void @llvm.objc.moveWeak(i8** [[Y]], i8** [[T0]])
// CHECK-NEXT: call void @llvm.objc.destroyWeak(i8** [[Y]])
+
+void test42() {
+ __attribute__((ns_returns_retained)) id test42_0();
+ id test42_1(id);
+ void test42_2(id &&);
+ test42_2(test42_1(test42_0()));
+}
+
+// Check that the pointer returned by test42_0 is released after the full expression.
+
+// CHECK-LABEL: define void @_Z6test42v()
+// CHECK: %[[CALL:.*]] = call i8* @_Z8test42_0v()
+// CHECK: call void @_Z8test42_2OU15__autoreleasingP11objc_object(
+// CHECK: call void @llvm.objc.release(i8* %[[CALL]])
Index: clang/test/CodeGenObjCXX/arc-blocks.mm
===================================================================
--- clang/test/CodeGenObjCXX/arc-blocks.mm
+++ clang/test/CodeGenObjCXX/arc-blocks.mm
@@ -204,10 +204,10 @@
// Test that calls to @llvm.objc.retainBlock aren't emitted in some cases.
-namespace test_block_retain {
- typedef void (^BlockTy)();
+typedef void (^BlockTy)();
+void foo1(id);
- void foo1(id);
+namespace test_block_retain {
// CHECK-LABEL: define{{.*}} void @_ZN17test_block_retain14initializationEP11objc_object(
// CHECK-NOT: @llvm.objc.retainBlock(
@@ -320,4 +320,25 @@
b1 = b0;
((BlockTy)b1)();
}
-}
+ }
+
+ // Check that the block capture is released after the full expression.
+
+ // CHECK-LABEL: define void @_ZN13test_rval_ref4testEP11objc_object(
+ // CHECK: %[[BLOCK:.*]] = alloca <{ i8*, i32, i32, i8*, %[[STRUCT_BLOCK_DESCRIPTOR]]*, i8* }>, align 8
+ // CHECK: %[[BLOCK_CAPTURED:.*]] = getelementptr inbounds <{ i8*, i32, i32, i8*, %[[STRUCT_BLOCK_DESCRIPTOR]]*, i8* }>, <{ i8*, i32, i32, i8*, %[[STRUCT_BLOCK_DESCRIPTOR]]*, i8* }>* %[[BLOCK]], i32 0, i32 5
+ // CHECK: %[[V1:.*]] = call i8* @llvm.objc.retain(
+ // CHECK: store i8* %[[V1]], i8** %[[BLOCK_CAPTURED]], align 8
+ // CHECK: invoke void @_ZN13test_rval_ref17callTemplateBlockEOU15__autoreleasingU13block_pointerFvvE(
+
+ // CHECK: call void @llvm.objc.storeStrong(i8** %[[BLOCK_CAPTURED]], i8* null)
+
+ namespace test_rval_ref {
+ void callTemplateBlock(BlockTy &&func);
+
+ void test(id str) {
+ return callTemplateBlock(^void() {
+ foo1(str);
+ });
+ }
+ }
Index: clang/lib/CodeGen/CGDecl.cpp
===================================================================
--- clang/lib/CodeGen/CGDecl.cpp
+++ clang/lib/CodeGen/CGDecl.cpp
@@ -772,9 +772,10 @@
// If we're emitting a value with lifetime, we have to do the
// initialization *before* we leave the cleanup scopes.
- if (const ExprWithCleanups *EWC = dyn_cast<ExprWithCleanups>(init))
- init = EWC->getSubExpr();
- CodeGenFunction::RunCleanupsScope Scope(*this);
+ if (auto *EWC = dyn_cast<ExprWithCleanups>(init)) {
+ CodeGenFunction::RunCleanupsScope Scope(*this);
+ return EmitScalarInit(EWC->getSubExpr(), D, lvalue, capturedByInit);
+ }
// We have to maintain the illusion that the variable is
// zero-initialized. If the variable might be accessed in its
-------------- next part --------------
A non-text attachment was scrubbed...
Name: D101502.341366.patch
Type: text/x-patch
Size: 3245 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/cfe-commits/attachments/20210429/311ea902/attachment.bin>
More information about the cfe-commits
mailing list