brintos

brintos / llvm-project-archived public Read only

0
0
Text · 5.5 KiB · f460da2 Raw
114 lines · c
1// RUN: %clang_cc1 -triple arm64-apple-ios -fptrauth-calls -fptrauth-intrinsics -fblocks -emit-llvm %s  -o - | FileCheck %s2 3struct A {4  int value;5};6struct A *createA(void);7 8void use_block(int (^)(void));9 10// CHECK-LABEL: define void @test_block_nonaddress_capture(11void test_block_nonaddress_capture() {12  // CHECK: [[VAR:%.*]] = alloca ptr,13  // CHECK: [[BLOCK:%.*]] = alloca14  //   flags - no copy/dispose required15  // CHECK: store i32 1073741824, ptr16  // CHECK: [[CAPTURE:%.*]] = getelementptr inbounds {{.*}} [[BLOCK]], i32 0, i32 517  // CHECK: [[LOAD:%.*]] = load ptr, ptr [[VAR]],18  // CHECK: store ptr [[LOAD]], ptr [[CAPTURE]]19  struct A * __ptrauth(1, 0, 15) ptr = createA();20  use_block(^{ return ptr->value; });21}22// CHECK-LABEL: define internal i32 @__test_block_nonaddress_capture_block_invoke23// CHECK: call i64 @llvm.ptrauth.auth(i64 {{%.*}}, i32 1, i64 15)24 25// CHECK-LABEL: define void @test_block_address_capture(26void test_block_address_capture() {27  // CHECK: [[VAR:%.*]] = alloca ptr,28  // CHECK: [[BLOCK:%.*]] = alloca29  //   flags - copy/dispose required30  // CHECK: store i32 1107296256, ptr31  // CHECK: [[CAPTURE:%.*]] = getelementptr inbounds {{.*}} [[BLOCK]], i32 0, i32 532  // CHECK: [[LOAD:%.*]] = load ptr, ptr [[VAR]],33  // CHECK: [[T0:%.*]] = ptrtoint ptr [[VAR]] to i6434  // CHECK: [[OLDDISC:%.*]] = call i64 @llvm.ptrauth.blend(i64 [[T0]], i64 30)35  // CHECK: [[T0:%.*]] = ptrtoint ptr [[CAPTURE]] to i6436  // CHECK: [[NEWDISC:%.*]] = call i64 @llvm.ptrauth.blend(i64 [[T0]], i64 30)37  // CHECK: [[T0:%.*]] = icmp ne ptr [[LOAD]], null38  // CHECK: br i1 [[T0]]39  // CHECK: [[T0:%.*]] = ptrtoint ptr [[LOAD]] to i6440  // CHECK: [[T1:%.*]] = call i64 @llvm.ptrauth.resign(i64 [[T0]], i32 1, i64 [[OLDDISC]], i32 1, i64 [[NEWDISC]])41  // CHECK: [[T2:%.*]] = inttoptr i64 [[T1]] to ptr42  // CHECK: [[T0:%.*]] = phi43  // CHECK: store ptr [[T0]], ptr [[CAPTURE]]44  struct A * __ptrauth(1, 1, 30) ptr = createA();45  use_block(^{ return ptr->value; });46}47// CHECK-LABEL: define internal i32 @__test_block_address_capture_block_invoke48// CHECK: call i64 @llvm.ptrauth.auth(i64 {{%.*}}, i32 1, i64 {{%.*}})49 50// CHECK: linkonce_odr hidden void @__copy_helper_block_8_32p1d30(51// CHECK: [[OLDSLOT:%.*]] = getelementptr inbounds {{.*}} {{.*}}, i32 0, i32 552// CHECK: [[NEWSLOT:%.*]] = getelementptr inbounds {{.*}} {{.*}}, i32 0, i32 553// CHECK: [[LOAD:%.*]] = load ptr, ptr [[OLDSLOT]],54// CHECK: [[T0:%.*]] = ptrtoint ptr [[OLDSLOT]] to i6455// CHECK: [[OLDDISC:%.*]] = call i64 @llvm.ptrauth.blend(i64 [[T0]], i64 30)56// CHECK: [[T0:%.*]] = ptrtoint ptr [[NEWSLOT]] to i6457// CHECK: [[NEWDISC:%.*]] = call i64 @llvm.ptrauth.blend(i64 [[T0]], i64 30)58// CHECK: [[T0:%.*]] = icmp ne ptr [[LOAD]], null59// CHECK: br i1 [[T0]]60// CHECK: [[T0:%.*]] = ptrtoint ptr [[LOAD]] to i6461// CHECK: [[T1:%.*]] = call i64 @llvm.ptrauth.resign(i64 [[T0]], i32 1, i64 [[OLDDISC]], i32 1, i64 [[NEWDISC]])62// CHECK: [[T2:%.*]] = inttoptr i64 [[T1]] to ptr63// CHECK: [[T0:%.*]] = phi64// CHECK: store ptr [[T0]], ptr [[NEWSLOT]]65 66// CHECK-LABEL: define void @test_block_nonaddress_byref_capture(67void test_block_nonaddress_byref_capture() {68  //   flags - no copy/dispose required for byref69  // CHECK: store i32 0,70  // CHECK: call ptr @createA()71  //   flags - copy/dispose required for block (because it captures byref)72  // CHECK: store i32 1107296256,73  __block struct A * __ptrauth(1, 0, 45) ptr = createA();74  use_block(^{ return ptr->value; });75}76 77// CHECK-LABEL: define void @test_block_address_byref_capture(78void test_block_address_byref_capture() {79  // CHECK: [[BYREF:%.*]] = alloca [[BYREF_T:.*]], align80  // CHECK: [[BLOCK:%.*]] = alloca81  //   flags - byref requires copy/dispose82  // CHECK: store i32 33554432,83  // CHECK: store i32 48,84  // CHECK: [[COPY_HELPER_FIELD:%.*]] = getelementptr inbounds nuw [[BYREF_T]], ptr [[BYREF]], i32 0, i32 485  // CHECK: [[T0:%.*]] = ptrtoint ptr [[COPY_HELPER_FIELD]] to i6486  // CHECK: [[T1:%.*]] = call i64 @llvm.ptrauth.sign(i64 ptrtoint (ptr @__Block_byref_object_copy_ to i64), i32 0, i64 [[T0]])87  // CHECK: [[T2:%.*]] = inttoptr i64 [[T1]] to ptr88  // CHECK: store ptr [[T2]], ptr [[COPY_HELPER_FIELD]], align89  // CHECK: [[DISPOSE_HELPER_FIELD:%.*]] = getelementptr inbounds nuw [[BYREF_T]], ptr [[BYREF]], i32 0, i32 590  // CHECK: [[T0:%.*]] = ptrtoint ptr [[DISPOSE_HELPER_FIELD]] to i6491  // CHECK: [[T1:%.*]] = call i64 @llvm.ptrauth.sign(i64 ptrtoint (ptr @__Block_byref_object_dispose_ to i64), i32 0, i64 [[T0]])92  // CHECK: [[T2:%.*]] = inttoptr i64 [[T1]] to ptr93  // CHECK: store ptr [[T2]], ptr [[DISPOSE_HELPER_FIELD]], align94  //   flags - copy/dispose required95  // CHECK: store i32 1107296256, ptr96  __block struct A * __ptrauth(1, 1, 60) ptr = createA();97  use_block(^{ return ptr->value; });98}99// CHECK-LABEL: define internal void @__Block_byref_object_copy_100// CHECK: [[NEWSLOT:%.*]] = getelementptr inbounds {{.*}} {{.*}}, i32 0, i32 6101// CHECK: [[OLDSLOT:%.*]] = getelementptr inbounds {{.*}} {{.*}}, i32 0, i32 6102// CHECK: [[LOAD:%.*]] = load ptr, ptr [[OLDSLOT]],103// CHECK: [[T0:%.*]] = ptrtoint ptr [[OLDSLOT]] to i64104// CHECK: [[OLDDISC:%.*]] = call i64 @llvm.ptrauth.blend(i64 [[T0]], i64 60)105// CHECK: [[T0:%.*]] = ptrtoint ptr [[NEWSLOT]] to i64106// CHECK: [[NEWDISC:%.*]] = call i64 @llvm.ptrauth.blend(i64 [[T0]], i64 60)107// CHECK: [[T0:%.*]] = icmp ne ptr [[LOAD]], null108// CHECK: br i1 [[T0]]109// CHECK: [[T0:%.*]] = ptrtoint ptr [[LOAD]] to i64110// CHECK: [[T1:%.*]] = call i64 @llvm.ptrauth.resign(i64 [[T0]], i32 1, i64 [[OLDDISC]], i32 1, i64 [[NEWDISC]])111// CHECK: [[T2:%.*]] = inttoptr i64 [[T1]] to ptr112// CHECK: [[T0:%.*]] = phi113// CHECK: store ptr [[T0]], ptr [[NEWSLOT]]114