[Runtime][IRGen] Sign type context descriptor pointers.

Ensure that context descriptor pointers are signed in the runtime by putting the ptrauth_struct attribute on the types.

We use the new __builtin_ptrauth_struct_key/disc to conditionally apply ptrauth_struct to TrailingObjects based on the signing of the base type, so that pointers to TrailingObjects get signed when used with a context descriptor pointer.

We add new runtime entrypoints that take signed pointers where appropriate, and have the compiler emit calls to the new entrypoints when targeting a sufficiently new OS.

rdar://111480914
This commit is contained in:
Mike Ash
2023-06-30 11:58:17 -04:00
parent 6f8fd07bdf
commit fe7e13bba5
29 changed files with 519 additions and 75 deletions

View File

@@ -56,12 +56,24 @@ template <typename Runtime> struct TargetOpaqueMetadata;
template <typename Runtime> struct TargetValueMetadata;
template <typename Runtime> struct TargetForeignClassMetadata;
template <typename Runtime> struct TargetForeignReferenceTypeMetadata;
template <typename Runtime> struct TargetContextDescriptor;
template <typename Runtime> class TargetTypeContextDescriptor;
template <typename Runtime> class TargetClassDescriptor;
template <typename Runtime> class TargetValueTypeDescriptor;
template <typename Runtime> class TargetEnumDescriptor;
template <typename Runtime> class TargetStructDescriptor;
template <typename Runtime>
struct swift_ptrauth_struct_context_descriptor(ContextDescriptor)
TargetContextDescriptor;
template <typename Runtime>
class swift_ptrauth_struct_context_descriptor(TypeContextDescriptor)
TargetTypeContextDescriptor;
template <typename Runtime>
class swift_ptrauth_struct_context_descriptor(ClassDescriptor)
TargetClassDescriptor;
template <typename Runtime>
class swift_ptrauth_struct_context_descriptor(ValueTypeDescriptor)
TargetValueTypeDescriptor;
template <typename Runtime>
class swift_ptrauth_struct_context_descriptor(EnumDescriptor)
TargetEnumDescriptor;
template <typename Runtime>
class swift_ptrauth_struct_context_descriptor(StructDescriptor)
TargetStructDescriptor;
template <typename Runtime> struct TargetGenericMetadataPattern;
template <typename Runtime> struct TargetProtocolConformanceDescriptor;
@@ -1632,7 +1644,9 @@ TargetTupleTypeMetadata<Runtime>::getOffsetToNumElements() -> StoredSize {
return offsetof(TargetTupleTypeMetadata<Runtime>, NumElements);
}
template <typename Runtime> struct TargetProtocolDescriptor;
template <typename Runtime>
struct swift_ptrauth_struct_context_descriptor(ProtocolDescriptor)
TargetProtocolDescriptor;
/// A protocol requirement descriptor. This describes a single protocol
/// requirement in a protocol descriptor. The index of the requirement in
@@ -1660,7 +1674,9 @@ struct TargetProtocolRequirement {
using ProtocolRequirement = TargetProtocolRequirement<InProcess>;
template<typename Runtime> struct TargetProtocolDescriptor;
template <typename Runtime>
struct swift_ptrauth_struct_context_descriptor(ProtocolDescriptor)
TargetProtocolDescriptor;
using ProtocolDescriptor = TargetProtocolDescriptor<InProcess>;
template<template <typename Runtime> class ObjCInteropKind, unsigned PointerSize>
@@ -2803,12 +2819,14 @@ using ExternalProtocolConformanceDescriptor = TargetProtocolConformanceDescripto
template<template <typename Runtime> class ObjCInteropKind, unsigned PointerSize>
using ExternalProtocolConformanceRecord = TargetProtocolConformanceRecord<External<ObjCInteropKind<RuntimeTarget<PointerSize>>>>;
template<typename Runtime>
struct TargetModuleContextDescriptor;
template <typename Runtime>
struct swift_ptrauth_struct_context_descriptor(ModuleContextDescriptor)
TargetModuleContextDescriptor;
/// Base class for all context descriptors.
template<typename Runtime>
struct TargetContextDescriptor {
template <typename Runtime>
struct swift_ptrauth_struct_context_descriptor(ContextDescriptor)
TargetContextDescriptor {
/// Flags describing the context, including its kind and format version.
ContextDescriptorFlags Flags;
@@ -2864,8 +2882,9 @@ inline bool isCImportedModuleName(llvm::StringRef name) {
}
/// Descriptor for a module context.
template<typename Runtime>
struct TargetModuleContextDescriptor final : TargetContextDescriptor<Runtime> {
template <typename Runtime>
struct swift_ptrauth_struct_context_descriptor(ModuleContextDescriptor)
TargetModuleContextDescriptor final : TargetContextDescriptor<Runtime> {
/// The module name.
RelativeDirectPointer<const char, /*nullable*/ false> Name;
@@ -2905,8 +2924,9 @@ TargetContextDescriptor<Runtime>::getModuleContext() const {
}
/// Descriptor for an extension context.
template<typename Runtime>
struct TargetExtensionContextDescriptor final
template <typename Runtime>
struct swift_ptrauth_struct_context_descriptor(ExtensionContextDescriptor)
TargetExtensionContextDescriptor final
: TargetContextDescriptor<Runtime>,
TrailingGenericContextObjects<TargetExtensionContextDescriptor<Runtime>>
{
@@ -2944,8 +2964,9 @@ struct TargetMangledContextName {
TargetRelativeDirectPointer<Runtime, const char, /*nullable*/ false> name;
};
template<typename Runtime>
struct TargetAnonymousContextDescriptor final
template <typename Runtime>
struct swift_ptrauth_struct_context_descriptor(AnonymousContextDescriptor)
TargetAnonymousContextDescriptor final
: TargetContextDescriptor<Runtime>,
TrailingGenericContextObjects<TargetAnonymousContextDescriptor<Runtime>,
TargetGenericContextDescriptorHeader,
@@ -3025,8 +3046,9 @@ using ExternalAnonymousContextDescriptor = TargetAnonymousContextDescriptor<Exte
/// Only Swift protocols are defined by a protocol descriptor, whereas
/// Objective-C (including protocols defined in Swift as @objc) use the
/// Objective-C protocol layout.
template<typename Runtime>
struct TargetProtocolDescriptor final
template <typename Runtime>
struct swift_ptrauth_struct_context_descriptor(ProtocolDescriptor)
TargetProtocolDescriptor final
: TargetContextDescriptor<Runtime>,
swift::ABI::TrailingObjects<
TargetProtocolDescriptor<Runtime>,
@@ -3114,11 +3136,12 @@ public:
return cd->getKind() == ContextDescriptorKind::Protocol;
}
};
/// The descriptor for an opaque type.
template <typename Runtime>
struct TargetOpaqueTypeDescriptor final
: TargetContextDescriptor<Runtime>,
struct swift_ptrauth_struct_context_descriptor(OpaqueTypeDescriptor)
TargetOpaqueTypeDescriptor final
: TargetContextDescriptor<Runtime>,
TrailingGenericContextObjects<TargetOpaqueTypeDescriptor<Runtime>,
TargetGenericContextDescriptorHeader,
RelativeDirectPointer<const char>>
@@ -3694,8 +3717,8 @@ struct TargetCanonicalSpecializedMetadatasCachingOnceToken {
};
template <typename Runtime>
class TargetTypeContextDescriptor
: public TargetContextDescriptor<Runtime> {
class swift_ptrauth_struct_context_descriptor(TypeContextDescriptor)
TargetTypeContextDescriptor : public TargetContextDescriptor<Runtime> {
public:
/// The name of the type.
TargetRelativeDirectPointer<Runtime, const char, /*nullable*/ false> Name;
@@ -3917,7 +3940,8 @@ struct TargetObjCResilientClassStubInfo {
};
template <typename Runtime>
class TargetClassDescriptor final
class swift_ptrauth_struct_context_descriptor(ClassDescriptor)
TargetClassDescriptor final
: public TargetTypeContextDescriptor<Runtime>,
public TrailingGenericContextObjects<TargetClassDescriptor<Runtime>,
TargetTypeGenericContextDescriptorHeader,
@@ -4307,8 +4331,8 @@ public:
using ClassDescriptor = TargetClassDescriptor<InProcess>;
template <typename Runtime>
class TargetValueTypeDescriptor
: public TargetTypeContextDescriptor<Runtime> {
class swift_ptrauth_struct_context_descriptor(ValueTypeDescriptor)
TargetValueTypeDescriptor : public TargetTypeContextDescriptor<Runtime>{
public:
static bool classof(const TargetContextDescriptor<Runtime> *cd) {
return cd->getKind() == ContextDescriptorKind::Struct ||
@@ -4318,7 +4342,8 @@ public:
using ValueTypeDescriptor = TargetValueTypeDescriptor<InProcess>;
template <typename Runtime>
class TargetStructDescriptor final
class swift_ptrauth_struct_context_descriptor(StructDescriptor)
TargetStructDescriptor final
: public TargetValueTypeDescriptor<Runtime>,
public TrailingGenericContextObjects<TargetStructDescriptor<Runtime>,
TargetTypeGenericContextDescriptorHeader,
@@ -4445,7 +4470,8 @@ public:
using StructDescriptor = TargetStructDescriptor<InProcess>;
template <typename Runtime>
class TargetEnumDescriptor final
class swift_ptrauth_struct_context_descriptor(EnumDescriptor)
TargetEnumDescriptor final
: public TargetValueTypeDescriptor<Runtime>,
public TrailingGenericContextObjects<TargetEnumDescriptor<Runtime>,
TargetTypeGenericContextDescriptorHeader,

View File

@@ -34,9 +34,11 @@ struct TargetAnyClassMetadataObjCInterop;
template <typename Runtime, typename TargetAnyClassMetadataVariant>
struct TargetClassMetadata;
template <typename Runtime>
struct TargetContextDescriptor;
struct swift_ptrauth_struct_context_descriptor(ContextDescriptor)
TargetContextDescriptor;
template <typename Runtime>
struct TargetProtocolDescriptor;
struct swift_ptrauth_struct_context_descriptor(ProtocolDescriptor)
TargetProtocolDescriptor;
namespace detail {
template <typename Runtime, bool ObjCInterop = Runtime::ObjCInterop>

View File

@@ -1391,6 +1391,12 @@ namespace SpecialPointerAuthDiscriminators {
/// Protocol conformance descriptors.
const uint16_t ProtocolConformanceDescriptor = 0xc6eb;
const uint16_t ProtocolDescriptor = 0xe909; // = 59657
// Type descriptors as arguments.
const uint16_t OpaqueTypeDescriptor = 0xbdd1; // = 48593
const uint16_t ContextDescriptor = 0xb5e3; // = 46563
/// Pointer to value witness table stored in type metadata.
///
/// Computed with ptrauth_string_discriminator("value_witness_table_t").

View File

@@ -234,7 +234,8 @@ protected:
/// See the file comment for details on the usage of the
/// TrailingObjects type.
template <typename BaseTy, typename... TrailingTys>
class TrailingObjects : private trailing_objects_internal::TrailingObjectsImpl<
class swift_ptrauth_struct_derived(BaseTy) TrailingObjects
: private trailing_objects_internal::TrailingObjectsImpl<
trailing_objects_internal::AlignmentCalcHelper<
TrailingTys...>::Alignment,
BaseTy, TrailingObjects<BaseTy, TrailingTys...>,

View File

@@ -19,11 +19,14 @@
#define SWIFT_ABI_TYPEIDENTITY_H
#include "swift/Basic/LLVM.h"
#include "swift/Runtime/Config.h"
#include <llvm/ADT/Optional.h>
#include <llvm/ADT/StringRef.h>
namespace swift {
template <class> class TargetTypeContextDescriptor;
template <typename Runtime>
class swift_ptrauth_struct_context_descriptor(TypeContextDescriptor)
TargetTypeContextDescriptor;
struct InProcess;
using TypeContextDescriptor = TargetTypeContextDescriptor<InProcess>;

View File

@@ -929,6 +929,14 @@ public:
/// variadic generic types.
AvailabilityContext getVariadicGenericTypeAvailability();
/// Get the runtime availability of the conformsToProtocol runtime entrypoint
/// that takes a signed protocol descriptor pointer.
AvailabilityContext getSignedConformsToProtocolAvailability();
/// Get the runtime availability of runtime entrypoints that take signed type
/// descriptors.
AvailabilityContext getSignedDescriptorAvailability();
/// Get the runtime availability of features introduced in the Swift 5.2
/// compiler for the target platform.
AvailabilityContext getSwift52Availability();

View File

@@ -147,6 +147,15 @@ struct PointerAuthOptions : clang::PointerAuthOptions {
/// Protocol conformance descriptors when passed as arguments.
PointerAuthSchema ProtocolConformanceDescriptorsAsArguments;
/// Protocol descriptors when passed as arguments.
PointerAuthSchema ProtocolDescriptorsAsArguments;
/// Opaque type descriptors when passed as arguments.
PointerAuthSchema OpaqueTypeDescriptorsAsArguments;
/// Type context descriptors when passed as arguments.
PointerAuthSchema ContextDescriptorsAsArguments;
/// Resumption functions from yield-once coroutines.
PointerAuthSchema YieldOnceResumeFunctions;

View File

@@ -239,11 +239,26 @@ const Metadata *swift_getObjectType(HeapObject *object);
/// \param type The metadata for the type for which to do the conformance
/// check.
/// \param protocol The protocol descriptor for the protocol to check
/// conformance for.
/// conformance for. This pointer does not have ptrauth applied.
SWIFT_RUNTIME_EXPORT
const WitnessTable *swift_conformsToProtocol(const Metadata *type,
const ProtocolDescriptor *protocol);
const void *protocol);
/// Check whether a type conforms to a given native Swift protocol. Identical to
/// swift_conformsToProtocol, except that the protocol parameter has a ptrauth
/// signature on ARM64e that is signed with a process independent key.
SWIFT_RUNTIME_EXPORT
const WitnessTable *
swift_conformsToProtocol2(const Metadata *type,
const ProtocolDescriptor *protocol);
/// Check whether a type conforms to a given native Swift protocol. Identical to
/// swift_conformsToProtocol, except that the protocol parameter has a ptrauth
/// signature on ARM64e that is signed with a process dependent key.
SWIFT_RUNTIME_EXPORT
const WitnessTable *
swift_conformsToProtocolCommon(const Metadata *type,
const ProtocolDescriptor *protocol);
} // end namespace swift
#endif // SWIFT_RUNTIME_CASTING_H

View File

@@ -199,7 +199,7 @@ extern uintptr_t __COMPATIBILITY_LIBRARIES_CANNOT_CHECK_THE_IS_SWIFT_BIT_DIRECTL
// SWIFT_CC(swift) is the Swift calling convention.
// FIXME: the next comment is false.
// Functions outside the stdlib or runtime that include this file may be built
// Functions outside the stdlib or runtime that include this file may be built
// with a compiler that doesn't support swiftcall; don't define these macros
// in that case so any incorrect usage is caught.
#if __has_attribute(swiftcall)
@@ -326,6 +326,18 @@ extern uintptr_t __COMPATIBILITY_LIBRARIES_CANNOT_CHECK_THE_IS_SWIFT_BIT_DIRECTL
#define __ptrauth_swift_type_layout_string \
__ptrauth(ptrauth_key_process_independent_data, 1, \
SpecialPointerAuthDiscriminators::TypeLayoutString)
#if __has_attribute(ptrauth_struct)
#define swift_ptrauth_struct(key, discriminator) \
__attribute__((ptrauth_struct(key, discriminator)))
#else
#define swift_ptrauth_struct(key, discriminator)
#endif
// Set ptrauth_struct to the same scheme as the ptrauth_struct on `from`, but
// with a modified discriminator.
#define swift_ptrauth_struct_derived(from) \
swift_ptrauth_struct(__builtin_ptrauth_struct_key(from), \
__builtin_ptrauth_struct_disc(from) + 1)
#else
#define SWIFT_PTRAUTH 0
#define __ptrauth_swift_function_pointer(__typekey)
@@ -354,11 +366,18 @@ extern uintptr_t __COMPATIBILITY_LIBRARIES_CANNOT_CHECK_THE_IS_SWIFT_BIT_DIRECTL
#define swift_ptrauth_sign_opaque_read_resume_function(__fn, __buffer) (__fn)
#define swift_ptrauth_sign_opaque_modify_resume_function(__fn, __buffer) (__fn)
#define __ptrauth_swift_type_layout_string
#define swift_ptrauth_struct(key, discriminator)
#define swift_ptrauth_struct_derived(from)
#endif
#ifdef __cplusplus
/// Copy an address-discriminated signed pointer from the source to the dest.
#define swift_ptrauth_struct_context_descriptor(name) \
swift_ptrauth_struct(ptrauth_key_process_dependent_data, \
ptrauth_string_discriminator(#name))
/// Copy an address-discriminated signed code pointer from the source
/// to the destination.
template <class T>
SWIFT_RUNTIME_ATTRIBUTE_ALWAYS_INLINE static inline void
swift_ptrauth_copy(T *dest, const T *src, unsigned extra, bool allowNull) {
@@ -462,9 +481,53 @@ template <typename T>
SWIFT_RUNTIME_ATTRIBUTE_ALWAYS_INLINE
static inline T swift_auth_data_non_address(T value, unsigned extra) {
#if SWIFT_PTRAUTH
return (T)ptrauth_auth_data((void *)value,
ptrauth_key_process_independent_data,
extra);
// Cast to void* using a union to avoid implicit ptrauth operations when T
// points to a type with the ptrauth_struct attribute.
union {
T value;
void *voidValue;
} converter;
converter.value = value;
if (converter.voidValue == nullptr)
return nullptr;
return (T)ptrauth_auth_data(converter.voidValue,
ptrauth_key_process_independent_data, extra);
#else
return value;
#endif
}
template <typename T>
SWIFT_RUNTIME_ATTRIBUTE_ALWAYS_INLINE
static inline T swift_sign_data_non_address(T value, unsigned extra) {
#if SWIFT_PTRAUTH
// Cast from void* using a union to avoid implicit ptrauth operations when T
// points to a type with the ptrauth_struct attribute.
union {
T value;
void *voidValue;
} converter;
converter.voidValue = ptrauth_sign_unauthenticated(
(void *)value, ptrauth_key_process_independent_data, extra);
return converter.value;
#else
return value;
#endif
}
template <typename T>
SWIFT_RUNTIME_ATTRIBUTE_ALWAYS_INLINE
static inline T swift_strip_data(T value) {
#if SWIFT_PTRAUTH
// Cast to void* using a union to avoid implicit ptrauth operations when T
// points to a type with the ptrauth_struct attribute.
union {
T value;
void *voidValue;
} converter;
converter.value = value;
return (T)ptrauth_strip(converter.voidValue, ptrauth_key_process_independent_data);
#else
return value;
#endif

View File

@@ -847,7 +847,7 @@ FUNCTION(GetCanonicalPrespecializedGenericMetadata,
// MetadataResponse swift_getOpaqueTypeMetadata(MetadataRequest request,
// const void * const *arguments,
// const OpaqueTypeDescriptor *descriptor,
// const void *descriptor,
// uintptr_t index);
FUNCTION(GetOpaqueTypeMetadata, swift_getOpaqueTypeMetadata,
SwiftCC, OpaqueTypeAvailability,
@@ -856,6 +856,17 @@ FUNCTION(GetOpaqueTypeMetadata, swift_getOpaqueTypeMetadata,
ATTRS(NoUnwind, ReadOnly),
EFFECT(MetaData))
// MetadataResponse swift_getOpaqueTypeMetadata2(MetadataRequest request,
// const void * const *arguments,
// const OpaqueTypeDescriptor *descriptor,
// uintptr_t index);
FUNCTION(GetOpaqueTypeMetadata2, swift_getOpaqueTypeMetadata2,
SwiftCC, SignedDescriptorAvailability,
RETURNS(TypeMetadataResponseTy),
ARGS(SizeTy, Int8PtrTy, OpaqueTypeDescriptorPtrTy, SizeTy),
ATTRS(NoUnwind, ReadOnly),
EFFECT(MetaData))
// const WitnessTable *swift_getOpaqueTypeConformance(const void * const *arguments,
// const OpaqueTypeDescriptor *descriptor,
// uintptr_t index);
@@ -866,6 +877,16 @@ FUNCTION(GetOpaqueTypeConformance, swift_getOpaqueTypeConformance,
ATTRS(NoUnwind, ReadOnly, WillReturn),
EFFECT(MetaData))
// const WitnessTable *swift_getOpaqueTypeConformance2(const void * const *arguments,
// const OpaqueTypeDescriptor *descriptor,
// uintptr_t index);
FUNCTION(GetOpaqueTypeConformance2, swift_getOpaqueTypeConformance2,
SwiftCC, SignedDescriptorAvailability,
RETURNS(WitnessTablePtrTy),
ARGS(Int8PtrTy, OpaqueTypeDescriptorPtrTy, SizeTy),
ATTRS(NoUnwind, ReadOnly, WillReturn),
EFFECT(MetaData))
// Metadata *swift_allocateGenericClassMetadata(ClassDescriptor *type,
// const void * const *arguments,
// const void *template);
@@ -1617,6 +1638,14 @@ FUNCTION(ConformsToProtocol,
ATTRS(NoUnwind, ReadNone),
EFFECT(Casting))
// witness_table* swift_conformsToProtocol2(type*, protocol*);
FUNCTION(ConformsToProtocol2,
swift_conformsToProtocol2, C_CC, SignedConformsToProtocolAvailability,
RETURNS(WitnessTablePtrTy),
ARGS(TypeMetadataPtrTy, ProtocolDescriptorPtrTy),
ATTRS(NoUnwind, ReadNone),
EFFECT(Casting))
// bool swift_isClassType(type*);
FUNCTION(IsClassType,
swift_isClassType, C_CC, AlwaysAvailable,
@@ -1909,7 +1938,7 @@ FUNCTION(IntToFloat64, swift_intToFloat64, SwiftCC, AlwaysAvailable,
// const Metadata *swift_getTypeByMangledNameInContext(
// const char *typeNameStart,
// size_t typeNameLength,
// const TargetContextDescriptor<InProcess> *context,
// const void *context,
// const void * const *genericArgs)
FUNCTION(GetTypeByMangledNameInContext, swift_getTypeByMangledNameInContext,
SwiftCC, AlwaysAvailable,
@@ -1918,11 +1947,23 @@ FUNCTION(GetTypeByMangledNameInContext, swift_getTypeByMangledNameInContext,
ATTRS(NoUnwind, ArgMemOnly),
EFFECT(MetaData))
// const Metadata *swift_getTypeByMangledNameInContext2(
// const char *typeNameStart,
// size_t typeNameLength,
// const TargetContextDescriptor<InProcess> *context,
// const void * const *genericArgs)
FUNCTION(GetTypeByMangledNameInContext2, swift_getTypeByMangledNameInContext2,
SwiftCC, SignedDescriptorAvailability,
RETURNS(TypeMetadataPtrTy),
ARGS(Int8PtrTy, SizeTy, TypeContextDescriptorPtrTy, Int8PtrPtrTy),
ATTRS(NoUnwind, ArgMemOnly),
EFFECT(MetaData))
// const Metadata *swift_getTypeByMangledNameInContextInMetadataState(
// size_t metadataState,
// const char *typeNameStart,
// size_t typeNameLength,
// const TargetContextDescriptor<InProcess> *context,
// const void *context,
// const void * const *genericArgs)
FUNCTION(GetTypeByMangledNameInContextInMetadataState,
swift_getTypeByMangledNameInContextInMetadataState, SwiftCC,
@@ -1933,6 +1974,21 @@ FUNCTION(GetTypeByMangledNameInContextInMetadataState,
ATTRS(NoUnwind, ArgMemOnly),
EFFECT(MetaData))
// const Metadata *swift_getTypeByMangledNameInContextInMetadataState2(
// size_t metadataState,
// const char *typeNameStart,
// size_t typeNameLength,
// const TargetContextDescriptor<InProcess> *context,
// const void * const *genericArgs)
FUNCTION(GetTypeByMangledNameInContextInMetadataState2,
swift_getTypeByMangledNameInContextInMetadataState2, SwiftCC,
SignedDescriptorAvailability,
RETURNS(TypeMetadataPtrTy),
ARGS(SizeTy, Int8PtrTy, SizeTy, TypeContextDescriptorPtrTy,
Int8PtrPtrTy),
ATTRS(NoUnwind, ArgMemOnly),
EFFECT(MetaData))
// AsyncTask *swift_task_getCurrent();s
FUNCTION(GetCurrentTask,
swift_task_getCurrent, SwiftCC,

View File

@@ -530,6 +530,16 @@ ASTContext::getVariadicGenericTypeAvailability() {
return getSwift59Availability();
}
AvailabilityContext
ASTContext::getSignedConformsToProtocolAvailability() {
return getSwift59Availability();
}
AvailabilityContext
ASTContext::getSignedDescriptorAvailability() {
return getSwift59Availability();
}
AvailabilityContext ASTContext::getSwift52Availability() {
auto target = LangOpts.Target;

View File

@@ -39,6 +39,7 @@
#include "GenHeap.h"
#include "GenMeta.h"
#include "GenOpaque.h"
#include "GenPointerAuth.h"
#include "GenPoly.h"
#include "GenProto.h"
#include "GenType.h"
@@ -460,7 +461,13 @@ getAddressOfOpaqueTypeDescriptor(IRGenFunction &IGF,
MetadataResponse irgen::emitOpaqueTypeMetadataRef(IRGenFunction &IGF,
CanOpaqueTypeArchetypeType archetype,
DynamicMetadataRequest request) {
auto accessorFn = IGF.IGM.getGetOpaqueTypeMetadataFunctionPointer();
bool signedDescriptor = IGF.IGM.getAvailabilityContext().isContainedIn(
IGF.IGM.Context.getSignedDescriptorAvailability());
auto accessorFn = signedDescriptor ?
IGF.IGM.getGetOpaqueTypeMetadata2FunctionPointer() :
IGF.IGM.getGetOpaqueTypeMetadataFunctionPointer();
auto opaqueDecl = archetype->getDecl();
auto genericParam = archetype->getInterfaceType()
->castTo<GenericTypeParamType>();
@@ -468,6 +475,16 @@ MetadataResponse irgen::emitOpaqueTypeMetadataRef(IRGenFunction &IGF,
auto indexValue = llvm::ConstantInt::get(
IGF.IGM.SizeTy, genericParam->getIndex());
// Sign the descriptor.
auto schema =
IGF.IGM.getOptions().PointerAuth.OpaqueTypeDescriptorsAsArguments;
if (schema && signedDescriptor) {
auto authInfo = PointerAuthInfo::emit(
IGF, schema, nullptr,
PointerAuthEntity::Special::OpaqueTypeDescriptorAsArgument);
descriptor = emitPointerAuthSign(IGF, descriptor, authInfo);
}
llvm::CallInst *result = nullptr;
withOpaqueTypeGenericArgs(IGF, archetype,
[&](llvm::Value *genericArgs) {
@@ -487,12 +504,27 @@ MetadataResponse irgen::emitOpaqueTypeMetadataRef(IRGenFunction &IGF,
llvm::Value *irgen::emitOpaqueTypeWitnessTableRef(IRGenFunction &IGF,
CanOpaqueTypeArchetypeType archetype,
ProtocolDecl *protocol) {
auto accessorFn = IGF.IGM.getGetOpaqueTypeConformanceFunctionPointer();
bool signedDescriptor = IGF.IGM.getAvailabilityContext().isContainedIn(
IGF.IGM.Context.getSignedDescriptorAvailability());
auto accessorFn = signedDescriptor ?
IGF.IGM.getGetOpaqueTypeConformance2FunctionPointer() :
IGF.IGM.getGetOpaqueTypeConformanceFunctionPointer();
auto opaqueDecl = archetype->getDecl();
assert(archetype->isRoot() && "Can only follow from the root");
llvm::Value *descriptor = getAddressOfOpaqueTypeDescriptor(IGF, opaqueDecl);
// Sign the descriptor.
auto schema =
IGF.IGM.getOptions().PointerAuth.OpaqueTypeDescriptorsAsArguments;
if (schema && signedDescriptor) {
auto authInfo = PointerAuthInfo::emit(
IGF, schema, nullptr,
PointerAuthEntity::Special::OpaqueTypeDescriptorAsArgument);
descriptor = emitPointerAuthSign(IGF, descriptor, authInfo);
}
// Compute the index at which this witness table resides.
unsigned index = opaqueDecl->getOpaqueGenericParams().size();
auto opaqueReqs =

View File

@@ -355,6 +355,12 @@ PointerAuthEntity::getDeclDiscriminator(IRGenModule &IGM) const {
case Special::ProtocolConformanceDescriptor:
case Special::ProtocolConformanceDescriptorAsArgument:
return SpecialPointerAuthDiscriminators::ProtocolConformanceDescriptor;
case Special::ProtocolDescriptorAsArgument:
return SpecialPointerAuthDiscriminators::ProtocolDescriptor;
case Special::OpaqueTypeDescriptorAsArgument:
return SpecialPointerAuthDiscriminators::OpaqueTypeDescriptor;
case Special::ContextDescriptorAsArgument:
return SpecialPointerAuthDiscriminators::ContextDescriptor;
case Special::PartialApplyCapture:
return PointerAuthDiscriminator_PartialApplyCapture;
case Special::KeyPathDestroy:

View File

@@ -64,6 +64,9 @@ public:
DynamicReplacementKey,
ProtocolConformanceDescriptor,
ProtocolConformanceDescriptorAsArgument,
ProtocolDescriptorAsArgument,
OpaqueTypeDescriptorAsArgument,
ContextDescriptorAsArgument,
TypeLayoutString,
};

View File

@@ -739,6 +739,21 @@ static void setPointerAuthOptions(PointerAuthOptions &opts,
opts.ProtocolConformanceDescriptorsAsArguments =
PointerAuthSchema(dataKey, /*address*/ false, Discrimination::Decl);
opts.ProtocolDescriptorsAsArguments =
PointerAuthSchema(dataKey, /*address*/ false, Discrimination::Decl);
opts.OpaqueTypeDescriptorsAsArguments =
PointerAuthSchema(dataKey, /*address*/ false, Discrimination::Decl);
opts.ContextDescriptorsAsArguments =
PointerAuthSchema(dataKey, /*address*/ false, Discrimination::Decl);
opts.OpaqueTypeDescriptorsAsArguments =
PointerAuthSchema(dataKey, /*address*/ false, Discrimination::Decl);
opts.ContextDescriptorsAsArguments =
PointerAuthSchema(dataKey, /*address*/ false, Discrimination::Decl);
// Coroutine resumption functions are never stored globally in the ABI,
// so we can do some things that aren't normally okay to do. However,
// we can't use ASIB because that would break ARM64 interoperation.

View File

@@ -888,6 +888,24 @@ namespace RuntimeConstants {
return RuntimeAvailability::AlwaysAvailable;
}
RuntimeAvailability SignedConformsToProtocolAvailability(ASTContext &context) {
auto featureAvailability =
context.getSignedConformsToProtocolAvailability();
if (!isDeploymentAvailabilityContainedIn(context, featureAvailability)) {
return RuntimeAvailability::ConditionallyAvailable;
}
return RuntimeAvailability::AlwaysAvailable;
}
RuntimeAvailability SignedDescriptorAvailability(ASTContext &context) {
auto featureAvailability =
context.getSignedDescriptorAvailability();
if (!isDeploymentAvailabilityContainedIn(context, featureAvailability)) {
return RuntimeAvailability::ConditionallyAvailable;
}
return RuntimeAvailability::AlwaysAvailable;
}
RuntimeAvailability TaskRunInlineAvailability(ASTContext &context) {
if (context.LangOpts.isConcurrencyModelTaskToThread()) {
return RuntimeAvailability::AlwaysAvailable;

View File

@@ -3090,8 +3090,19 @@ emitMetadataAccessByMangledName(IRGenFunction &IGF, CanType type,
stringAddr = subIGF.Builder.CreateIntToPtr(stringAddr, IGM.Int8PtrTy);
llvm::CallInst *call;
bool signedDescriptor = IGM.getAvailabilityContext().isContainedIn(
IGM.Context.getSignedDescriptorAvailability());
if (request.isStaticallyAbstract()) {
call = subIGF.Builder.CreateCall(
call = signedDescriptor ?
subIGF.Builder.CreateCall(
IGM.getGetTypeByMangledNameInContextInMetadataState2FunctionPointer(),
{llvm::ConstantInt::get(IGM.SizeTy, (size_t)MetadataState::Abstract),
stringAddr, size,
// TODO: Use mangled name lookup in generic
// contexts?
llvm::ConstantPointerNull::get(IGM.TypeContextDescriptorPtrTy),
llvm::ConstantPointerNull::get(IGM.Int8PtrPtrTy)}):
subIGF.Builder.CreateCall(
IGM.getGetTypeByMangledNameInContextInMetadataStateFunctionPointer(),
{llvm::ConstantInt::get(IGM.SizeTy, (size_t)MetadataState::Abstract),
stringAddr, size,
@@ -3100,7 +3111,15 @@ emitMetadataAccessByMangledName(IRGenFunction &IGF, CanType type,
llvm::ConstantPointerNull::get(IGM.TypeContextDescriptorPtrTy),
llvm::ConstantPointerNull::get(IGM.Int8PtrPtrTy)});
} else {
call = subIGF.Builder.CreateCall(
call = signedDescriptor ?
subIGF.Builder.CreateCall(
IGM.getGetTypeByMangledNameInContext2FunctionPointer(),
{stringAddr, size,
// TODO: Use mangled name lookup in generic
// contexts?
llvm::ConstantPointerNull::get(IGM.TypeContextDescriptorPtrTy),
llvm::ConstantPointerNull::get(IGM.Int8PtrPtrTy)}) :
subIGF.Builder.CreateCall(
IGM.getGetTypeByMangledNameInContextFunctionPointer(),
{stringAddr, size,
// TODO: Use mangled name lookup in generic

View File

@@ -167,6 +167,16 @@ OVERRIDE_FOREIGN(dynamicCastForeignClassMetatypeUnconditional,
OVERRIDE_PROTOCOLCONFORMANCE(conformsToProtocol, const WitnessTable *, , , swift::,
(const Metadata * const type,
const void *protocol),
(type, protocol))
OVERRIDE_PROTOCOLCONFORMANCE(conformsToProtocol2, const WitnessTable *, , , swift::,
(const Metadata * const type,
const ProtocolDescriptor *protocol),
(type, protocol))
OVERRIDE_PROTOCOLCONFORMANCE(conformsToProtocolCommon, const WitnessTable *, , , swift::,
(const Metadata * const type,
const ProtocolDescriptor *protocol),
(type, protocol))

View File

@@ -91,7 +91,7 @@ findHashableBaseTypeImpl(const Metadata *type) {
}
auto witnessTable =
swift_conformsToProtocol(type, &HashableProtocolDescriptor);
swift_conformsToProtocolCommon(type, &HashableProtocolDescriptor);
if (!KnownToConformToHashable && !witnessTable) {
// Don't cache the negative response because we don't invalidate
// this cache when a new conformance is loaded dynamically.
@@ -175,7 +175,7 @@ void _swift_makeAnyHashableUpcastingToHashableBaseType(
getValueFromSwiftValue(srcSwiftValue);
if (auto unboxedHashableWT =
swift_conformsToProtocol(unboxedType, &HashableProtocolDescriptor)) {
swift_conformsToProtocolCommon(unboxedType, &HashableProtocolDescriptor)) {
_swift_makeAnyHashableUpcastingToHashableBaseType(
const_cast<OpaqueValue *>(unboxedValue), anyHashableResultPointer,
unboxedType, unboxedHashableWT);

View File

@@ -519,7 +519,7 @@ bool swift::_conformsToProtocol(const OpaqueValue *value,
const WitnessTable **conformance) {
// Look up the witness table for protocols that need them.
if (protocol.needsWitnessTable()) {
auto witness = swift_conformsToProtocol(type, protocol.getSwiftProtocol());
auto witness = swift_conformsToProtocolCommon(type, protocol.getSwiftProtocol());
if (!witness)
return false;
if (conformance)
@@ -1349,7 +1349,7 @@ extern "C" const StructDescriptor NOMINAL_TYPE_DESCR_SYM(SS);
static const _ObjectiveCBridgeableWitnessTable *
swift_conformsToObjectiveCBridgeable(const Metadata *T) {
return reinterpret_cast<const _ObjectiveCBridgeableWitnessTable *>
(swift_conformsToProtocol(T, &PROTOCOL_DESCR_SYM(s21_ObjectiveCBridgeable)));
(swift_conformsToProtocolCommon(T, &PROTOCOL_DESCR_SYM(s21_ObjectiveCBridgeable)));
}
static const _ObjectiveCBridgeableWitnessTable *

View File

@@ -210,7 +210,7 @@ static const _ObjectiveCBridgeableWitnessTable *
findBridgeWitness(const Metadata *T) {
static const auto bridgeableProtocol
= &PROTOCOL_DESCR_SYM(s21_ObjectiveCBridgeable);
auto w = swift_conformsToProtocol(T, bridgeableProtocol);
auto w = swift_conformsToProtocolCommon(T, bridgeableProtocol);
return reinterpret_cast<const _ObjectiveCBridgeableWitnessTable *>(w);
}
@@ -833,7 +833,7 @@ tryCastToAnyHashable(
// General case: If it conforms to Hashable, we cast it
if (hashableConformance == nullptr) {
hashableConformance = reinterpret_cast<const HashableWitnessTable *>(
swift_conformsToProtocol(srcType, &HashableProtocolDescriptor)
swift_conformsToProtocolCommon(srcType, &HashableProtocolDescriptor)
);
}
if (hashableConformance) {

View File

@@ -197,7 +197,7 @@ const Metadata *swift::getNSErrorMetadata() {
extern "C" const ProtocolDescriptor PROTOCOL_DESCR_SYM(s5Error);
const WitnessTable *swift::findErrorWitness(const Metadata *srcType) {
return swift_conformsToProtocol(srcType, &PROTOCOL_DESCR_SYM(s5Error));
return swift_conformsToProtocolCommon(srcType, &PROTOCOL_DESCR_SYM(s5Error));
}
id swift::dynamicCastValueToNSError(OpaqueValue *src,
@@ -389,7 +389,7 @@ const HashableWitnessTable *SwiftError::getHashableConformance() const {
const HashableWitnessTable *expectedWT = nullptr;
const HashableWitnessTable *wt =
reinterpret_cast<const HashableWitnessTable *>(
swift_conformsToProtocol(type, &HashableProtocolDescriptor));
swift_conformsToProtocolCommon(type, &HashableProtocolDescriptor));
hashableConformance.compare_exchange_strong(
expectedWT, wt ? wt : reinterpret_cast<const HashableWitnessTable *>(1),
std::memory_order_acq_rel);
@@ -613,7 +613,7 @@ swift::tryDynamicCastNSErrorObjectToValue(HeapObject *object,
return false;
// Is the target type a bridgeable error?
auto witness = swift_conformsToProtocol(destType,
auto witness = swift_conformsToProtocolCommon(destType,
TheObjectiveCBridgeableError);
if (witness) {

View File

@@ -2009,7 +2009,7 @@ public:
if (!assocType) return BuiltType();
auto projectDependentMemberType = [&](const Metadata *baseMetadata) -> const Metadata * {
auto witnessTable = swift_conformsToProtocol(baseMetadata, swiftProtocol);
auto witnessTable = swift_conformsToProtocolCommon(baseMetadata, swiftProtocol);
if (!witnessTable)
return nullptr;
@@ -2282,9 +2282,9 @@ swift_getTypeByMangledNameInEnvironmentInMetadataState(
return result.getType().getMetadata();
}
SWIFT_CC(swift) SWIFT_RUNTIME_EXPORT
static
const Metadata * _Nullable
swift_getTypeByMangledNameInContext(
swift_getTypeByMangledNameInContextImpl(
const char *typeNameStart,
size_t typeNameLength,
const TargetContextDescriptor<InProcess> *context,
@@ -2316,7 +2316,38 @@ swift_getTypeByMangledNameInContext(
SWIFT_CC(swift) SWIFT_RUNTIME_EXPORT
const Metadata * _Nullable
swift_getTypeByMangledNameInContextInMetadataState(
swift_getTypeByMangledNameInContext2(
const char *typeNameStart,
size_t typeNameLength,
const TargetContextDescriptor<InProcess> *context,
const void * const *genericArgs) {
context = swift_auth_data_non_address(
context, SpecialPointerAuthDiscriminators::ContextDescriptor);
return swift_getTypeByMangledNameInContextImpl(typeNameStart, typeNameLength,
context, genericArgs);
}
SWIFT_CC(swift) SWIFT_RUNTIME_EXPORT
const Metadata * _Nullable
swift_getTypeByMangledNameInContext(
const char *typeNameStart,
size_t typeNameLength,
const void *context,
const void * const *genericArgs) {
// This call takes `context` without a ptrauth signature. We
// declare it as `void *` to avoid the implicit ptrauth we get from
// the ptrauth_struct attribute. The static_cast implicitly signs the
// pointer when we call through to the implementation in
// swift_getTypeByMangledNameInContextImpl.
return swift_getTypeByMangledNameInContextImpl(
typeNameStart, typeNameLength,
static_cast<const TargetContextDescriptor<InProcess> *>(context),
genericArgs);
}
static
const Metadata * _Nullable
swift_getTypeByMangledNameInContextInMetadataStateImpl(
size_t metadataState,
const char *typeNameStart,
size_t typeNameLength,
@@ -2345,7 +2376,39 @@ swift_getTypeByMangledNameInContextInMetadataState(
return nullptr;
}
return result.getType().getMetadata();
}
SWIFT_CC(swift) SWIFT_RUNTIME_EXPORT
const Metadata * _Nullable
swift_getTypeByMangledNameInContextInMetadataState2(
size_t metadataState,
const char *typeNameStart,
size_t typeNameLength,
const TargetContextDescriptor<InProcess> *context,
const void * const *genericArgs) {
context = swift_auth_data_non_address(
context, SpecialPointerAuthDiscriminators::ContextDescriptor);
return swift_getTypeByMangledNameInContextInMetadataStateImpl(
metadataState, typeNameStart, typeNameLength, context, genericArgs);
}
SWIFT_CC(swift) SWIFT_RUNTIME_EXPORT
const Metadata * _Nullable
swift_getTypeByMangledNameInContextInMetadataState(
size_t metadataState,
const char *typeNameStart,
size_t typeNameLength,
const void *context,
const void * const *genericArgs) {
// This call takes `descriptor` without a ptrauth signature. We
// declare it as `void *` to avoid the implicit ptrauth we get from
// the ptrauth_struct attribute. The static_cast implicitly signs the
// pointer when we call through to the implementation in
// swift_getTypeByMangledNameInContextInMetadataState2.
return swift_getTypeByMangledNameInContextInMetadataStateImpl(
metadataState, typeNameStart, typeNameLength,
static_cast<const TargetContextDescriptor<InProcess> *>(context),
genericArgs);
}
/// Demangle a mangled name, but don't allow symbolic references.
@@ -2624,9 +2687,9 @@ swift_distributed_getWitnessTables(GenericEnvironmentDescriptor *genericEnv,
// ==== End of Function metadata functions ---------------------------------------
SWIFT_CC(swift) SWIFT_RUNTIME_EXPORT
static
MetadataResponse
swift_getOpaqueTypeMetadata(MetadataRequest request,
swift_getOpaqueTypeMetadataImpl(MetadataRequest request,
const void * const *arguments,
const OpaqueTypeDescriptor *descriptor,
unsigned index) {
@@ -2644,15 +2707,64 @@ swift_getOpaqueTypeMetadata(MetadataRequest request,
}).getType().getResponse();
}
SWIFT_CC(swift) SWIFT_RUNTIME_EXPORT
MetadataResponse
swift_getOpaqueTypeMetadata2(MetadataRequest request,
const void * const *arguments,
const OpaqueTypeDescriptor *descriptor,
unsigned index) {
descriptor = swift_auth_data_non_address(
descriptor, SpecialPointerAuthDiscriminators::OpaqueTypeDescriptor);
return swift_getOpaqueTypeMetadataImpl(request, arguments, descriptor, index);
}
SWIFT_CC(swift) SWIFT_RUNTIME_EXPORT
MetadataResponse
swift_getOpaqueTypeMetadata(MetadataRequest request,
const void * const *arguments,
const void *descriptor,
unsigned index) {
// This call takes `descriptor` without a ptrauth signature. We
// declare it as `void *` to avoid the implicit ptrauth we get from
// the ptrauth_struct attribute. The static_cast implicitly signs the
// pointer when we call through to the implementation in
// swift_getOpaqueTypeMetadataImpl.
return swift_getOpaqueTypeMetadataImpl(
request, arguments, static_cast<const OpaqueTypeDescriptor *>(descriptor),
index);
}
static const WitnessTable *
swift_getOpaqueTypeConformanceImpl(const void *const *arguments,
const OpaqueTypeDescriptor *descriptor,
unsigned index) {
auto response = swift_getOpaqueTypeMetadataImpl(
MetadataRequest(MetadataState::Complete), arguments, descriptor, index);
return (const WitnessTable *)response.Value;
}
SWIFT_CC(swift) SWIFT_RUNTIME_EXPORT
const WitnessTable *
swift_getOpaqueTypeConformance(const void * const *arguments,
swift_getOpaqueTypeConformance2(const void * const *arguments,
const OpaqueTypeDescriptor *descriptor,
unsigned index) {
auto response = swift_getOpaqueTypeMetadata(
MetadataRequest(MetadataState::Complete),
arguments, descriptor, index);
return (const WitnessTable *)response.Value;
descriptor = swift_auth_data_non_address(
descriptor, SpecialPointerAuthDiscriminators::OpaqueTypeDescriptor);
return swift_getOpaqueTypeConformanceImpl(arguments, descriptor, index);
}
SWIFT_CC(swift) SWIFT_RUNTIME_EXPORT
const WitnessTable *
swift_getOpaqueTypeConformance(const void * const *arguments,
const void *descriptor,
unsigned index) {
// This call takes `descriptor` without a ptrauth signature. We
// declare it as `void *` to avoid the implicit ptrauth we get from
// the ptrauth_struct attribute. The static_cast implicitly signs the
// pointer when we call through to the implementation in
// swift_getOpaqueTypeConformanceImpl.
return swift_getOpaqueTypeConformanceImpl(
arguments, static_cast<const OpaqueTypeDescriptor *>(descriptor), index);
}
#if SWIFT_OBJC_INTEROP

View File

@@ -1147,8 +1147,8 @@ swift_conformsToProtocolMaybeInstantiateSuperclasses(
}
static const WitnessTable *
swift_conformsToProtocolImpl(const Metadata *const type,
const ProtocolDescriptor *protocol) {
swift_conformsToProtocolCommonImpl(const Metadata *const type,
const ProtocolDescriptor *protocol) {
const WitnessTable *table;
bool hasUninstantiatedSuperclass;
@@ -1173,6 +1173,26 @@ swift_conformsToProtocolImpl(const Metadata *const type,
return table;
}
static const WitnessTable *
swift_conformsToProtocol2Impl(const Metadata *const type,
const ProtocolDescriptor *protocol) {
protocol = swift_auth_data_non_address(
protocol, SpecialPointerAuthDiscriminators::ProtocolDescriptor);
return swift_conformsToProtocolCommonImpl(type, protocol);
}
static const WitnessTable *
swift_conformsToProtocolImpl(const Metadata *const type,
const void *protocol) {
// This call takes `protocol` without a ptrauth signature. We declare
// it as `void *` to avoid the implicit ptrauth we get from the
// ptrauth_struct attribute. The static_cast implicitly signs the
// pointer when we call through to the implementation in
// swift_conformsToProtocolCommon.
return swift_conformsToProtocolCommonImpl(
type, static_cast<const ProtocolDescriptor *>(protocol));
}
const ContextDescriptor *
swift::_searchConformancesByMangledTypeName(Demangle::NodePointer node) {
auto traceState = runtime::trace::protocol_conformance_scan_begin(node);

View File

@@ -1644,7 +1644,7 @@ const HashableWitnessTable *
swift::hashable_support::getNSStringHashableConformance() {
return SWIFT_LAZY_CONSTANT(
reinterpret_cast<const HashableWitnessTable *>(
swift_conformsToProtocol(
swift_conformsToProtocolCommon(
getNSStringMetadata(),
&HashableProtocolDescriptor
)

View File

@@ -117,7 +117,7 @@ SwiftValueHeader::getHashableConformance() const {
const HashableWitnessTable *expectedWT = nullptr;
const HashableWitnessTable *wt =
reinterpret_cast<const HashableWitnessTable *>(
swift_conformsToProtocol(type, &HashableProtocolDescriptor));
swift_conformsToProtocolCommon(type, &HashableProtocolDescriptor));
hashableConformance.compare_exchange_strong(
expectedWT, wt ? wt : reinterpret_cast<const HashableWitnessTable *>(1),
std::memory_order_acq_rel);

View File

@@ -192,7 +192,7 @@ public func useFoo(x: String, y: C) {
// CHECK-LABEL: define {{.*}} @"$s18opaque_result_type6useFoo1x1yySS_AA1CCtF"
// CHECK: [[OPAQUE:%.*]] = call {{.*}} @"$s18opaque_result_type3baz1zQrx_tAA1PRzAA1QRzlFQOMg"
// CHECK: [[CONFORMANCE:%.*]] = call swiftcc ptr @swift_getOpaqueTypeConformance(ptr {{.*}}, ptr [[OPAQUE]], [[WORD:i32|i64]] 1)
// CHECK: [[CONFORMANCE:%.*]] = call swiftcc ptr @swift_getOpaqueTypeConformance{{2?}}(ptr {{.*}}, ptr [[OPAQUE]], [[WORD:i32|i64]] 1)
// CHECK: [[TYPE:%.*]] = call {{.*}} @__swift_instantiateConcreteTypeFromMangledName{{.*}}({{.*}} @"$s18opaque_result_type3baz1zQrx_tAA1PRzAA1QRzlFQOyAA1CCQo_MD")
// CHECK: call swiftcc ptr @swift_getAssociatedConformanceWitness(ptr [[CONFORMANCE]], ptr [[TYPE]]
@@ -210,7 +210,7 @@ public func gimmeBoom() -> Any {
// CHECK-LABEL: define {{.*}} @"$sSS18opaque_result_type1PAA1AAaBP_AA1OPWT"
// CHECK: [[OPAQUE:%.*]] = call {{.*}} @"$sSS18opaque_result_typeE3pooQryFQOMg"
// CHECK: call swiftcc ptr @swift_getOpaqueTypeConformance(ptr {{.*}}, ptr [[OPAQUE]], [[WORD]] 1)
// CHECK: call swiftcc ptr @swift_getOpaqueTypeConformance{{2?}}(ptr {{.*}}, ptr [[OPAQUE]], [[WORD]] 1)
// rdar://problem/49585457
protocol R {

View File

@@ -15,7 +15,7 @@ struct Foo<T: Tubb>: P {
}
// CHECK-LABEL: define {{.*}} @"$s030opaque_result_type_associated_C17_conformance_path3FooVyxGAA1PAA1AAaEP_AA4ButtPWT"
// CHECK: [[TUBB_CONFORMANCE:%.*]] = call swiftcc ptr @swift_getOpaqueTypeConformance({{.*}}, i{{.*}} 1)
// CHECK: [[TUBB_CONFORMANCE:%.*]] = call swiftcc ptr @swift_getOpaqueTypeConformance{{2?}}({{.*}}, i{{.*}} 1)
// CHECK: [[BUTT_CONFORMANCE_ADDR:%.*]] = getelementptr {{.*}} [[TUBB_CONFORMANCE]], i32 1
// CHECK: [[BUTT_CONFORMANCE:%.*]] = load {{.*}} [[BUTT_CONFORMANCE_ADDR]]
// CHECK: ret {{.*}} [[BUTT_CONFORMANCE]]

View File

@@ -178,6 +178,16 @@ TEST_F(CompatibilityOverrideRuntimeTest, test_swift_conformsToProtocol) {
ASSERT_EQ(Result, nullptr);
}
TEST_F(CompatibilityOverrideRuntimeTest, test_swift_conformsToProtocol2) {
auto Result = swift_conformsToProtocol2(nullptr, nullptr);
ASSERT_EQ(Result, nullptr);
}
TEST_F(CompatibilityOverrideRuntimeTest, test_swift_conformsToProtocolCommon) {
auto Result = swift_conformsToProtocolCommon(nullptr, nullptr);
ASSERT_EQ(Result, nullptr);
}
TEST_F(CompatibilityOverrideRuntimeTest, test_swift_getTypeByMangledNode) {
Demangler demangler;
auto Result = swift_getTypeByMangledNode(MetadataState::Abstract,