// RUN: %swift -swift-version 4 -target arm64e-apple-ios12.0 -parse-stdlib -parse-as-library %s -emit-ir -module-name test -Xcc -Xclang -Xcc -fptrauth-calls | %FileCheck %s --check-prefix=CHECK // RUN: %swift -swift-version 4 -target arm64e-apple-ios12.0 -parse-stdlib -parse-as-library %s -emit-ir -module-name test -Xcc -Xclang -Xcc -fptrauth-calls // REQUIRES: CPU=arm64e // REQUIRES: OS=ios import Builtin struct S { var a, b, c: Builtin.NativeObject } // Check the constant discriminators for all value witnesses. // CHECK: @"$s4test1SVwCP.ptrauth" = private constant {{.*}} i64 55882 // CHECK: @"$s4test1SVwxx.ptrauth" = private constant {{.*}} i64 1272 // CHECK: @"$s4test1SVwcp.ptrauth" = private constant {{.*}} i64 58298 // CHECK: @"$s4test1SVwca.ptrauth" = private constant {{.*}} i64 34641 // CHECK: @__swift_memcpy24_8.ptrauth = private constant {{.*}} i64 18648 // CHECK: @"$s4test1SVwta.ptrauth" = private constant {{.*}} i64 61402 // CHECK: @"$s4test1SVwet.ptrauth" = private constant {{.*}} i64 24816 // CHECK: @"$s4test1SVwst.ptrauth" = private constant {{.*}} i64 41169 // The pointer to the value witness table is signed too. // 0x2e3f == 11839 is the constant discriminator for value witness tables. // CHECK: @"$s4test1SVWV.ptrauth" = private constant {{.*}} i64 11839 sil @test_destroy : $@convention(thin) (@in T) -> () { bb0(%0 : $*T): destroy_addr %0 : $*T %result = tuple () return %result : $() } // CHECK-LABEL: define swiftcc void @test_destroy( // CHECK: [[SIGNED_VWT_ADDR:%.*]] = getelementptr inbounds ptr, ptr {{%.*}}, i64 -1 // CHECK: [[SIGNED_VWT:%.*]] = load ptr, ptr [[SIGNED_VWT_ADDR]] // CHECK: [[SIGNED_VWT_ADDR_INT:%.*]] = ptrtoint ptr [[SIGNED_VWT_ADDR]] // CHECK: [[BLENDED_ADDR:%.*]] = call i64 @llvm.ptrauth.blend(i64 [[SIGNED_VWT_ADDR_INT]], i64 11839) // CHECK: [[SIGNED_VWT_INT:%.*]] = ptrtoint ptr [[SIGNED_VWT]] // CHECK: [[AUTHENTICATED_VWT_INT:%.*]] = call i64 @llvm.ptrauth.auth(i64 [[SIGNED_VWT_INT]], i32 2, i64 [[BLENDED_ADDR]]) // CHECK: [[AUTHENTICATED_VWT:%.*]] = inttoptr i64 [[AUTHENTICATED_VWT_INT]] // CHECK-NEXT: [[SLOT:%.*]] = getelementptr inbounds ptr, ptr [[AUTHENTICATED_VWT]], i32 // CHECK-NEXT: [[T0:%.*]] = load ptr, ptr [[SLOT]], align // CHECK-NEXT: [[T1:%.*]] = ptrtoint ptr [[SLOT]] to i64 // CHECK-NEXT: [[DISC:%.*]] = call i64 @llvm.ptrauth.blend(i64 [[T1]], i64 1272) // CHECK-NEXT: call void [[T0]](ptr noalias %0, ptr %T) {{#[0-9]+}} [ "ptrauth"(i32 0, i64 [[DISC]]) ] // CHECK-NEXT: ret void sil @test_copy_init : $@convention(thin) (@in_guaranteed T) -> (@out T) { bb0(%0 : $*T, %1 : $*T): copy_addr %1 to [init] %0 : $*T %result = tuple () return %result : $() } // CHECK-LABEL: define swiftcc void @test_copy_init( // CHECK: [[SIGNED_VWT_ADDR:%.*]] = getelementptr inbounds ptr, ptr {{%.*}}, i64 -1 // CHECK: [[SIGNED_VWT:%.*]] = load ptr, ptr [[SIGNED_VWT_ADDR]] // CHECK: [[SIGNED_VWT_ADDR_INT:%.*]] = ptrtoint ptr [[SIGNED_VWT_ADDR]] // CHECK: [[BLENDED_ADDR:%.*]] = call i64 @llvm.ptrauth.blend(i64 [[SIGNED_VWT_ADDR_INT]], i64 11839) // CHECK: [[SIGNED_VWT_INT:%.*]] = ptrtoint ptr [[SIGNED_VWT]] // CHECK: [[AUTHENTICATED_VWT_INT:%.*]] = call i64 @llvm.ptrauth.auth(i64 [[SIGNED_VWT_INT]], i32 2, i64 [[BLENDED_ADDR]]) // CHECK: [[AUTHENTICATED_VWT:%.*]] = inttoptr i64 [[AUTHENTICATED_VWT_INT]] // CHECK-NEXT: [[SLOT:%.*]] = getelementptr inbounds ptr, ptr [[AUTHENTICATED_VWT]], i32 // CHECK-NEXT: [[T0:%.*]] = load ptr, ptr [[SLOT]], align // CHECK-NEXT: [[T1:%.*]] = ptrtoint ptr [[SLOT]] to i64 // CHECK-NEXT: [[DISC:%.*]] = call i64 @llvm.ptrauth.blend(i64 [[T1]], i64 58298) // CHECK-NEXT: call ptr [[T0]](ptr noalias %0, ptr noalias %1, ptr %T) {{#[0-9]+}} [ "ptrauth"(i32 0, i64 [[DISC]]) ] // CHECK-NEXT: ret void sil @test_take_init : $@convention(thin) (@in T) -> (@out T) { bb0(%0 : $*T, %1 : $*T): copy_addr [take] %1 to [init] %0 : $*T %result = tuple () return %result : $() } // CHECK-LABEL: define swiftcc void @test_take_init( // CHECK: [[SIGNED_VWT_ADDR:%.*]] = getelementptr inbounds ptr, ptr {{%.*}}, i64 -1 // CHECK: [[SIGNED_VWT:%.*]] = load ptr, ptr [[SIGNED_VWT_ADDR]] // CHECK: [[SIGNED_VWT_ADDR_INT:%.*]] = ptrtoint ptr [[SIGNED_VWT_ADDR]] // CHECK: [[BLENDED_ADDR:%.*]] = call i64 @llvm.ptrauth.blend(i64 [[SIGNED_VWT_ADDR_INT]], i64 11839) // CHECK: [[SIGNED_VWT_INT:%.*]] = ptrtoint ptr [[SIGNED_VWT]] // CHECK: [[AUTHENTICATED_VWT_INT:%.*]] = call i64 @llvm.ptrauth.auth(i64 [[SIGNED_VWT_INT]], i32 2, i64 [[BLENDED_ADDR]]) // CHECK: [[AUTHENTICATED_VWT:%.*]] = inttoptr i64 [[AUTHENTICATED_VWT_INT]] // CHECK-NEXT: [[SLOT:%.*]] = getelementptr inbounds ptr, ptr [[AUTHENTICATED_VWT]], i32 // CHECK-NEXT: [[T0:%.*]] = load ptr, ptr [[SLOT]], align // CHECK-NEXT: [[T1:%.*]] = ptrtoint ptr [[SLOT]] to i64 // CHECK-NEXT: [[DISC:%.*]] = call i64 @llvm.ptrauth.blend(i64 [[T1]], i64 18648) // CHECK-NEXT: call ptr [[T0]](ptr noalias %0, ptr noalias %1, ptr %T) {{#[0-9]+}} [ "ptrauth"(i32 0, i64 [[DISC]]) ] // CHECK-NEXT: ret void sil @test_copy_assign : $@convention(thin) (@inout T, @in_guaranteed T) -> () { bb0(%0 : $*T, %1 : $*T): copy_addr %1 to %0 : $*T %result = tuple () return %result : $() } // CHECK-LABEL: define swiftcc void @test_copy_assign( // CHECK: [[SIGNED_VWT_ADDR:%.*]] = getelementptr inbounds ptr, ptr {{%.*}}, i64 -1 // CHECK: [[SIGNED_VWT:%.*]] = load ptr, ptr [[SIGNED_VWT_ADDR]] // CHECK: [[SIGNED_VWT_ADDR_INT:%.*]] = ptrtoint ptr [[SIGNED_VWT_ADDR]] // CHECK: [[BLENDED_ADDR:%.*]] = call i64 @llvm.ptrauth.blend(i64 [[SIGNED_VWT_ADDR_INT]], i64 11839) // CHECK: [[SIGNED_VWT_INT:%.*]] = ptrtoint ptr [[SIGNED_VWT]] // CHECK: [[AUTHENTICATED_VWT_INT:%.*]] = call i64 @llvm.ptrauth.auth(i64 [[SIGNED_VWT_INT]], i32 2, i64 [[BLENDED_ADDR]]) // CHECK: [[AUTHENTICATED_VWT:%.*]] = inttoptr i64 [[AUTHENTICATED_VWT_INT]] // CHECK-NEXT: [[SLOT:%.*]] = getelementptr inbounds ptr, ptr [[AUTHENTICATED_VWT]], i32 // CHECK-NEXT: [[T0:%.*]] = load ptr, ptr [[SLOT]], align // CHECK-NEXT: [[T1:%.*]] = ptrtoint ptr [[SLOT]] to i64 // CHECK-NEXT: [[DISC:%.*]] = call i64 @llvm.ptrauth.blend(i64 [[T1]], i64 34641) // CHECK-NEXT: call ptr [[T0]](ptr %0, ptr %1, ptr %T) {{#[0-9]+}} [ "ptrauth"(i32 0, i64 [[DISC]]) ] // CHECK-NEXT: ret void sil @test_take_assign : $@convention(thin) (@inout T, @in T) -> () { bb0(%0 : $*T, %1 : $*T): copy_addr [take] %1 to %0 : $*T %result = tuple () return %result : $() } // CHECK-LABEL: define swiftcc void @test_take_assign( // CHECK: [[SIGNED_VWT_ADDR:%.*]] = getelementptr inbounds ptr, ptr {{%.*}}, i64 -1 // CHECK: [[SIGNED_VWT:%.*]] = load ptr, ptr [[SIGNED_VWT_ADDR]] // CHECK: [[SIGNED_VWT_ADDR_INT:%.*]] = ptrtoint ptr [[SIGNED_VWT_ADDR]] // CHECK: [[BLENDED_ADDR:%.*]] = call i64 @llvm.ptrauth.blend(i64 [[SIGNED_VWT_ADDR_INT]], i64 11839) // CHECK: [[SIGNED_VWT_INT:%.*]] = ptrtoint ptr [[SIGNED_VWT]] // CHECK: [[AUTHENTICATED_VWT_INT:%.*]] = call i64 @llvm.ptrauth.auth(i64 [[SIGNED_VWT_INT]], i32 2, i64 [[BLENDED_ADDR]]) // CHECK: [[AUTHENTICATED_VWT:%.*]] = inttoptr i64 [[AUTHENTICATED_VWT_INT]] // CHECK-NEXT: [[SLOT:%.*]] = getelementptr inbounds ptr, ptr [[AUTHENTICATED_VWT]], i32 // CHECK-NEXT: [[T0:%.*]] = load ptr, ptr [[SLOT]], align // CHECK-NEXT: [[T1:%.*]] = ptrtoint ptr [[SLOT]] to i64 // CHECK-NEXT: [[DISC:%.*]] = call i64 @llvm.ptrauth.blend(i64 [[T1]], i64 61402) // CHECK-NEXT: call ptr [[T0]](ptr noalias %0, ptr noalias %1, ptr %T) {{#[0-9]+}} [ "ptrauth"(i32 0, i64 [[DISC]]) ] // CHECK-NEXT: ret void // Make sure that the local-type-data caching mechanism sets things up right. sil @test_destroy_twice : $@convention(thin) (@in T, @in T) -> () { bb0(%0 : $*T, %1 : $*T): destroy_addr %0 : $*T destroy_addr %1 : $*T %result = tuple () return %result : $() } // CHECK-LABEL: define swiftcc void @test_destroy_twice( // CHECK: [[SIGNED_VWT_ADDR:%.*]] = getelementptr inbounds ptr, ptr {{%.*}}, i64 -1 // CHECK: [[SIGNED_VWT:%.*]] = load ptr, ptr [[SIGNED_VWT_ADDR]] // CHECK: [[SIGNED_VWT_ADDR_INT:%.*]] = ptrtoint ptr [[SIGNED_VWT_ADDR]] // CHECK: [[BLENDED_ADDR:%.*]] = call i64 @llvm.ptrauth.blend(i64 [[SIGNED_VWT_ADDR_INT]], i64 11839) // CHECK: [[SIGNED_VWT_INT:%.*]] = ptrtoint ptr [[SIGNED_VWT]] // CHECK: [[AUTHENTICATED_VWT_INT:%.*]] = call i64 @llvm.ptrauth.auth(i64 [[SIGNED_VWT_INT]], i32 2, i64 [[BLENDED_ADDR]]) // CHECK: [[AUTHENTICATED_VWT:%.*]] = inttoptr i64 [[AUTHENTICATED_VWT_INT]] // CHECK-NEXT: [[SLOT:%.*]] = getelementptr inbounds ptr, ptr [[AUTHENTICATED_VWT]], i32 // CHECK-NEXT: [[T0:%.*]] = load ptr, ptr [[SLOT]], align // CHECK-NEXT: [[T1:%.*]] = ptrtoint ptr [[SLOT]] to i64 // CHECK-NEXT: [[DISC:%.*]] = call i64 @llvm.ptrauth.blend(i64 [[T1]], i64 1272) // CHECK-NEXT: call void [[T0]](ptr noalias %0, ptr %T) {{#[0-9]+}} [ "ptrauth"(i32 0, i64 [[DISC]]) ] // CHECK-NEXT: call void [[T0]](ptr noalias %1, ptr %T) {{#[0-9]+}} [ "ptrauth"(i32 0, i64 [[DISC]]) ] // CHECK-NEXT: ret void