1// RUN: %clang_cc1 -triple x86_64-apple-darwin10 -emit-llvm -fobjc-arc -fobjc-runtime-has-weak -o - %s | FileCheck %s 2 3// CHECK: %[[STRUCT_TRIVIAL:.*]] = type { i32 } 4// CHECK: %[[STRUCT_TRIVIALBIG:.*]] = type { [64 x i32] } 5// CHECK: %[[STRUCT_STRONG:.*]] = type { ptr } 6// CHECK: %[[STRUCT_WEAK:.*]] = type { ptr } 7 8typedef struct { 9 int x; 10} Trivial; 11 12typedef struct { 13 int x[64]; 14} TrivialBig; 15 16typedef struct { 17 id x; 18} Strong; 19 20typedef struct { 21 __weak id x; 22} Weak; 23 24// CHECK: define{{.*}} i32 @testTrivial() 25// CHECK: %[[RETVAL:.*]] = alloca %[[STRUCT_TRIVIAL]], align 4 26// CHECK-NEXT: call void @func0(ptr noundef %[[RETVAL]]) 27// CHECK-NOT: memcpy 28// CHECK: ret i32 % 29 30void func0(Trivial *); 31 32Trivial testTrivial(void) { 33 Trivial a; 34 func0(&a); 35 return a; 36} 37 38void func1(TrivialBig *); 39 40// CHECK: define{{.*}} void @testTrivialBig(ptr dead_on_unwind noalias writable sret(%[[STRUCT_TRIVIALBIG]]) align 4 %[[AGG_RESULT:.*]]) 41// CHECK: call void @func1(ptr noundef %[[AGG_RESULT]]) 42// CHECK-NEXT: ret void 43 44TrivialBig testTrivialBig(void) { 45 TrivialBig a; 46 func1(&a); 47 return a; 48} 49 50// CHECK: define{{.*}} ptr @testStrong() 51// CHECK: %[[RETVAL:.*]] = alloca %[[STRUCT_STRONG]], align 8 52// CHECK: %[[NRVO:.*]] = alloca i1, align 1 53// CHECK: call void @__default_constructor_8_s0(ptr %[[RETVAL]]) 54// CHECK: store i1 true, ptr %[[NRVO]], align 1 55// CHECK: %[[NRVO_VAL:.*]] = load i1, ptr %[[NRVO]], align 1 56// CHECK: br i1 %[[NRVO_VAL]], 57 58// CHECK: call void @__destructor_8_s0(ptr %[[RETVAL]]) 59// CHECK: br 60 61// CHECK: %[[COERCE_DIVE:.*]] = getelementptr inbounds nuw %[[STRUCT_STRONG]], ptr %[[RETVAL]], i32 0, i32 0 62// CHECK: %[[V2:.*]] = load ptr, ptr %[[COERCE_DIVE]], align 8 63// CHECK: ret ptr %[[V2]] 64 65Strong testStrong(void) { 66 Strong a; 67 return a; 68} 69 70// CHECK: define{{.*}} void @testWeak(ptr dead_on_unwind noalias writable sret(%[[STRUCT_WEAK]]) align 8 %[[AGG_RESULT:.*]]) 71// CHECK: %[[NRVO:.*]] = alloca i1, align 1 72// CHECK: call void @__default_constructor_8_w0(ptr %[[AGG_RESULT]]) 73// CHECK: store i1 true, ptr %[[NRVO]], align 1 74// CHECK: %[[NRVO_VAL:.*]] = load i1, ptr %[[NRVO]], align 1 75// CHECK: br i1 %[[NRVO_VAL]], 76 77// CHECK: call void @__destructor_8_w0(ptr %[[AGG_RESULT]]) 78// CHECK: br 79 80// CHECK-NOT: call 81// CHECK: ret void 82 83Weak testWeak(void) { 84 Weak a; 85 return a; 86} 87 88// CHECK: define{{.*}} void @testWeak2( 89// CHECK: call void @__default_constructor_8_w0( 90// CHECK: call void @__default_constructor_8_w0( 91// CHECK: call void @__copy_constructor_8_8_w0( 92// CHECK: call void @__copy_constructor_8_8_w0( 93// CHECK: call void @__destructor_8_w0( 94// CHECK: call void @__destructor_8_w0( 95 96Weak testWeak2(int c) { 97 Weak a, b; 98 if (c) 99 return a; 100 else 101 return b; 102} 103 104// CHECK: define internal void @"\01-[C1 foo1]"(ptr dead_on_unwind noalias writable sret(%[[STRUCT_WEAK]]) align 8 %[[AGG_RESULT:.*]], ptr noundef %{{.*}}, ptr noundef %{{.*}}) 105// CHECK: %[[NRVO:.*]] = alloca i1, align 1 106// CHECK: call void @__default_constructor_8_w0(ptr %[[AGG_RESULT]]) 107// CHECK: store i1 true, ptr %[[NRVO]], align 1 108// CHECK: %[[NRVO_VAL:.*]] = load i1, ptr %[[NRVO]], align 1 109// CHECK: br i1 %[[NRVO_VAL]], 110 111// CHECK: call void @__destructor_8_w0(ptr %[[AGG_RESULT]]) 112// CHECK: br 113 114// CHECK-NOT: call 115// CHECK: ret void 116 117__attribute__((objc_root_class)) 118@interface C1 119- (Weak)foo1; 120@end 121 122@implementation C1 123- (Weak)foo1 { 124 Weak a; 125 return a; 126} 127@end 128