// RUN: %swift -swift-version 5 -target arm64e-apple-ios12.0 -parse-stdlib %s -emit-ir -disable-llvm-optzns -o - | %FileCheck %s --check-prefix=CHECK // REQUIRES: CODEGENERATOR=ARM // REQUIRES: CPU=arm64e // REQUIRES: OS=ios // UNSUPPORTED: CPU=arm64e // CHECK: [[PROTOTYPE_HOLDER_INOUT_VALUE:@"\$s29ptrauth_generalized_accessors6HolderVIetMl_TC.ptrauth"]] = // CHECK-SAME: private constant { i8*, i32, i64, i64 } { i8* bitcast (void (i8*, i1)* @"$s29ptrauth_generalized_accessors6HolderVIetMl_TC" to i8*), i32 0, i64 1, i64 [[PTRAUTH_INOUT:3909]] }, section "llvm.ptrauth" // CHECK: [[PROTOTYPE_HOLDER_BORROWED_VALUE:@"\$s29ptrauth_generalized_accessors6HolderVIetMg_TC.ptrauth"]] = // CHECK-SAME: private constant { i8*, i32, i64, i64 } { i8* bitcast (void (i8*, i1)* @"$s29ptrauth_generalized_accessors6HolderVIetMg_TC" to i8*), i32 0, i64 1, i64 [[PTRAUTH_BORROWED_VALUE:51173]] }, section "llvm.ptrauth" // CHECK: [[PROTOTYPE_HOLDER_INOUT_VALUE_1:@"\$s29ptrauth_generalized_accessors6HolderVIetMl_TC.ptrauth.1"]] = // CHECK-SAME: private constant { i8*, i32, i64, i64 } { i8* bitcast (void (i8*, i1)* @"$s29ptrauth_generalized_accessors6HolderVIetMl_TC" to i8*), i32 0, i64 1, i64 [[PTRAUTH_INOUT]] }, section "llvm.ptrauth" // CHECK: [[PROTOTYPE_OPAQUEOWNER_INOUT_HOLDER:@"\$s29ptrauth_generalized_accessors11OpaqueOwnerVIetMl_TC.ptrauth"]] = // CHECK-SAME: private constant { i8*, i32, i64, i64 } { i8* bitcast (void (i8*, i1)* @"$s29ptrauth_generalized_accessors11OpaqueOwnerVIetMl_TC" to i8*), i32 0, i64 1, i64 [[PTRAUTH_INOUT]] }, section "llvm.ptrauth" // CHECK: [[PROTOTYPE_OPAQUEOWNER_OPAQUE_INOUT_HOLDER:@"\$s29ptrauth_generalized_accessors11OpaqueOwnerVIetWl_TC.ptrauth"]] = // CHECK-SAME: private constant { i8*, i32, i64, i64 } { i8* bitcast (void (i8*, i1)* @"$s29ptrauth_generalized_accessors11OpaqueOwnerVIetWl_TC" to i8*), i32 0, i64 1, i64 [[PTRAUTH_INOUT]] }, section "llvm.ptrauth" // CHECK: [[PROTOTYPE_OPAQUEOWNER_OPAQUE_BORROWED_HOLDER:@"\$s29ptrauth_generalized_accessors11OpaqueOwnerVIetWn_TC.ptrauth"]] = // CHECK-SAME: private constant { i8*, i32, i64, i64 } { i8* bitcast (void (i8*, i1)* @"$s29ptrauth_generalized_accessors11OpaqueOwnerVIetWn_TC" to i8*), i32 0, i64 1, i64 [[PTRAUTH_OPAQUE:56769]] }, section "llvm.ptrauth" // CHECK: [[PROTOTYPE_OPAQUEOWNER_BORROWED_HOLDER:@"\$s29ptrauth_generalized_accessors11OpaqueOwnerVIetMg_TC.ptrauth"]] = // CHECK-SAME: private constant { i8*, i32, i64, i64 } { i8* bitcast (void (i8*, i1)* @"$s29ptrauth_generalized_accessors11OpaqueOwnerVIetMg_TC" to i8*), i32 0, i64 1, i64 [[PTRAUTH_BORROWED_HOLDER:11564]] }, section "llvm.ptrauth" // CHECK: [[PROTOTYPE_OWNER_INOUT_HOLDER:@"\$s29ptrauth_generalized_accessors5OwnerVIetWl_TC.ptrauth"]] = // CHECK-SAME: private constant { i8*, i32, i64, i64 } { i8* bitcast (void (i8*, i1)* @"$s29ptrauth_generalized_accessors5OwnerVIetWl_TC" to i8*), i32 0, i64 1, i64 [[PTRAUTH_INOUT]] }, section "llvm.ptrauth" // CHECK: [[PROTOTYPE_OWNER_BORROWED_HOLDER:@"\$s29ptrauth_generalized_accessors5OwnerVIetWn_TC.ptrauth"]] = // CHECK-SAME: private constant { i8*, i32, i64, i64 } { i8* bitcast (void (i8*, i1)* @"$s29ptrauth_generalized_accessors5OwnerVIetWn_TC" to i8*), i32 0, i64 1, i64 [[PTRAUTH_BORROWED_HOLDER]] }, section "llvm.ptrauth" public class C {} public struct Value { public var c: C func use() {} mutating func mutate() {} } // Concrete accessor. // CHECK-LABEL: define {{.*}} @"$s29ptrauth_generalized_accessors6HolderV5valueAA5ValueVvr" // CHECK: call token @llvm.coro.id.retcon.once // CHECK-SAME: [[PROTOTYPE_HOLDER_BORROWED_VALUE]] // CHECK-LABEL: define {{.*}} @"$s29ptrauth_generalized_accessors6HolderV5valueAA5ValueVvM" // CHECK: call token @llvm.coro.id.retcon.once // CHECK-SAME: [[PROTOTYPE_HOLDER_INOUT_VALUE_1]] public struct Holder { public var _value: Value public var value: Value { _read { yield _value } _modify { yield &_value } } } public protocol Owning { @_borrowed var holder: Holder { get set } } public protocol OpaqueOwning { associatedtype Holding @_borrowed var holder: Holding { get set } } // Thunks for Owning, which uses concrete types. // CHECK-LABEL: define {{.*}} @"$s29ptrauth_generalized_accessors5OwnerVAA6OwningA2aDP6holderAA6HolderVvrTW" // CHECK: call token @llvm.coro.id.retcon.once // CHECK-SAME: [[PROTOTYPE_OWNER_BORROWED_HOLDER]] // CHECK-LABEL: define {{.*}} @"$s29ptrauth_generalized_accessors5OwnerVAA6OwningA2aDP6holderAA6HolderVvMTW" // CHECK: call token @llvm.coro.id.retcon.once // CHECK-SAME: [[PROTOTYPE_OWNER_INOUT_HOLDER]] public struct Owner: Owning { public var holder: Holder } // Concrete accessor. // CHECK-LABEL: define {{.*}} @"$s29ptrauth_generalized_accessors11OpaqueOwnerV6holderAA6HolderVvM" // CHECK: call token @llvm.coro.id.retcon.once // CHECK-SAME: [[PROTOTYPE_OPAQUEOWNER_INOUT_HOLDER]] // Thunks for OpaqueOwning, which uses abstract types. // CHECK-LABEL: define {{.*}} @"$s29ptrauth_generalized_accessors11OpaqueOwnerVAA0D6OwningA2aDP6holder7HoldingQzvrTW" // CHECK: call token @llvm.coro.id.retcon.once // CHECK-SAME: [[PROTOTYPE_OPAQUEOWNER_OPAQUE_BORROWED_HOLDER]] // Concrete accessor. // CHECK-LABEL: define {{.*}} @"$s29ptrauth_generalized_accessors11OpaqueOwnerV6holderAA6HolderVvr" // CHECK: call token @llvm.coro.id.retcon.once // CHECK-SAME: [[PROTOTYPE_OPAQUEOWNER_BORROWED_HOLDER]] public struct OpaqueOwner: OpaqueOwning { public var holder: Holder } // Thunks for OpaqueOwning, which uses abstract types. // CHECK-LABEL: define {{.*}} @"$s29ptrauth_generalized_accessors11OpaqueOwnerVAA0D6OwningA2aDP6holder7HoldingQzvMTW" // CHECK: call token @llvm.coro.id.retcon.once // CHECK-SAME: [[PROTOTYPE_OPAQUEOWNER_OPAQUE_INOUT_HOLDER]] // CHECK-LABEL: define {{.*}} @"$s29ptrauth_generalized_accessors17testInOutConcrete6holderyAA6HolderVz_tF" // CHECK: [[T0:%.*]] = alloca [32 x i8], align 8 // CHECK-NEXT: [[BUFFER:%.*]] = getelementptr inbounds [32 x i8], [32 x i8]* [[T0]], i32 0, i32 0 // CHECK: [[T0:%.*]] = call swiftcc { i8*, %T29ptrauth_generalized_accessors5ValueV* } {{.*}} [[BUFFER]] // CHECK: [[T1:%.*]] = extractvalue { i8*, %T29ptrauth_generalized_accessors5ValueV* } [[T0]], 0 // CHECK: call swiftcc void @"$s29ptrauth_generalized_accessors5ValueV6mutateyyF" // CHECK: [[RESUME:%.*]] = bitcast i8* [[T1]] to void (i8*, i1)* // CHECK-NEXT: [[T0:%.*]] = ptrtoint i8* [[BUFFER]] to i64 // CHECK-NEXT: [[DISCRIMINATOR:%.*]] = call i64 @llvm.ptrauth.blend.i64(i64 [[T0]], i64 [[PTRAUTH_INOUT]]) // CHECK-NEXT: call swiftcc void [[RESUME]](i8* noalias dereferenceable(32) [[BUFFER]], i1 false) [ "ptrauth"(i32 0, i64 [[DISCRIMINATOR]]) ] public func testInOutConcrete(holder: inout Holder) { holder.value.mutate() } // CHECK-LABEL: define {{.*}} @"$s29ptrauth_generalized_accessors20testBorrowedConcrete6holderyAA6HolderVz_tF" // CHECK: [[T0:%.*]] = alloca [32 x i8], align 8 // CHECK: [[BUFFER:%.*]] = getelementptr inbounds [32 x i8], [32 x i8]* [[T0]], i32 0, i32 0 // CHECK: [[T0:%.*]] = call swiftcc { i8*, %T29ptrauth_generalized_accessors1CC* } {{.*}} [[BUFFER]] // CHECK: [[T1:%.*]] = extractvalue { i8*, %T29ptrauth_generalized_accessors1CC* } [[T0]], 0 // CHECK: [[RESUME:%.*]] = bitcast i8* [[T1]] to void (i8*, i1)* // CHECK-NEXT: [[T0:%.*]] = ptrtoint i8* [[BUFFER]] to i64 // CHECK-NEXT: [[DISCRIMINATOR:%.*]] = call i64 @llvm.ptrauth.blend.i64(i64 [[T0]], i64 [[PTRAUTH_BORROWED_VALUE]]) // CHECK-NEXT: call swiftcc void [[RESUME]](i8* noalias dereferenceable(32) [[BUFFER]], i1 false) [ "ptrauth"(i32 0, i64 [[DISCRIMINATOR]]) ] public func testBorrowedConcrete(holder: inout Holder) { holder.value.use() } // CHECK-LABEL: define {{.*}} @"$s29ptrauth_generalized_accessors9testInOut5valueyxz_tAA6OwningRzlF" // CHECK: [[T0:%.*]] = alloca [32 x i8], align 8 // CHECK: [[BUFFER:%.*]] = getelementptr inbounds [32 x i8], [32 x i8]* [[T0]], i32 0, i32 0 // CHECK: [[T0:%.*]] = call swiftcc { i8*, %T29ptrauth_generalized_accessors6HolderV* } {{.*}} [[BUFFER]] // CHECK: [[T1:%.*]] = extractvalue { i8*, %T29ptrauth_generalized_accessors6HolderV* } [[T0]], 0 // CHECK: call swiftcc void @"$s29ptrauth_generalized_accessors5ValueV6mutateyyF" // CHECK: [[RESUME:%.*]] = bitcast i8* [[T1]] to void (i8*, i1)* // CHECK-NEXT: [[T0:%.*]] = ptrtoint i8* [[BUFFER]] to i64 // CHECK-NEXT: [[DISCRIMINATOR:%.*]] = call i64 @llvm.ptrauth.blend.i64(i64 [[T0]], i64 [[PTRAUTH_INOUT]]) // CHECK-NEXT: call swiftcc void [[RESUME]](i8* noalias dereferenceable(32) [[BUFFER]], i1 false) [ "ptrauth"(i32 0, i64 [[DISCRIMINATOR]]) ] public func testInOut(value: inout T) { value.holder.value.mutate() } // CHECK-LABEL: define {{.*}} @"$s29ptrauth_generalized_accessors12testBorrowed5valueyxz_tAA6OwningRzlF" // CHECK: [[T0:%.*]] = alloca [32 x i8], align 8 // CHECK: [[BUFFER:%.*]] = getelementptr inbounds [32 x i8], [32 x i8]* [[T0]], i32 0, i32 0 // CHECK: [[T0:%.*]] = call swiftcc { i8*, %T29ptrauth_generalized_accessors1CC* } {{.*}} [[BUFFER]] // CHECK: [[T1:%.*]] = extractvalue { i8*, %T29ptrauth_generalized_accessors1CC* } [[T0]], 0 // CHECK: [[RESUME:%.*]] = bitcast i8* [[T1]] to void (i8*, i1)* // CHECK-NEXT: [[T0:%.*]] = ptrtoint i8* [[BUFFER]] to i64 // CHECK-NEXT: [[DISCRIMINATOR:%.*]] = call i64 @llvm.ptrauth.blend.i64(i64 [[T0]], i64 [[PTRAUTH_BORROWED_HOLDER]]) // CHECK-NEXT: call swiftcc void [[RESUME]](i8* noalias dereferenceable(32) [[BUFFER]], i1 false) [ "ptrauth"(i32 0, i64 [[DISCRIMINATOR]]) ] public func testBorrowed(value: inout T) { value.holder.value.use() } // CHECK-LABEL: define {{.*}} @"$s29ptrauth_generalized_accessors15testOpaqueInOut5valueyxz_tAA0E6OwningRzAA6HolderV7HoldingRtzlF" // CHECK: [[T0:%.*]] = alloca [32 x i8], align 8 // CHECK: [[BUFFER:%.*]] = getelementptr inbounds [32 x i8], [32 x i8]* [[T0]], i32 0, i32 0 // CHECK: [[T0:%.*]] = call swiftcc { i8*, %swift.opaque* } {{.*}} [[BUFFER]] // CHECK: [[T1:%.*]] = extractvalue { i8*, %swift.opaque* } [[T0]], 0 // CHECK: call swiftcc void @"$s29ptrauth_generalized_accessors5ValueV6mutateyyF" // CHECK: [[RESUME:%.*]] = bitcast i8* [[T1]] to void (i8*, i1)* // CHECK-NEXT: [[T0:%.*]] = ptrtoint i8* [[BUFFER]] to i64 // CHECK-NEXT: [[DISCRIMINATOR:%.*]] = call i64 @llvm.ptrauth.blend.i64(i64 [[T0]], i64 [[PTRAUTH_INOUT]]) // CHECK-NEXT: call swiftcc void [[RESUME]](i8* noalias dereferenceable(32) [[BUFFER]], i1 false) [ "ptrauth"(i32 0, i64 [[DISCRIMINATOR]]) ] public func testOpaqueInOut(value: inout T) where T.Holding == Holder { value.holder.value.mutate() } // CHECK-LABEL: define {{.*}} @"$s29ptrauth_generalized_accessors18testOpaqueBorrowed5valueyxz_tAA0E6OwningRzAA6HolderV7HoldingRtzlF" // CHECK: [[T0:%.*]] = alloca [32 x i8], align 8 // CHECK: [[BUFFER:%.*]] = getelementptr inbounds [32 x i8], [32 x i8]* [[T0]], i32 0, i32 0 // CHECK: [[T0:%.*]] = call swiftcc { i8*, %swift.opaque* } {{.*}} [[BUFFER]] // CHECK: [[T1:%.*]] = extractvalue { i8*, %swift.opaque* } [[T0]], 0 // CHECK: [[RESUME:%.*]] = bitcast i8* [[T1]] to void (i8*, i1)* // CHECK-NEXT: [[T0:%.*]] = ptrtoint i8* [[BUFFER]] to i64 // CHECK-NEXT: [[DISCRIMINATOR:%.*]] = call i64 @llvm.ptrauth.blend.i64(i64 [[T0]], i64 [[PTRAUTH_OPAQUE]]) // CHECK-NEXT: call swiftcc void [[RESUME]](i8* noalias dereferenceable(32) [[BUFFER]], i1 false) [ "ptrauth"(i32 0, i64 [[DISCRIMINATOR]]) ] public func testOpaqueBorrowed(value: inout T) where T.Holding == Holder { value.holder.value.use() }