[PATCH] D32029: [ObjC] Fix lifetime markers of loop variable in EmitObjCForCollectionStmt

2017-04-13 Thread Kuba (Brecka) Mracek via Phabricator via cfe-commits
kubamracek created this revision.
kubamracek added a project: Sanitizers.

CodeGenFunction::EmitObjCForCollectionStmt currently emits lifetime markers for 
the loop variable in an inconsistent way:  `lifetime.start` is emitted before 
the loop is entered, but `lifetime.end` is emitted inside the loop:

  ; entry block
%u = alloca %1*, align 8
%1 = bitcast %1** %u to i8*
call void @llvm.lifetime.start(i64 8, i8* %1) #5
...
  
  ; loop body
...
%14 = bitcast %1** %u to i8*
call void @llvm.lifetime.end(i64 8, i8* %14) #5
...
br i1 %21, ... ; loop
  
  ; loop ended
ret void

AddressSanitizer uses these markers to track out-of-scope accesses to local 
variables, and we get false positives in Obj-C foreach loops (in the 2nd 
iteration of the loop).  The markers of the loop variable need to be either 
both inside the loop (so that we poison and unpoison the variable in each 
iteration), or both outside.  This patch implements the "both inside" approach 
and makes EmitObjCForCollectionStmt emit:

  ; entry block
%u = alloca %1*, align 8
...
  
  ; loop body
%12 = bitcast %1** %u to i8*
call void @llvm.lifetime.start(i64 8, i8* %12) #5
...
%14 = bitcast %1** %u to i8*
call void @llvm.lifetime.end(i64 8, i8* %14) #5
br label %15
  
  ; loop ended
ret void

The test fixups are only changing the order of allocas.   There's some related 
discussion at https://reviews.llvm.org/D18618.


Repository:
  rL LLVM

https://reviews.llvm.org/D32029

Files:
  lib/CodeGen/CGObjC.cpp
  test/CodeGenObjC/arc-foreach.m
  test/CodeGenObjC/arc-ternary-op.m


Index: test/CodeGenObjC/arc-ternary-op.m
===
--- test/CodeGenObjC/arc-ternary-op.m
+++ test/CodeGenObjC/arc-ternary-op.m
@@ -120,9 +120,9 @@
 
   // CHECK-LABEL:define void @test2(
   // CHECK:  [[COND:%.*]] = alloca i32,
-  // CHECK:  alloca i8*
   // CHECK:  [[CLEANUP_SAVE:%.*]] = alloca i8*
   // CHECK:  [[RUN_CLEANUP:%.*]] = alloca i1
+  // CHECK:  alloca i8*
   //   Evaluate condition; cleanup disabled by default.
   // CHECK:  [[T0:%.*]] = load i32, i32* [[COND]],
   // CHECK-NEXT: icmp ne i32 [[T0]], 0
Index: test/CodeGenObjC/arc-foreach.m
===
--- test/CodeGenObjC/arc-foreach.m
+++ test/CodeGenObjC/arc-foreach.m
@@ -24,9 +24,9 @@
 
 // CHECK-LP64-LABEL:define void @test0(
 // CHECK-LP64:  [[ARRAY:%.*]] = alloca [[ARRAY_T:%.*]]*,
-// CHECK-LP64-NEXT: [[X:%.*]] = alloca i8*,
 // CHECK-LP64-NEXT: [[STATE:%.*]] = alloca [[STATE_T:%.*]],
 // CHECK-LP64-NEXT: [[BUFFER:%.*]] = alloca [16 x i8*], align 8
+// CHECK-LP64-NEXT: [[X:%.*]] = alloca i8*,
 // CHECK-LP64-NEXT: [[BLOCK:%.*]] = alloca [[BLOCK_T:<{.*}>]],
 
 // Initialize 'array'.
@@ -97,9 +97,9 @@
 
 // CHECK-LP64-LABEL:define void @test1(
 // CHECK-LP64:  alloca [[ARRAY_T:%.*]]*,
-// CHECK-LP64-NEXT: [[X:%.*]] = alloca i8*,
 // CHECK-LP64-NEXT: [[STATE:%.*]] = alloca [[STATE_T:%.*]],
 // CHECK-LP64-NEXT: alloca [16 x i8*], align 8
+// CHECK-LP64-NEXT: [[X:%.*]] = alloca i8*,
 // CHECK-LP64-NEXT: [[BLOCK:%.*]] = alloca [[BLOCK_T:<{.*}>]],
 
 // CHECK-LP64:  [[T0:%.*]] = getelementptr inbounds [[STATE_T]], 
[[STATE_T]]* [[STATE]], i32 0, i32 1
@@ -160,7 +160,7 @@
 
   // CHECK-LP64-LABEL:define void @test3(
   // CHECK-LP64:  [[ARRAY:%.*]] = alloca [[ARRAY_T]]*, align 8
-  // CHECK-LP64-NEXT: [[X:%.*]] = alloca i8*, align 8
+  // CHECK-LP64:  [[X:%.*]] = alloca i8*, align 8
   // CHECK-LP64:  [[T0:%.*]] = load i8*, i8** [[X]], align 8
   // CHECK-LP64-NEXT: [[T1:%.*]] = icmp ne i8* [[T0]], null
   // CHECK-LP64-NEXT: br i1 [[T1]],
Index: lib/CodeGen/CGObjC.cpp
===
--- lib/CodeGen/CGObjC.cpp
+++ lib/CodeGen/CGObjC.cpp
@@ -1469,11 +1469,6 @@
   if (DI)
 DI->EmitLexicalBlockStart(Builder, S.getSourceRange().getBegin());
 
-  // The local variable comes into scope immediately.
-  AutoVarEmission variable = AutoVarEmission::invalid();
-  if (const DeclStmt *SD = dyn_cast(S.getElement()))
-variable = EmitAutoVarAlloca(*cast(SD->getSingleDecl()));
-
   JumpDest LoopEnd = getJumpDestInCurrentScope("forcoll.end");
 
   // Fast enumeration state.
@@ -1625,8 +1620,10 @@
   bool elementIsVariable;
   LValue elementLValue;
   QualType elementType;
+  AutoVarEmission variable = AutoVarEmission::invalid();
   if (const DeclStmt *SD = dyn_cast(S.getElement())) {
 // Initialize the variable, in case it's a __block variable or something.
+variable = EmitAutoVarAlloca(*cast(SD->getSingleDecl()));
 EmitAutoVarInit(variable);
 
 const VarDecl* D = cast(SD->getSingleDecl());


Index: test/CodeGenObjC/arc-ternary-op.m
===
--- test/CodeGenObjC/arc-ternary-op.m
+++ test/CodeGenObjC/arc-ternary-op.m
@@ -120,9 +120,9 @@
 
   // CHECK-LABEL: 

[PATCH] D32029: [ObjC] Fix lifetime markers of loop variable in EmitObjCForCollectionStmt

2017-04-13 Thread Kuba (Brecka) Mracek via Phabricator via cfe-commits
kubamracek added a comment.

Note that C++ foreach loops also generate lifetime.start and lifetime.end 
inside of the loop body.


Repository:
  rL LLVM

https://reviews.llvm.org/D32029



___
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D32029: [ObjC] Fix lifetime markers of loop variable in EmitObjCForCollectionStmt

2017-04-13 Thread John McCall via Phabricator via cfe-commits
rjmccall accepted this revision.
rjmccall added a comment.
This revision is now accepted and ready to land.

Yes, looks good to me.


Repository:
  rL LLVM

https://reviews.llvm.org/D32029



___
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D32029: [ObjC] Fix lifetime markers of loop variable in EmitObjCForCollectionStmt

2017-04-13 Thread Phabricator via Phabricator via cfe-commits
This revision was automatically updated to reflect the committed changes.
Closed by commit rL300287: [ObjC] Fix lifetime markers of loop variable in 
EmitObjCForCollectionStmt (authored by kuba.brecka).

Changed prior to commit:
  https://reviews.llvm.org/D32029?vs=95157&id=95251#toc

Repository:
  rL LLVM

https://reviews.llvm.org/D32029

Files:
  cfe/trunk/lib/CodeGen/CGObjC.cpp
  cfe/trunk/test/CodeGenObjC/arc-foreach.m
  cfe/trunk/test/CodeGenObjC/arc-ternary-op.m


Index: cfe/trunk/lib/CodeGen/CGObjC.cpp
===
--- cfe/trunk/lib/CodeGen/CGObjC.cpp
+++ cfe/trunk/lib/CodeGen/CGObjC.cpp
@@ -1469,11 +1469,6 @@
   if (DI)
 DI->EmitLexicalBlockStart(Builder, S.getSourceRange().getBegin());
 
-  // The local variable comes into scope immediately.
-  AutoVarEmission variable = AutoVarEmission::invalid();
-  if (const DeclStmt *SD = dyn_cast(S.getElement()))
-variable = EmitAutoVarAlloca(*cast(SD->getSingleDecl()));
-
   JumpDest LoopEnd = getJumpDestInCurrentScope("forcoll.end");
 
   // Fast enumeration state.
@@ -1625,8 +1620,10 @@
   bool elementIsVariable;
   LValue elementLValue;
   QualType elementType;
+  AutoVarEmission variable = AutoVarEmission::invalid();
   if (const DeclStmt *SD = dyn_cast(S.getElement())) {
 // Initialize the variable, in case it's a __block variable or something.
+variable = EmitAutoVarAlloca(*cast(SD->getSingleDecl()));
 EmitAutoVarInit(variable);
 
 const VarDecl* D = cast(SD->getSingleDecl());
Index: cfe/trunk/test/CodeGenObjC/arc-foreach.m
===
--- cfe/trunk/test/CodeGenObjC/arc-foreach.m
+++ cfe/trunk/test/CodeGenObjC/arc-foreach.m
@@ -24,9 +24,9 @@
 
 // CHECK-LP64-LABEL:define void @test0(
 // CHECK-LP64:  [[ARRAY:%.*]] = alloca [[ARRAY_T:%.*]]*,
-// CHECK-LP64-NEXT: [[X:%.*]] = alloca i8*,
 // CHECK-LP64-NEXT: [[STATE:%.*]] = alloca [[STATE_T:%.*]],
 // CHECK-LP64-NEXT: [[BUFFER:%.*]] = alloca [16 x i8*], align 8
+// CHECK-LP64-NEXT: [[X:%.*]] = alloca i8*,
 // CHECK-LP64-NEXT: [[BLOCK:%.*]] = alloca [[BLOCK_T:<{.*}>]],
 
 // Initialize 'array'.
@@ -97,9 +97,9 @@
 
 // CHECK-LP64-LABEL:define void @test1(
 // CHECK-LP64:  alloca [[ARRAY_T:%.*]]*,
-// CHECK-LP64-NEXT: [[X:%.*]] = alloca i8*,
 // CHECK-LP64-NEXT: [[STATE:%.*]] = alloca [[STATE_T:%.*]],
 // CHECK-LP64-NEXT: alloca [16 x i8*], align 8
+// CHECK-LP64-NEXT: [[X:%.*]] = alloca i8*,
 // CHECK-LP64-NEXT: [[BLOCK:%.*]] = alloca [[BLOCK_T:<{.*}>]],
 
 // CHECK-LP64:  [[T0:%.*]] = getelementptr inbounds [[STATE_T]], 
[[STATE_T]]* [[STATE]], i32 0, i32 1
@@ -160,7 +160,7 @@
 
   // CHECK-LP64-LABEL:define void @test3(
   // CHECK-LP64:  [[ARRAY:%.*]] = alloca [[ARRAY_T]]*, align 8
-  // CHECK-LP64-NEXT: [[X:%.*]] = alloca i8*, align 8
+  // CHECK-LP64:  [[X:%.*]] = alloca i8*, align 8
   // CHECK-LP64:  [[T0:%.*]] = load i8*, i8** [[X]], align 8
   // CHECK-LP64-NEXT: [[T1:%.*]] = icmp ne i8* [[T0]], null
   // CHECK-LP64-NEXT: br i1 [[T1]],
Index: cfe/trunk/test/CodeGenObjC/arc-ternary-op.m
===
--- cfe/trunk/test/CodeGenObjC/arc-ternary-op.m
+++ cfe/trunk/test/CodeGenObjC/arc-ternary-op.m
@@ -120,9 +120,9 @@
 
   // CHECK-LABEL:define void @test2(
   // CHECK:  [[COND:%.*]] = alloca i32,
-  // CHECK:  alloca i8*
   // CHECK:  [[CLEANUP_SAVE:%.*]] = alloca i8*
   // CHECK:  [[RUN_CLEANUP:%.*]] = alloca i1
+  // CHECK:  alloca i8*
   //   Evaluate condition; cleanup disabled by default.
   // CHECK:  [[T0:%.*]] = load i32, i32* [[COND]],
   // CHECK-NEXT: icmp ne i32 [[T0]], 0


Index: cfe/trunk/lib/CodeGen/CGObjC.cpp
===
--- cfe/trunk/lib/CodeGen/CGObjC.cpp
+++ cfe/trunk/lib/CodeGen/CGObjC.cpp
@@ -1469,11 +1469,6 @@
   if (DI)
 DI->EmitLexicalBlockStart(Builder, S.getSourceRange().getBegin());
 
-  // The local variable comes into scope immediately.
-  AutoVarEmission variable = AutoVarEmission::invalid();
-  if (const DeclStmt *SD = dyn_cast(S.getElement()))
-variable = EmitAutoVarAlloca(*cast(SD->getSingleDecl()));
-
   JumpDest LoopEnd = getJumpDestInCurrentScope("forcoll.end");
 
   // Fast enumeration state.
@@ -1625,8 +1620,10 @@
   bool elementIsVariable;
   LValue elementLValue;
   QualType elementType;
+  AutoVarEmission variable = AutoVarEmission::invalid();
   if (const DeclStmt *SD = dyn_cast(S.getElement())) {
 // Initialize the variable, in case it's a __block variable or something.
+variable = EmitAutoVarAlloca(*cast(SD->getSingleDecl()));
 EmitAutoVarInit(variable);
 
 const VarDecl* D = cast(SD->getSingleDecl());
Index: cfe/trunk/test/CodeGenObjC/arc-foreach.m
===
--- cfe/trunk/test/CodeGenObjC/arc-foreach.m
+++ cfe/trunk/test/CodeGenObjC/arc-foreach.m
@@ -24,9 +24,9 @@
 
 // CHE

[PATCH] D32029: [ObjC] Fix lifetime markers of loop variable in EmitObjCForCollectionStmt

2017-04-13 Thread Kuba (Brecka) Mracek via Phabricator via cfe-commits
kubamracek reopened this revision.
kubamracek added a comment.
This revision is now accepted and ready to land.

Reverted because this fails for-in.m by crashing the compiler when compiling:

  void t2(NSArray *array) {
for (NSArray *array in array) { // expected-warning {{collection expression 
type 'NSArray *' may not respond}}
}
  }


Repository:
  rL LLVM

https://reviews.llvm.org/D32029



___
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D32029: [ObjC] Fix lifetime markers of loop variable in EmitObjCForCollectionStmt

2017-04-13 Thread Kuba (Brecka) Mracek via Phabricator via cfe-commits
kubamracek updated this revision to Diff 95271.
kubamracek added a comment.

Trying a different approach:  Keeping the loop variable alive for the whole 
loop by extending ForScope and registering the cleanup function inside 
EmitAutoVarAlloca.


https://reviews.llvm.org/D32029

Files:
  lib/CodeGen/CGDecl.cpp
  lib/CodeGen/CGObjC.cpp
  test/CodeGenObjC/arc-blocks.m
  test/CodeGenObjCXX/arc-references.mm

Index: test/CodeGenObjCXX/arc-references.mm
===
--- test/CodeGenObjCXX/arc-references.mm
+++ 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
 }
 
Index: test/CodeGenObjC/arc-blocks.m
===
--- test/CodeGenObjC/arc-blocks.m
+++ test/CodeGenObjC/arc-blocks.m
@@ -532,16 +532,16 @@
   // 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]]
   // CHECK:  [[T0:%.*]] = load i8*, i8** [[CLEANUP_ADDR]]
   // 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: lib/CodeGen/CGObjC.cpp
===
--- lib/CodeGen/CGObjC.cpp
+++ 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: lib/CodeGen/CGDecl.cpp
===
--- lib/CodeGen/CGDecl.cpp
+++ 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);
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D32029: [ObjC] Fix lifetime markers of loop variable in EmitObjCForCollectionStmt

2017-04-13 Thread John McCall via Phabricator via cfe-commits
rjmccall added a comment.

Those test changes are smaller than I thought they might be; great.


https://reviews.llvm.org/D32029



___
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D32029: [ObjC] Fix lifetime markers of loop variable in EmitObjCForCollectionStmt

2017-04-14 Thread Phabricator via Phabricator via cfe-commits
This revision was automatically updated to reflect the committed changes.
Closed by commit rL300340: [ObjC] Fix lifetime markers of loop variable in 
EmitObjCForCollectionStmt [takeā€¦ (authored by kuba.brecka).

Changed prior to commit:
  https://reviews.llvm.org/D32029?vs=95271&id=95313#toc

Repository:
  rL LLVM

https://reviews.llvm.org/D32029

Files:
  cfe/trunk/lib/CodeGen/CGDecl.cpp
  cfe/trunk/lib/CodeGen/CGObjC.cpp
  cfe/trunk/test/CodeGenObjC/arc-blocks.m
  cfe/trunk/test/CodeGenObjCXX/arc-references.mm

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/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/test/CodeGenObjC/arc-blocks.m
===
--- cfe/trunk/test/CodeGenObjC/arc-blocks.m
+++ cfe/trunk/test/CodeGenObjC/arc-blocks.m
@@ -532,16 +532,16 @@
   // 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]]
   // CHECK:  [[T0:%.*]] = load i8*, i8** [[CLEANUP_ADDR]]
   // 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
 }
 
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits