1// RUN: %clang_cc1 -triple x86_64-apple-darwin11 -emit-llvm -fobjc-arc -o - %s | FileCheck %s 2 3id makeObject1() __attribute__((ns_returns_retained)); 4id makeObject2() __attribute__((ns_returns_retained)); 5void releaseObject(__attribute__((ns_consumed)) id); 6 7// CHECK-LABEL: define void @_Z10sanityTestv 8void sanityTest() { 9 // CHECK: [[X:%.*]] = alloca i8*, align 8 10 // CHECK-NEXT: [[OBJ1:%.*]] = call i8* @_Z11makeObject1v() 11 // CHECK-NEXT: store i8* [[OBJ1]], i8** [[X]], align 8 12 id x = makeObject1(); 13 14 // CHECK-NEXT: [[OBJ2:%.*]] = call i8* @_Z11makeObject2v() 15 // CHECK-NEXT: call void @_Z13releaseObjectP11objc_object(i8* [[OBJ2]]) 16 releaseObject(makeObject2()); 17 18 // CHECK-NEXT: call void @llvm.objc.storeStrong(i8** [[X]], i8* null) 19 // CHECK-NEXT: ret void 20} 21 22 23template <typename T> 24T makeObjectT1() __attribute__((ns_returns_retained)); 25template <typename T> 26T makeObjectT2() __attribute__((ns_returns_retained)); 27 28template <typename T> 29void releaseObjectT(__attribute__((ns_consumed)) T); 30 31// CHECK-LABEL: define void @_Z12templateTestv 32void templateTest() { 33 // CHECK: [[X:%.*]] = alloca i8*, align 8 34 // CHECK-NEXT: [[OBJ1:%.*]] = call i8* @_Z12makeObjectT1IU8__strongP11objc_objectET_v() 35 // CHECK-NEXT: store i8* [[OBJ1]], i8** [[X]], align 8 36 id x = makeObjectT1<id>(); 37 38 // CHECK-NEXT: [[OBJ2:%.*]] = call i8* @_Z12makeObjectT2IU8__strongP11objc_objectET_v() 39 // CHECK-NEXT: call void @_Z13releaseObjectP11objc_object(i8* [[OBJ2]]) 40 releaseObject(makeObjectT2<id>()); 41 42 // CHECK-NEXT: [[OBJ3:%.*]] = call i8* @_Z11makeObject1v() 43 // CHECK-NEXT: call void @_Z14releaseObjectTIU8__strongP11objc_objectEvT_(i8* [[OBJ3]]) 44 releaseObjectT(makeObject1()); 45 46 // CHECK-NEXT: call void @llvm.objc.storeStrong(i8** [[X]], i8* null) 47 // CHECK-NEXT: ret void 48} 49 50// PR27887 51struct ForwardConsumed { 52 ForwardConsumed(__attribute__((ns_consumed)) id x); 53}; 54 55ForwardConsumed::ForwardConsumed(__attribute__((ns_consumed)) id x) {} 56 57// CHECK: define void @_ZN15ForwardConsumedC2EP11objc_object( 58// CHECK-NOT: objc_retain 59// CHECK: store i8* {{.*}}, i8** [[X:%.*]], 60// CHECK-NOT: [[X]] 61// CHECK: call void @llvm.objc.storeStrong(i8** [[X]], i8* null) 62 63// CHECK: define void @_ZN15ForwardConsumedC1EP11objc_object( 64// CHECK-NOT: objc_retain 65// CHECK: store i8* {{.*}}, i8** [[X:%.*]], 66// CHECK: [[T0:%.*]] = load i8*, i8** [[X]], 67// CHECK-NEXT: store i8* null, i8** [[X]], 68// CHECK-NEXT: call void @_ZN15ForwardConsumedC2EP11objc_object({{.*}}, i8* [[T0]]) 69// CHECK: call void @llvm.objc.storeStrong(i8** [[X]], i8* null) 70