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 @_Z20basicCorrectnessTestv 8void basicCorrectnessTest() { 9 // CHECK: [[X:%.*]] = alloca ptr, align 8 10 // CHECK-NEXT: [[OBJ1:%.*]] = call noundef ptr @_Z11makeObject1v() 11 // CHECK-NEXT: store ptr [[OBJ1]], ptr [[X]], align 8 12 id x = makeObject1(); 13 14 // CHECK-NEXT: [[OBJ2:%.*]] = call noundef ptr @_Z11makeObject2v() 15 // CHECK-NEXT: call void @_Z13releaseObjectP11objc_object(ptr noundef [[OBJ2]]) 16 releaseObject(makeObject2()); 17 18 // CHECK-NEXT: call void @llvm.objc.storeStrong(ptr [[X]], ptr 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 ptr, align 8 34 // CHECK-NEXT: [[OBJ1:%.*]] = call noundef ptr @_Z12makeObjectT1IU8__strongP11objc_objectET_v() 35 // CHECK-NEXT: store ptr [[OBJ1]], ptr [[X]], align 8 36 id x = makeObjectT1<id>(); 37 38 // CHECK-NEXT: [[OBJ2:%.*]] = call noundef ptr @_Z12makeObjectT2IU8__strongP11objc_objectET_v() 39 // CHECK-NEXT: call void @_Z13releaseObjectP11objc_object(ptr noundef [[OBJ2]]) 40 releaseObject(makeObjectT2<id>()); 41 42 // CHECK-NEXT: [[OBJ3:%.*]] = call noundef ptr @_Z11makeObject1v() 43 // CHECK-NEXT: call void @_Z14releaseObjectTIU8__strongP11objc_objectEvT_(ptr noundef [[OBJ3]]) 44 releaseObjectT(makeObject1()); 45 46 // CHECK-NEXT: call void @llvm.objc.storeStrong(ptr [[X]], ptr 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 ptr %x, ptr [[X:%.*]], 60// CHECK-NOT: [[X]] 61// CHECK: call void @llvm.objc.storeStrong(ptr [[X]], ptr null) 62 63// CHECK: define{{.*}} void @_ZN15ForwardConsumedC1EP11objc_object( 64// CHECK-NOT: objc_retain 65// CHECK: store ptr %x, ptr [[X:%.*]], 66// CHECK: [[T0:%.*]] = load ptr, ptr [[X]], 67// CHECK-NEXT: store ptr null, ptr [[X]], 68// CHECK-NEXT: call void @_ZN15ForwardConsumedC2EP11objc_object({{.*}}, ptr noundef [[T0]]) 69// CHECK: call void @llvm.objc.storeStrong(ptr [[X]], ptr null) 70