Index: cfe/trunk/lib/CodeGen/CGDecl.cpp =================================================================== --- cfe/trunk/lib/CodeGen/CGDecl.cpp +++ cfe/trunk/lib/CodeGen/CGDecl.cpp @@ -1118,6 +1118,12 @@ if (D.hasAttr()) EmitVarAnnotations(&D, address.getPointer()); + // Make sure we call @llvm.lifetime.end. + if (emission.useLifetimeMarkers()) + EHStack.pushCleanup(NormalEHLifetimeMarker, + emission.getAllocatedAddress(), + emission.getSizeForLifetimeMarkers()); + return emission; } @@ -1408,13 +1414,6 @@ const VarDecl &D = *emission.Variable; - // Make sure we call @llvm.lifetime.end. This needs to happen - // *last*, so the cleanup needs to be pushed *first*. - if (emission.useLifetimeMarkers()) - EHStack.pushCleanup(NormalEHLifetimeMarker, - emission.getAllocatedAddress(), - emission.getSizeForLifetimeMarkers()); - // Check the type for a cleanup. if (QualType::DestructionKind dtorKind = D.getType().isDestructedType()) emitAutoVarTypeCleanup(emission, dtorKind); Index: cfe/trunk/lib/CodeGen/CGObjC.cpp =================================================================== --- cfe/trunk/lib/CodeGen/CGObjC.cpp +++ cfe/trunk/lib/CodeGen/CGObjC.cpp @@ -1469,6 +1469,8 @@ if (DI) DI->EmitLexicalBlockStart(Builder, S.getSourceRange().getBegin()); + RunCleanupsScope ForScope(*this); + // The local variable comes into scope immediately. AutoVarEmission variable = AutoVarEmission::invalid(); if (const DeclStmt *SD = dyn_cast(S.getElement())) @@ -1499,8 +1501,6 @@ ArrayType::Normal, 0); Address ItemsPtr = CreateMemTemp(ItemsTy, "items.ptr"); - RunCleanupsScope ForScope(*this); - // Emit the collection pointer. In ARC, we do a retain. llvm::Value *Collection; if (getLangOpts().ObjCAutoRefCount) { Index: cfe/trunk/test/CodeGenObjC/arc-blocks.m =================================================================== --- cfe/trunk/test/CodeGenObjC/arc-blocks.m +++ cfe/trunk/test/CodeGenObjC/arc-blocks.m @@ -532,8 +532,6 @@ // CHECK-NEXT: [[T0:%.*]] = load void ()*, void ()** [[B]] // CHECK-NEXT: [[T1:%.*]] = bitcast void ()* [[T0]] to i8* // CHECK-NEXT: call void @objc_release(i8* [[T1]]) - // CHECK-NEXT: [[BPTR2:%.*]] = bitcast void ()** [[B]] to i8* - // CHECK-NEXT: call void @llvm.lifetime.end.p0i8(i64 8, i8* [[BPTR2]]) // CHECK-NEXT: [[T0:%.*]] = load i1, i1* [[CLEANUP_ACTIVE]] // CHECK-NEXT: br i1 [[T0]] @@ -541,7 +539,9 @@ // CHECK-NEXT: call void @objc_release(i8* [[T0]]) // CHECK-NEXT: br label - // CHECK: [[T0:%.*]] = load i8*, i8** [[X]] + // CHECK: [[BPTR2:%.*]] = bitcast void ()** [[B]] to i8* + // CHECK-NEXT: call void @llvm.lifetime.end.p0i8(i64 8, i8* [[BPTR2]]) + // CHECK-NEXT: [[T0:%.*]] = load i8*, i8** [[X]] // CHECK-NEXT: call void @objc_release(i8* [[T0]]) // CHECK-NEXT: ret void } Index: cfe/trunk/test/CodeGenObjCXX/arc-references.mm =================================================================== --- cfe/trunk/test/CodeGenObjCXX/arc-references.mm +++ cfe/trunk/test/CodeGenObjCXX/arc-references.mm @@ -21,7 +21,7 @@ // CHECK: call void @_Z6calleev callee(); // CHECK: call void @objc_release - // CHECK-NEXT: ret + // CHECK: ret } // No lifetime extension when we're binding a reference to an lvalue. @@ -44,9 +44,9 @@ const __weak id &ref = strong_id(); // CHECK-NEXT: call void @_Z6calleev() callee(); + // CHECK-NEXT: call void @objc_destroyWeak // CHECK-NEXT: [[PTR:%.*]] = bitcast i8*** [[REF]] to i8* // CHECK-NEXT: call void @llvm.lifetime.end.p0i8(i64 8, i8* [[PTR]]) - // CHECK-NEXT: call void @objc_destroyWeak // CHECK-NEXT: ret void }