r295034 - [CodeGen][ObjC] Use the type of the captured field of the enclosing

Akira Hatanaka via cfe-commits cfe-commits at lists.llvm.org
Mon Feb 13 22:46:55 PST 2017


Author: ahatanak
Date: Tue Feb 14 00:46:55 2017
New Revision: 295034

URL: http://llvm.org/viewvc/llvm-project?rev=295034&view=rev
Log:
[CodeGen][ObjC] Use the type of the captured field of the enclosing
block or lambda.

This is a follow-up to r281682, which fixed a bug in computeBlockInfo
where the captured VarDecl's type, rather than the captured field type
of the enclosing lambda or block, was used to compute the layout of a
block.

This commit makes similar changes to enterBlockScope. This is necessary
to correctly determine whether a block capture requires cleanup.

rdar://problem/30388124

Modified:
    cfe/trunk/lib/CodeGen/CGBlocks.cpp
    cfe/trunk/test/CodeGenObjCXX/lambda-expressions.mm

Modified: cfe/trunk/lib/CodeGen/CGBlocks.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CGBlocks.cpp?rev=295034&r1=295033&r2=295034&view=diff
==============================================================================
--- cfe/trunk/lib/CodeGen/CGBlocks.cpp (original)
+++ cfe/trunk/lib/CodeGen/CGBlocks.cpp Tue Feb 14 00:46:55 2017
@@ -318,6 +318,19 @@ static void initializeForBlockHeader(Cod
   elementTypes.push_back(CGM.getBlockDescriptorType());
 }
 
+static QualType getCaptureFieldType(const CodeGenFunction &CGF,
+                                    const BlockDecl::Capture &CI) {
+  const VarDecl *VD = CI.getVariable();
+
+  // If the variable is captured by an enclosing block or lambda expression,
+  // use the type of the capture field.
+  if (CGF.BlockInfo && CI.isNested())
+    return CGF.BlockInfo->getCapture(VD).fieldType();
+  if (auto *FD = CGF.LambdaCaptureFields.lookup(VD))
+    return FD->getType();
+  return VD->getType();
+}
+
 /// Compute the layout of the given block.  Attempts to lay the block
 /// out with minimal space requirements.
 static void computeBlockInfo(CodeGenModule &CGM, CodeGenFunction *CGF,
@@ -432,15 +445,7 @@ static void computeBlockInfo(CodeGenModu
       }
     }
 
-    QualType VT = variable->getType();
-
-    // If the variable is captured by an enclosing block or lambda expression,
-    // use the type of the capture field.
-    if (CGF->BlockInfo && CI.isNested())
-      VT = CGF->BlockInfo->getCapture(variable).fieldType();
-    else if (auto *FD = CGF->LambdaCaptureFields.lookup(variable))
-      VT = FD->getType();
-
+    QualType VT = getCaptureFieldType(*CGF, CI);
     CharUnits size = C.getTypeSizeInChars(VT);
     CharUnits align = C.getDeclAlign(variable);
     
@@ -606,8 +611,8 @@ static void enterBlockScope(CodeGenFunct
     if (capture.isConstant()) continue;
 
     // Ignore objects that aren't destructed.
-    QualType::DestructionKind dtorKind =
-      variable->getType().isDestructedType();
+    QualType VT = getCaptureFieldType(CGF, CI);
+    QualType::DestructionKind dtorKind = VT.isDestructedType();
     if (dtorKind == QualType::DK_none) continue;
 
     CodeGenFunction::Destroyer *destroyer;
@@ -634,7 +639,7 @@ static void enterBlockScope(CodeGenFunct
     if (useArrayEHCleanup) 
       cleanupKind = InactiveNormalAndEHCleanup;
 
-    CGF.pushDestroy(cleanupKind, addr, variable->getType(),
+    CGF.pushDestroy(cleanupKind, addr, VT,
                     destroyer, useArrayEHCleanup);
 
     // Remember where that cleanup was.

Modified: cfe/trunk/test/CodeGenObjCXX/lambda-expressions.mm
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CodeGenObjCXX/lambda-expressions.mm?rev=295034&r1=295033&r2=295034&view=diff
==============================================================================
--- cfe/trunk/test/CodeGenObjCXX/lambda-expressions.mm (original)
+++ cfe/trunk/test/CodeGenObjCXX/lambda-expressions.mm Tue Feb 14 00:46:55 2017
@@ -71,6 +71,10 @@ void take_block(void (^block)()) { block
 // ARC:   %[[CAPTURE1:.*]] = getelementptr inbounds <{ i8*, i32, i32, i8*, %struct.__block_descriptor*, i32 }>, <{ i8*, i32, i32, i8*, %struct.__block_descriptor*, i32 }>* %[[BLOCK]], i32 0, i32 5
 // ARC:   store i32 %{{.*}}, i32* %[[CAPTURE1]]
 
+// ARC-LABEL: define internal void @"_ZZ10-[Foo foo]ENK3$_4clEv"(
+// ARC-NOT: @objc_storeStrong(
+// ARC: ret void
+
 // ARC: define internal void @"___ZZN13LambdaCapture4foo1ERiENK3$_3clEv_block_invoke"
 // ARC:   %[[CAPTURE2:.*]] = getelementptr inbounds <{ i8*, i32, i32, i8*, %struct.__block_descriptor*, i32 }>, <{ i8*, i32, i32, i8*, %struct.__block_descriptor*, i32 }>* %{{.*}}, i32 0, i32 5
 // ARC:   store i32 %{{.*}}, i32* %[[CAPTURE2]]
@@ -124,6 +128,15 @@ namespace BlockInLambda {
   };
 }
 
+ at interface NSObject @end
+ at interface Foo : NSObject @end
+ at implementation Foo
+- (void)foo {
+  [&] {
+    ^{ (void)self; }();
+  }();
+}
+ at end
 
 // ARC: attributes [[NUW]] = { noinline nounwind{{.*}} }
 // MRC: attributes [[NUW]] = { noinline nounwind{{.*}} }




More information about the cfe-commits mailing list