diff --git a/benchmark/cmake/modules/AddSwiftBenchmarkSuite.cmake b/benchmark/cmake/modules/AddSwiftBenchmarkSuite.cmake index e21f9c87566cc..a63d18c794dc4 100644 --- a/benchmark/cmake/modules/AddSwiftBenchmarkSuite.cmake +++ b/benchmark/cmake/modules/AddSwiftBenchmarkSuite.cmake @@ -106,7 +106,7 @@ endmacro() macro(configure_sdks_darwin) set(macosx_arch "x86_64") - set(iphoneos_arch "arm64" "armv7") + set(iphoneos_arch "arm64" "arm64e" "armv7") set(appletvos_arch "arm64") set(watchos_arch "armv7k") diff --git a/cmake/modules/DarwinSDKs.cmake b/cmake/modules/DarwinSDKs.cmake index 387ff28f6aaa7..f10940b79b82b 100644 --- a/cmake/modules/DarwinSDKs.cmake +++ b/cmake/modules/DarwinSDKs.cmake @@ -3,10 +3,10 @@ option(SWIFT_ENABLE_IOS32 TRUE) if(SWIFT_ENABLE_IOS32) -set(SUPPORTED_IOS_ARCHS "armv7;armv7s;arm64") +set(SUPPORTED_IOS_ARCHS "armv7;armv7s;arm64;arm64e") set(SUPPORTED_IOS_SIMULATOR_ARCHS "i386;x86_64") else() -set(SUPPORTED_IOS_ARCHS "arm64") +set(SUPPORTED_IOS_ARCHS "arm64;arm64e") set(SUPPORTED_IOS_SIMULATOR_ARCHS "x86_64") endif() diff --git a/cmake/modules/SwiftSetIfArchBitness.cmake b/cmake/modules/SwiftSetIfArchBitness.cmake index 5212cf3ccb854..9983cad817169 100644 --- a/cmake/modules/SwiftSetIfArchBitness.cmake +++ b/cmake/modules/SwiftSetIfArchBitness.cmake @@ -16,6 +16,7 @@ function(set_if_arch_bitness var_name) set("${var_name}" "${SIA_CASE_32_BIT}" PARENT_SCOPE) elseif("${SIA_ARCH}" STREQUAL "x86_64" OR "${SIA_ARCH}" STREQUAL "arm64" OR + "${SIA_ARCH}" STREQUAL "arm64e" OR "${SIA_ARCH}" STREQUAL "aarch64" OR "${SIA_ARCH}" STREQUAL "powerpc64" OR "${SIA_ARCH}" STREQUAL "powerpc64le" OR diff --git a/include/swift/ABI/Metadata.h b/include/swift/ABI/Metadata.h index 92ba02693beb7..53238489653af 100644 --- a/include/swift/ABI/Metadata.h +++ b/include/swift/ABI/Metadata.h @@ -53,6 +53,10 @@ struct RuntimeTarget; template <> struct RuntimeTarget<4> { using StoredPointer = uint32_t; + // To avoid implicit conversions from StoredSignedPointer to StoredPointer. + using StoredSignedPointer = struct { + uint32_t SignedValue; + }; using StoredSize = uint32_t; using StoredPointerDifference = int32_t; static constexpr size_t PointerSize = 4; @@ -61,6 +65,10 @@ struct RuntimeTarget<4> { template <> struct RuntimeTarget<8> { using StoredPointer = uint64_t; + // To avoid implicit conversions from StoredSignedPointer to StoredPointer. + using StoredSignedPointer = struct { + uint64_t SignedValue; + }; using StoredSize = uint64_t; using StoredPointerDifference = int64_t; static constexpr size_t PointerSize = 8; @@ -77,6 +85,7 @@ namespace reflection { struct InProcess { static constexpr size_t PointerSize = sizeof(uintptr_t); using StoredPointer = uintptr_t; + using StoredSignedPointer = uintptr_t; using StoredSize = size_t; using StoredPointerDifference = ptrdiff_t; @@ -85,6 +94,9 @@ struct InProcess { template using Pointer = T*; + + template + using SignedPointer = T; template using FarRelativeDirectPointer = FarRelativeDirectPointer; @@ -111,6 +123,7 @@ struct ExternalPointer { template struct External { using StoredPointer = typename Runtime::StoredPointer; + using StoredSignedPointer = typename Runtime::StoredSignedPointer; using StoredSize = typename Runtime::StoredSize; using StoredPointerDifference = typename Runtime::StoredPointerDifference; static constexpr size_t PointerSize = Runtime::PointerSize; @@ -118,6 +131,9 @@ struct External { template using Pointer = StoredPointer; + + template + using SignedPointer = StoredSignedPointer; template using FarRelativeDirectPointer = StoredPointer; @@ -141,9 +157,13 @@ using ConstTargetMetadataPointer template using TargetPointer = typename Runtime::template Pointer; +template +using TargetSignedPointer = typename Runtime::template SignedPointer; + template using ConstTargetPointer = typename Runtime::template Pointer; + template class Pointee, bool Nullable = true> using ConstTargetFarRelativeDirectPointer @@ -281,7 +301,10 @@ class TargetValueWitnessTypes { #define WANT_ALL_VALUE_WITNESSES #define DATA_VALUE_WITNESS(lowerId, upperId, type) #define FUNCTION_VALUE_WITNESS(lowerId, upperId, returnType, paramTypes) \ - typedef TargetPointer lowerId; + typedef returnType (*lowerId ## Unsigned) paramTypes; \ + typedef TargetSignedPointer lowerId; #define MUTABLE_VALUE_TYPE TargetPointer #define IMMUTABLE_VALUE_TYPE ConstTargetPointer #define MUTABLE_BUFFER_TYPE TargetPointer @@ -314,6 +337,9 @@ template struct TargetValueWitnessTable { #define WANT_ONLY_REQUIRED_VALUE_WITNESSES #define VALUE_WITNESS(LOWER_ID, UPPER_ID) \ typename TargetValueWitnessTypes::LOWER_ID LOWER_ID; +#define FUNCTION_VALUE_WITNESS(LOWER_ID, UPPER_ID, RET, PARAMS) \ + typename TargetValueWitnessTypes::LOWER_ID LOWER_ID; + #include "swift/ABI/ValueWitness.def" using StoredSize = typename Runtime::StoredSize; @@ -595,7 +621,7 @@ struct TargetMetadata { #define WANT_ONLY_REQUIRED_VALUE_WITNESSES #define FUNCTION_VALUE_WITNESS(WITNESS, UPPER, RET_TYPE, PARAM_TYPES) \ template \ - _ResultOf::type \ + _ResultOf::type \ vw_##WITNESS(A &&...args) const { \ return getValueWitnesses()->WITNESS(std::forward(args)..., this); \ } @@ -744,7 +770,7 @@ template struct TargetHeapMetadataHeaderPrefix { /// Destroy the object, returning the allocated size of the object /// or 0 if the object shouldn't be deallocated. - TargetPointer destroy; + TargetSignedPointer destroy; }; using HeapMetadataHeaderPrefix = TargetHeapMetadataHeaderPrefix; @@ -838,10 +864,17 @@ struct TargetVTableDescriptorHeader { template struct TargetContextDescriptor; -template +template class Context = TargetContextDescriptor> +using TargetSignedContextPointer = TargetSignedPointer * __ptrauth_swift_type_descriptor>; + +template class Context = TargetContextDescriptor> using TargetRelativeContextPointer = - RelativeIndirectablePointer, - /*nullable*/ true>; + RelativeIndirectablePointer, + /*nullable*/ true, int32_t, + TargetSignedContextPointer>; using RelativeContextPointer = TargetRelativeContextPointer; @@ -849,7 +882,8 @@ template class Context = TargetContextDescriptor> using RelativeContextPointerIntPair = RelativeIndirectablePointerIntPair, IntTy, - /*nullable*/ true, int32_t>; + /*nullable*/ true, int32_t, + TargetSignedContextPointer>; template struct TargetMethodDescriptor; @@ -1085,13 +1119,13 @@ struct TargetClassMetadata : public TargetAnyClassMetadata { /// if this is an artificial subclass. We currently provide no /// supported mechanism for making a non-artificial subclass /// dynamically. - ConstTargetMetadataPointer Description; + TargetSignedPointer * __ptrauth_swift_type_descriptor> Description; public: /// A function for destroying instance variables, used to clean up after an /// early return from a constructor. If null, no clean up will be performed /// and all ivars must be trivial. - TargetPointer IVarDestroyer; + TargetSignedPointer IVarDestroyer; // After this come the class members, laid out as follows: // - class members for the superclass (recursively) @@ -1108,6 +1142,12 @@ struct TargetClassMetadata : public TargetAnyClassMetadata { return Description; } + typename Runtime::StoredSignedPointer + getDescriptionAsSignedPointer() const { + assert(isTypeMetadata()); + return Description; + } + void setDescription(const TargetClassDescriptor *description) { Description = description; } @@ -1314,7 +1354,7 @@ struct TargetForeignClassMetadata : public TargetForeignTypeMetadata { using StoredPointer = typename Runtime::StoredPointer; /// An out-of-line description of the type. - ConstTargetMetadataPointer Description; + TargetSignedPointer * __ptrauth_swift_type_descriptor> Description; /// The superclass of the foreign class, if any. ConstTargetMetadataPointer @@ -1330,6 +1370,11 @@ struct TargetForeignClassMetadata : public TargetForeignTypeMetadata { return Description; } + typename Runtime::StoredSignedPointer + getDescriptionAsSignedPointer() const { + return Description; + } + static bool classof(const TargetMetadata *metadata) { return metadata->getKind() == MetadataKind::ForeignClass; } @@ -1345,8 +1390,7 @@ struct TargetValueMetadata : public TargetMetadata { : TargetMetadata(Kind), Description(description) {} /// An out-of-line description of the type. - ConstTargetMetadataPointer - Description; + TargetSignedPointer * __ptrauth_swift_type_descriptor> Description; static bool classof(const TargetMetadata *metadata) { return metadata->getKind() == MetadataKind::Struct @@ -1358,6 +1402,11 @@ struct TargetValueMetadata : public TargetMetadata { getDescription() const { return Description; } + + typename Runtime::StoredSignedPointer + getDescriptionAsSignedPointer() const { + return Description; + } }; using ValueMetadata = TargetValueMetadata; @@ -2189,7 +2238,7 @@ struct TargetTypeMetadataRecord { DirectNominalTypeDescriptor; /// An indirect reference to a nominal type descriptor. - RelativeDirectPointerIntPair * const, + RelativeDirectPointerIntPair * __ptrauth_swift_type_descriptor>, TypeReferenceKind> IndirectNominalTypeDescriptor; @@ -2242,24 +2291,25 @@ template class TargetGenericRequirementDescriptor; /// pointer equivalent to \c TargetProtocolDescriptorRef. template class RelativeTargetProtocolDescriptorPointer { - union AnyProtocol { - TargetProtocolDescriptor descriptor; + union { + /// Relative pointer to a Swift protocol descriptor. + /// The \c bool value will be false to indicate that the protocol + /// is a Swift protocol, or true to indicate that this references + /// an Objective-C protocol. + RelativeContextPointerIntPair + swiftPointer; +#if SWIFT_OBJC_INTEROP + /// Relative pointer to an ObjC protocol descriptor. + /// The \c bool value will be false to indicate that the protocol + /// is a Swift protocol, or true to indicate that this references + /// an Objective-C protocol. + RelativeIndirectablePointerIntPair objcPointer; +#endif }; - /// The relative pointer itself. - /// - /// The \c AnyProtocol value type ensures that we can reference any - /// protocol descriptor; it will be reinterpret_cast to the appropriate - /// protocol descriptor type. - /// - /// The \c bool integer value will be false to indicate that the protocol - /// is a Swift protocol, or true to indicate that this references - /// an Objective-C protocol. - RelativeIndirectablePointerIntPair pointer; - #if SWIFT_OBJC_INTEROP bool isObjC() const { - return pointer.getInt(); + return objcPointer.getInt(); } #endif @@ -2269,13 +2319,13 @@ class RelativeTargetProtocolDescriptorPointer { #if SWIFT_OBJC_INTEROP if (isObjC()) { return TargetProtocolDescriptorRef::forObjC( - protocol_const_cast(pointer.getPointer())); + const_cast(objcPointer.getPointer())); } #endif return TargetProtocolDescriptorRef::forSwift( reinterpret_cast>(pointer.getPointer())); + Runtime, TargetProtocolDescriptor>>(swiftPointer.getPointer())); } operator TargetProtocolDescriptorRef() const { @@ -2293,7 +2343,7 @@ struct TargetTypeReference { /// An indirect reference to a TypeContextDescriptor or ProtocolDescriptor. RelativeDirectPointer< - ConstTargetMetadataPointer> + TargetSignedPointer * __ptrauth_swift_type_descriptor>> IndirectTypeDescriptor; /// An indirect reference to an Objective-C class. @@ -2391,7 +2441,7 @@ struct TargetProtocolConformanceDescriptor final private: /// The protocol being conformed to. - RelativeIndirectablePointer Protocol; + TargetRelativeContextPointer Protocol; // Some description of the type that conforms to the protocol. TargetTypeReference TypeRef; @@ -2424,7 +2474,8 @@ struct TargetProtocolConformanceDescriptor final return TypeRef.getTypeDescriptor(getTypeKind()); } - const TargetContextDescriptor **_getTypeDescriptorLocation() const { + TargetContextDescriptor * __ptrauth_swift_type_descriptor * + _getTypeDescriptorLocation() const { if (getTypeKind() != TypeReferenceKind::IndirectTypeDescriptor) return nullptr; return TypeRef.IndirectTypeDescriptor.get(); @@ -4490,11 +4541,20 @@ struct DynamicReplacementChainEntry { struct DynamicReplacementKey { RelativeDirectPointer root; uint32_t flags; + + uint16_t getExtraDiscriminator() const { + return flags & 0x0000FFFF; + } }; /// A record describing a dynamic function replacement. class DynamicReplacementDescriptor { - RelativeIndirectablePointer replacedFunctionKey; + RelativeIndirectablePointer< + const DynamicReplacementKey, false, int32_t, + TargetSignedPointer> + replacedFunctionKey; RelativeDirectPointer replacementFunction; RelativeDirectPointer chainEntry; uint32_t flags; diff --git a/include/swift/ABI/MetadataValues.h b/include/swift/ABI/MetadataValues.h index 6e1cc0356f35e..606c1a007d150 100644 --- a/include/swift/ABI/MetadataValues.h +++ b/include/swift/ABI/MetadataValues.h @@ -19,6 +19,7 @@ #ifndef SWIFT_ABI_METADATAVALUES_H #define SWIFT_ABI_METADATAVALUES_H +#include "swift/ABI/KeyPath.h" #include "swift/AST/Ownership.h" #include "swift/Basic/LLVM.h" #include "swift/Basic/FlagSet.h" @@ -294,6 +295,8 @@ class MethodDescriptorFlags { KindMask = 0x0F, // 16 kinds should be enough for anybody IsInstanceMask = 0x10, IsDynamicMask = 0x20, + ExtraDiscriminatorShift = 16, + ExtraDiscriminatorMask = 0xFFFF0000, }; int_type Value; @@ -320,6 +323,13 @@ class MethodDescriptorFlags { return copy; } + MethodDescriptorFlags withExtraDiscriminator(uint16_t value) const { + auto copy = *this; + copy.Value = (copy.Value & ~ExtraDiscriminatorMask) + | (int_type(value) << ExtraDiscriminatorShift); + return copy; + } + Kind getKind() const { return Kind(Value & KindMask); } /// Is the method marked 'dynamic'? @@ -330,6 +340,10 @@ class MethodDescriptorFlags { /// Note that 'init' is not considered an instance member. bool isInstance() const { return Value & IsInstanceMask; } + uint16_t getExtraDiscriminator() const { + return (Value >> ExtraDiscriminatorShift); + } + int_type getIntValue() const { return Value; } }; @@ -516,6 +530,8 @@ class ProtocolRequirementFlags { enum : int_type { KindMask = 0x0F, // 16 kinds should be enough for anybody IsInstanceMask = 0x10, + ExtraDiscriminatorShift = 16, + ExtraDiscriminatorMask = 0xFFFF0000, }; int_type Value; @@ -533,6 +549,13 @@ class ProtocolRequirementFlags { return copy; } + ProtocolRequirementFlags withExtraDiscriminator(uint16_t value) const { + auto copy = *this; + copy.Value = (copy.Value & ~ExtraDiscriminatorMask) + | (int_type(value) << ExtraDiscriminatorShift); + return copy; + } + Kind getKind() const { return Kind(Value & KindMask); } /// Is the method an instance member? @@ -540,6 +563,14 @@ class ProtocolRequirementFlags { /// Note that 'init' is not considered an instance member. bool isInstance() const { return Value & IsInstanceMask; } + bool isSignedWithAddress() const { + return getKind() != Kind::BaseProtocol; + } + + uint16_t getExtraDiscriminator() const { + return (Value >> ExtraDiscriminatorShift); + } + int_type getIntValue() const { return Value; } enum : uintptr_t { @@ -1029,6 +1060,68 @@ static inline bool isValueWitnessTableMutable(EnumLayoutFlags flags) { return uintptr_t(flags) & uintptr_t(EnumLayoutFlags::IsVWTMutable); } +namespace SpecialPointerAuthDiscriminators { + // All of these values are the stable string hash of the corresponding + // variable name: + // (computeStableStringHash % 65535 + 1) + + /// HeapMetadataHeader::destroy + const uint16_t HeapDestructor = 0xbbbf; + + /// Type descriptor data pointers. + const uint16_t TypeDescriptor = 0xae86; + + /// Runtime function variables exported by the runtime. + const uint16_t RuntimeFunctionEntry = 0x625b; + + /// Value witness functions. + const uint16_t InitializeBufferWithCopyOfBuffer = 0xda4a; + const uint16_t Destroy = 0x04f8; + const uint16_t InitializeWithCopy = 0xe3ba; + const uint16_t AssignWithCopy = 0x8751; + const uint16_t InitializeWithTake = 0x48d8; + const uint16_t AssignWithTake = 0xefda; + const uint16_t DestroyArray = 0x2398; + const uint16_t InitializeArrayWithCopy = 0xa05c; + const uint16_t InitializeArrayWithTakeFrontToBack = 0x1c3e; + const uint16_t InitializeArrayWithTakeBackToFront = 0x8dd3; + const uint16_t StoreExtraInhabitant = 0x79c5; + const uint16_t GetExtraInhabitantIndex = 0x2ca8; + const uint16_t GetEnumTag = 0xa3b5; + const uint16_t DestructiveProjectEnumData = 0x041d; + const uint16_t DestructiveInjectEnumTag = 0xb2e4; + const uint16_t GetEnumTagSinglePayload = 0x60f0; + const uint16_t StoreEnumTagSinglePayload = 0xa0d1; + + /// KeyPath metadata functions. + const uint16_t KeyPathDestroy = _SwiftKeyPath_ptrauth_ArgumentDestroy; + const uint16_t KeyPathCopy = _SwiftKeyPath_ptrauth_ArgumentCopy; + const uint16_t KeyPathEquals = _SwiftKeyPath_ptrauth_ArgumentEquals; + const uint16_t KeyPathHash = _SwiftKeyPath_ptrauth_ArgumentHash; + const uint16_t KeyPathGetter = _SwiftKeyPath_ptrauth_Getter; + const uint16_t KeyPathNonmutatingSetter = _SwiftKeyPath_ptrauth_NonmutatingSetter; + const uint16_t KeyPathMutatingSetter = _SwiftKeyPath_ptrauth_MutatingSetter; + const uint16_t KeyPathGetLayout = _SwiftKeyPath_ptrauth_ArgumentLayout; + const uint16_t KeyPathInitializer = _SwiftKeyPath_ptrauth_ArgumentInit; + const uint16_t KeyPathMetadataAccessor = _SwiftKeyPath_ptrauth_MetadataAccessor; + + /// ObjC bridging entry points. + const uint16_t ObjectiveCTypeDiscriminator = 0x31c3; // = 12739 + const uint16_t bridgeToObjectiveCDiscriminator = 0xbca0; // = 48288 + const uint16_t forceBridgeFromObjectiveCDiscriminator = 0x22fb; // = 8955 + const uint16_t conditionallyBridgeFromObjectiveCDiscriminator = 0x9a9b; // = 39579 + + /// Dynamic replacement pointers. + const uint16_t DynamicReplacementScope = 0x48F0; // = 18672 + const uint16_t DynamicReplacementKey = 0x2C7D; // = 11389 + + /// Resume functions for yield-once coroutines that yield a single + /// opaque borrowed/inout value. These aren't actually hard-coded, but + /// they're important enough to be worth writing in one place. + const uint16_t OpaqueReadResumeFunction = 56769; + const uint16_t OpaqueModifyResumeFunction = 3909; +} + /// The number of arguments that will be passed directly to a generic /// nominal type access function. The remaining arguments (if any) will be /// passed as an array. That array has enough storage for all of the arguments, diff --git a/include/swift/AST/Builtins.def b/include/swift/AST/Builtins.def index 6925fd42d7703..60b2f7739a7a5 100644 --- a/include/swift/AST/Builtins.def +++ b/include/swift/AST/Builtins.def @@ -657,6 +657,9 @@ BUILTIN_MISC_OPERATION(WillThrow, "willThrow", "", Special) /// poundAssert has type (Builtin.Int1, Builtin.RawPointer) -> (). BUILTIN_MISC_OPERATION(PoundAssert, "poundAssert", "", Special) +// TypePtrAuthDiscriminator has type (T.Type) -> Int64 +BUILTIN_MISC_OPERATION(TypePtrAuthDiscriminator, "typePtrAuthDiscriminator", "n", Special) + // BUILTIN_MISC_OPERATION_WITH_SILGEN - Miscellaneous operations that are // specially emitted during SIL generation. // diff --git a/include/swift/AST/IRGenOptions.h b/include/swift/AST/IRGenOptions.h index 1ada3d32d0708..d18d5c94ab009 100644 --- a/include/swift/AST/IRGenOptions.h +++ b/include/swift/AST/IRGenOptions.h @@ -23,6 +23,7 @@ #include "swift/Basic/Sanitizers.h" #include "swift/Basic/OptionSet.h" #include "swift/Basic/OptimizationMode.h" +#include "clang/Basic/PointerAuthOptions.h" // FIXME: This include is just for llvm::SanitizerCoverageOptions. We should // split the header upstream so we don't include so much. #include "llvm/Transforms/Instrumentation.h" @@ -70,6 +71,59 @@ enum class IRGenEmbedMode : unsigned { EmbedBitcode }; +using clang::PointerAuthSchema; + +struct PointerAuthOptions : clang::PointerAuthOptions { + /// Native opaque function types, both thin and thick. + /// Never address-sensitive. + PointerAuthSchema SwiftFunctionPointers; + + /// Swift key path helpers. + PointerAuthSchema KeyPaths; + + /// Swift value witness functions. + PointerAuthSchema ValueWitnesses; + + /// Swift protocol witness functions. + PointerAuthSchema ProtocolWitnesses; + + /// Swift protocol witness table associated type metadata access functions. + PointerAuthSchema ProtocolAssociatedTypeAccessFunctions; + + /// Swift protocol witness table associated conformance witness table + /// access functions. + PointerAuthSchema ProtocolAssociatedTypeWitnessTableAccessFunctions; + + /// Swift class v-table functions. + PointerAuthSchema SwiftClassMethods; + + /// Swift dynamic replacement implementations. + PointerAuthSchema SwiftDynamicReplacements; + PointerAuthSchema SwiftDynamicReplacementKeys; + + /// Swift class v-table functions not signed with an address. This is the + /// return type of swift_lookUpClassMethod(). + PointerAuthSchema SwiftClassMethodPointers; + + /// Swift heap metadata destructors. + PointerAuthSchema HeapDestructors; + + /// Non-constant function pointers captured in a partial-apply context. + PointerAuthSchema PartialApplyCapture; + + /// Type descriptor data pointers. + PointerAuthSchema TypeDescriptors; + + /// Type descriptor data pointers when passed as arguments. + PointerAuthSchema TypeDescriptorsAsArguments; + + /// Resumption functions from yield-once coroutines. + PointerAuthSchema YieldOnceResumeFunctions; + + /// Resumption functions from yield-many coroutines. + PointerAuthSchema YieldManyResumeFunctions; +}; + /// The set of options supported by IR generation. class IRGenOptions { public: @@ -236,6 +290,9 @@ class IRGenOptions { /// Which sanitizer coverage is turned on. llvm::SanitizerCoverageOptions SanitizeCoverage; + /// Pointer authentication. + PointerAuthOptions PointerAuth; + /// The different modes for dumping IRGen type info. enum class TypeInfoDumpFilter { All, diff --git a/include/swift/AST/PlatformConditionKinds.def b/include/swift/AST/PlatformConditionKinds.def index d83914a16e5b2..147e74359ff2a 100644 --- a/include/swift/AST/PlatformConditionKinds.def +++ b/include/swift/AST/PlatformConditionKinds.def @@ -40,5 +40,8 @@ PLATFORM_CONDITION(CanImport, "canImport") /// Target Environment (currently just 'simulator' or absent) PLATFORM_CONDITION(TargetEnvironment, "targetEnvironment") +/// Pointer authentication enabled +PLATFORM_CONDITION_(PtrAuth, "ptrauth") + #undef PLATFORM_CONDITION #undef PLATFORM_CONDITION_ diff --git a/include/swift/Basic/LangOptions.h b/include/swift/Basic/LangOptions.h index fb4d94b444ec4..58d3fdc87439a 100644 --- a/include/swift/Basic/LangOptions.h +++ b/include/swift/Basic/LangOptions.h @@ -412,7 +412,7 @@ namespace swift { } private: - llvm::SmallVector, 5> + llvm::SmallVector, 6> PlatformConditionValues; llvm::SmallVector CustomConditionalCompilationFlags; }; diff --git a/include/swift/Basic/RelativePointer.h b/include/swift/Basic/RelativePointer.h index f5cffd1c33c25..8a11849520a7a 100644 --- a/include/swift/Basic/RelativePointer.h +++ b/include/swift/Basic/RelativePointer.h @@ -228,7 +228,7 @@ class RelativeIndirectPointer { /// A relative reference to an object stored in memory. The reference may be /// direct or indirect, and uses the low bit of the (assumed at least /// 2-byte-aligned) pointer to differentiate. -template +template class RelativeIndirectablePointer { private: static_assert(std::is_integral::value && @@ -290,7 +290,7 @@ class RelativeIndirectablePointer { // If the low bit is set, then this is an indirect address. Otherwise, // it's direct. if (offsetPlusIndirect & 1) { - return *reinterpret_cast(address); + return *reinterpret_cast(address); } else { return reinterpret_cast(address); } @@ -315,7 +315,8 @@ class RelativeIndirectablePointer { /// 2-byte-aligned) pointer to differentiate. The remaining low bits store /// an additional tiny integer value. template + typename Offset = int32_t, + typename IndirectType = const ValueTy *> class RelativeIndirectablePointerIntPair { private: static_assert(std::is_integral::value && @@ -363,7 +364,7 @@ class RelativeIndirectablePointerIntPair { // If the low bit is set, then this is an indirect address. Otherwise, // it's direct. if (offsetPlusIndirect & 1) { - return *reinterpret_cast(address); + return *reinterpret_cast(address); } else { return reinterpret_cast(address); } @@ -447,10 +448,15 @@ class RelativeDirectPointerImpl { } }; -/// A direct relative reference to an object. -template -class RelativeDirectPointer : - private RelativeDirectPointerImpl +template +class RelativeDirectPointer; + +/// A direct relative reference to an object that is not a function pointer. +template +class RelativeDirectPointer::value>::type> + : private RelativeDirectPointerImpl { using super = RelativeDirectPointerImpl; public: @@ -475,26 +481,44 @@ class RelativeDirectPointer : /// A specialization of RelativeDirectPointer for function pointers, /// allowing for calls. -template -class RelativeDirectPointer : - private RelativeDirectPointerImpl +template +class RelativeDirectPointer::value>::type> + : private RelativeDirectPointerImpl { - using super = RelativeDirectPointerImpl; + using super = RelativeDirectPointerImpl; public: - using super::get; using super::super; - RelativeDirectPointer &operator=(RetTy (*absolute)(ArgTy...)) & { + RelativeDirectPointer &operator=(T absolute) & { super::operator=(absolute); return *this; } - + + typename super::PointerTy get() const & { + auto ptr = this->super::get(); +#if SWIFT_PTRAUTH + if (Nullable && !ptr) + return ptr; + return ptrauth_sign_unauthenticated(ptr, ptrauth_key_function_pointer, 0); +#else + return ptr; +#endif + } + operator typename super::PointerTy() const & { return this->get(); } - RetTy operator()(ArgTy...arg) const { - return this->get()(std::forward(arg)...); + template + typename std::result_of::type operator()(ArgTy...arg) const { +#if SWIFT_PTRAUTH + return ptrauth_sign_unauthenticated(this->super::get(), + ptrauth_key_function_pointer, + 0)(std::forward(arg)...); +#else + return this->super::get()(std::forward(arg)...); +#endif } using super::isNull; @@ -504,17 +528,17 @@ class RelativeDirectPointer : /// tiny integer value crammed into its low bits. template -class RelativeDirectPointerIntPair { +class RelativeDirectPointerIntPairImpl { Offset RelativeOffsetPlusInt; /// RelativePointers should appear in statically-generated metadata. They /// shouldn't be constructed or copied. - RelativeDirectPointerIntPair() = delete; - RelativeDirectPointerIntPair(RelativeDirectPointerIntPair &&) = delete; - RelativeDirectPointerIntPair(const RelativeDirectPointerIntPair &) = delete; - RelativeDirectPointerIntPair &operator=(RelativeDirectPointerIntPair &&) + RelativeDirectPointerIntPairImpl() = delete; + RelativeDirectPointerIntPairImpl(RelativeDirectPointerIntPairImpl &&) = delete; + RelativeDirectPointerIntPairImpl(const RelativeDirectPointerIntPairImpl &) = delete; + RelativeDirectPointerIntPairImpl &operator=(RelativeDirectPointerIntPairImpl &&) = delete; - RelativeDirectPointerIntPair &operator=(const RelativeDirectPointerIntPair&) + RelativeDirectPointerIntPairImpl &operator=(const RelativeDirectPointerIntPairImpl&) = delete; static Offset getMask() { @@ -546,6 +570,24 @@ class RelativeDirectPointerIntPair { } }; +/// A direct relative reference to an aligned object, with an additional +/// tiny integer value crammed into its low bits. +template +class RelativeDirectPointerIntPair; + +template +class RelativeDirectPointerIntPair::value>::type> + : private RelativeDirectPointerIntPairImpl +{ + using super = RelativeDirectPointerIntPairImpl; +public: + using super::getPointer; + using super::getInt; + using super::getOpaqueValue; +}; + // Type aliases for "far" relative pointers, which need to be able to reach // across the full address space instead of only across a single small-code- // model image. diff --git a/include/swift/IRGen/Linking.h b/include/swift/IRGen/Linking.h index 6602dd8e562ed..88322616bd22c 100644 --- a/include/swift/IRGen/Linking.h +++ b/include/swift/IRGen/Linking.h @@ -1043,10 +1043,14 @@ class LinkEntity { ::getFromOpaqueValue(reinterpret_cast(Pointer)); } - SILFunction *getSILFunction() const { - assert(getKind() == Kind::SILFunction || + bool hasSILFunction() const { + return getKind() == Kind::SILFunction || getKind() == Kind::DynamicallyReplaceableFunctionVariable || - getKind() == Kind::DynamicallyReplaceableFunctionKey); + getKind() == Kind::DynamicallyReplaceableFunctionKey; + } + + SILFunction *getSILFunction() const { + assert(hasSILFunction()); return reinterpret_cast(Pointer); } @@ -1097,6 +1101,16 @@ class LinkEntity { assert(getKind() == Kind::SILFunction); return LINKENTITY_GET_FIELD(Data, IsDynamicallyReplaceableImpl); } + bool isDynamicallyReplaceableKey() const { + return getKind() == Kind::DynamicallyReplaceableFunctionKey || + getKind() == Kind::OpaqueTypeDescriptorAccessorKey; + } + bool isOpaqueTypeDescriptorAccessor() const { + return getKind() == Kind::OpaqueTypeDescriptorAccessor || + getKind() == Kind::OpaqueTypeDescriptorAccessorImpl || + getKind() == Kind::OpaqueTypeDescriptorAccessorKey || + getKind() == Kind::OpaqueTypeDescriptorAccessorVar; + } bool isAllocator() const { assert(getKind() == Kind::DynamicallyReplaceableFunctionImpl || getKind() == Kind::DynamicallyReplaceableFunctionKeyAST || @@ -1104,6 +1118,7 @@ class LinkEntity { return SecondaryPointer != nullptr; } bool isValueWitness() const { return getKind() == Kind::ValueWitness; } + bool isContextDescriptor() const; CanType getType() const { assert(isTypeKind(getKind())); return CanType(reinterpret_cast(Pointer)); diff --git a/include/swift/Remote/InProcessMemoryReader.h b/include/swift/Remote/InProcessMemoryReader.h index c2c4f0ee345ee..2f6b5b535a437 100644 --- a/include/swift/Remote/InProcessMemoryReader.h +++ b/include/swift/Remote/InProcessMemoryReader.h @@ -55,6 +55,15 @@ class InProcessMemoryReader final : public MemoryReader { *result = sizeof(size_t); return true; } + case DLQ_GetPtrAuthMask: { + auto result = static_cast(outBuffer); +#if __has_feature(ptrauth_calls) + *result = (uintptr_t)ptrauth_strip((void*)0x0007ffffffffffff, 0); +#else + *result = (uintptr_t)~0ull; +#endif + return true; + } case DLQ_GetObjCReservedLowBits: { auto result = static_cast(outBuffer); if (applePlatform && !iosDerivedPlatform && (sizeof(void *) == 8)) { diff --git a/include/swift/Remote/MetadataReader.h b/include/swift/Remote/MetadataReader.h index c117a4d15aba5..b11ee83f9a294 100644 --- a/include/swift/Remote/MetadataReader.h +++ b/include/swift/Remote/MetadataReader.h @@ -163,6 +163,7 @@ class MetadataReader { using BuiltTypeDecl = typename BuilderType::BuiltTypeDecl; using BuiltProtocolDecl = typename BuilderType::BuiltProtocolDecl; using StoredPointer = typename Runtime::StoredPointer; + using StoredSignedPointer = typename Runtime::StoredSignedPointer; using StoredSize = typename Runtime::StoredSize; private: @@ -346,11 +347,34 @@ class MetadataReader { std::shared_ptr Reader; + StoredPointer PtrAuthMask; + + StoredPointer stripSignedPointer(StoredSignedPointer P) { + return P.SignedValue & PtrAuthMask; + } + + RemoteAbsolutePointer stripSignedPointer(const RemoteAbsolutePointer &P) { + if (P.isResolved()) { + return RemoteAbsolutePointer("", + P.getResolvedAddress().getAddressData() & PtrAuthMask); + } + return P; + } + + StoredPointer queryPtrAuthMask() { + StoredPointer QueryResult; + if (Reader->queryDataLayout(DataLayoutQueryType::DLQ_GetPtrAuthMask, + nullptr, &QueryResult)) { + return QueryResult; + } + return ~StoredPointer(0); + } + template MetadataReader(std::shared_ptr reader, T &&... args) : Builder(std::forward(args)...), - Reader(std::move(reader)) { - + Reader(std::move(reader)), + PtrAuthMask(queryPtrAuthMask()) { } MetadataReader(const MetadataReader &other) = delete; @@ -383,7 +407,7 @@ class MetadataReader { RemoteAbsolutePointer resolved; if (directness == Directness::Indirect) { if (auto indirectAddress = readPointer(remoteAddress)) { - resolved = *indirectAddress; + resolved = stripSignedPointer(*indirectAddress); } else { return nullptr; } @@ -681,8 +705,8 @@ class MetadataReader { // Swift-native protocol. auto Demangled = - readDemanglingForContextDescriptor(ProtocolAddress.getSwiftProtocol(), - dem); + readDemanglingForContextDescriptor( + stripSignedPointer({ProtocolAddress.getSwiftProtocol()}), dem); if (!Demangled) return resolver.failure(); @@ -1516,7 +1540,10 @@ class MetadataReader { // Low bit set in the offset indicates that the offset leads to the absolute // address in memory. if (indirect) { - return readPointer(resultAddress); + if (auto ptr = readPointer(resultAddress)) { + return stripSignedPointer(*ptr); + } + return None; } return RemoteAbsolutePointer("", resultAddress); @@ -1681,7 +1708,8 @@ class MetadataReader { case MetadataKind::Class: { auto classMeta = cast>(metadata); while (true) { - auto descriptorAddress = classMeta->getDescription(); + StoredSignedPointer descriptorAddressSigned = classMeta->getDescriptionAsSignedPointer(); + StoredPointer descriptorAddress = stripSignedPointer(descriptorAddressSigned); // If this class has a null descriptor, it's artificial, // and we need to skip it upon request. Otherwise, we're done. @@ -1709,12 +1737,16 @@ class MetadataReader { case MetadataKind::Optional: case MetadataKind::Enum: { auto valueMeta = cast>(metadata); - return valueMeta->getDescription(); + StoredSignedPointer descriptorAddressSigned = valueMeta->getDescriptionAsSignedPointer(); + StoredPointer descriptorAddress = stripSignedPointer(descriptorAddressSigned); + return descriptorAddress; } case MetadataKind::ForeignClass: { auto foreignMeta = cast>(metadata); - return foreignMeta->Description; + StoredSignedPointer descriptorAddressSigned = foreignMeta->getDescriptionAsSignedPointer(); + StoredPointer descriptorAddress = stripSignedPointer(descriptorAddressSigned); + return descriptorAddress; } default: @@ -2609,16 +2641,20 @@ class MetadataReader { // Otherwise, it's the RW-data; read the RO-data pointer from a // well-known position within the RW-data. + StoredSignedPointer signedDataPtr; static constexpr uint32_t OffsetToROPtr = 8; - if (!Reader->readInteger(RemoteAddress(dataPtr + OffsetToROPtr), &dataPtr)) + if (!Reader->readInteger(RemoteAddress(dataPtr + OffsetToROPtr), &signedDataPtr)) return StoredPointer(); + dataPtr = stripSignedPointer(signedDataPtr); // Newer Objective-C runtimes implement a size optimization where the RO // field is a tagged union. If the low-bit is set, then the pointer needs // to be dereferenced once more to yield the real class_ro_t pointer. - if (dataPtr & 1) - if (!Reader->readInteger(RemoteAddress(dataPtr^1), &dataPtr)) + if (dataPtr & 1) { + if (!Reader->readInteger(RemoteAddress(dataPtr^1), &signedDataPtr)) return StoredPointer(); + dataPtr = stripSignedPointer(signedDataPtr); + } return dataPtr; } diff --git a/include/swift/Runtime/Config.h b/include/swift/Runtime/Config.h index c8cc49083ad17..471f4f521e050 100644 --- a/include/swift/Runtime/Config.h +++ b/include/swift/Runtime/Config.h @@ -226,4 +226,95 @@ // so changing this value is not sufficient. #define SWIFT_DEFAULT_LLVM_CC llvm::CallingConv::C +// Pointer authentication. +#if __has_feature(ptrauth_calls) +#define SWIFT_PTRAUTH 1 +#include +#define __ptrauth_swift_runtime_function_entry \ + __ptrauth(ptrauth_key_function_pointer, 1, \ + SpecialPointerAuthDiscriminators::RuntimeFunctionEntry) +#define __ptrauth_swift_runtime_function_entry_with_key(__key) \ + __ptrauth(ptrauth_key_function_pointer, 1, __key) +#define __ptrauth_swift_runtime_function_entry_strip(__fn) \ + ptrauth_strip(__fn, ptrauth_key_function_pointer) +#define __ptrauth_swift_type_descriptor \ + __ptrauth(ptrauth_key_process_independent_data, 1, \ + SpecialPointerAuthDiscriminators::TypeDescriptor) +#define __ptrauth_swift_dynamic_replacement_key \ + __ptrauth(ptrauth_key_process_independent_data, 1, \ + SpecialPointerAuthDiscriminators::DynamicReplacementKey) +#define swift_ptrauth_sign_opaque_read_resume_function(__fn, __buffer) \ + ptrauth_auth_and_resign(__fn, ptrauth_key_function_pointer, 0, \ + ptrauth_key_process_independent_code, \ + ptrauth_blend_discriminator(__buffer, \ + SpecialPointerAuthDiscriminators::OpaqueReadResumeFunction)) +#define swift_ptrauth_sign_opaque_modify_resume_function(__fn, __buffer) \ + ptrauth_auth_and_resign(__fn, ptrauth_key_function_pointer, 0, \ + ptrauth_key_process_independent_code, \ + ptrauth_blend_discriminator(__buffer, \ + SpecialPointerAuthDiscriminators::OpaqueModifyResumeFunction)) +#else +#define SWIFT_PTRAUTH 0 +#define __ptrauth_swift_function_pointer(__typekey) +#define __ptrauth_swift_class_method_pointer(__declkey) +#define __ptrauth_swift_protocol_witness_function_pointer(__declkey) +#define __ptrauth_swift_value_witness_function_pointer(__key) +#define __ptrauth_swift_type_metadata_instantiation_function +#define __ptrauth_swift_runtime_function_entry +#define __ptrauth_swift_runtime_function_entry_with_key(__key) +#define __ptrauth_swift_runtime_function_entry_strip(__fn) (__fn) +#define __ptrauth_swift_heap_object_destructor +#define __ptrauth_swift_type_descriptor +#define __ptrauth_swift_dynamic_replacement_key +#define swift_ptrauth_sign_opaque_read_resume_function(__fn, __buffer) (__fn) +#define swift_ptrauth_sign_opaque_modify_resume_function(__fn, __buffer) (__fn) +#endif + +#ifdef __cplusplus + +/// Copy an address-discriminated signed pointer from the source to the dest. +template +SWIFT_RUNTIME_ATTRIBUTE_ALWAYS_INLINE +static inline void swift_ptrauth_copy(T *dest, const T *src, unsigned extra) { +#if SWIFT_PTRAUTH + *dest = ptrauth_auth_and_resign(*src, + ptrauth_key_function_pointer, + ptrauth_blend_discriminator(src, extra), + ptrauth_key_function_pointer, + ptrauth_blend_discriminator(dest, extra)); +#else + *dest = *src; +#endif +} + +/// Initialize the destination with an address-discriminated signed pointer. +/// This does not authenticate the source value, so be careful about how +/// you construct it. +template +SWIFT_RUNTIME_ATTRIBUTE_ALWAYS_INLINE +static inline void swift_ptrauth_init(T *dest, T value, unsigned extra) { + // FIXME: assert that T is not a function-pointer type? +#if SWIFT_PTRAUTH + *dest = ptrauth_sign_unauthenticated(value, + ptrauth_key_function_pointer, + ptrauth_blend_discriminator(dest, extra)); +#else + *dest = value; +#endif +} + +template +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); +#else + return value; +#endif +} + +#endif + #endif // SWIFT_RUNTIME_CONFIG_H diff --git a/include/swift/Runtime/InstrumentsSupport.h b/include/swift/Runtime/InstrumentsSupport.h index ba8fe52f960f2..518db303adbba 100644 --- a/include/swift/Runtime/InstrumentsSupport.h +++ b/include/swift/Runtime/InstrumentsSupport.h @@ -18,23 +18,27 @@ #ifndef SWIFT_RUNTIME_INSTRUMENTS_SUPPORT_H #define SWIFT_RUNTIME_INSTRUMENTS_SUPPORT_H +#define SWIFT_RT_DECLARE_ENTRY \ + __ptrauth_swift_runtime_function_entry + namespace swift { // liboainject patches the function pointers and calls the functions below. SWIFT_RUNTIME_EXPORT -HeapObject *(*_swift_allocObject)(HeapMetadata const *metadata, +HeapObject *(*SWIFT_RT_DECLARE_ENTRY _swift_allocObject)( + HeapMetadata const *metadata, size_t requiredSize, size_t requiredAlignmentMask); SWIFT_RUNTIME_EXPORT -HeapObject *(*_swift_retain)(HeapObject *object); +HeapObject *(*SWIFT_RT_DECLARE_ENTRY _swift_retain)(HeapObject *object); SWIFT_RUNTIME_EXPORT -HeapObject *(*_swift_retain_n)(HeapObject *object, uint32_t n); +HeapObject *(*SWIFT_RT_DECLARE_ENTRY _swift_retain_n)(HeapObject *object, uint32_t n); SWIFT_RUNTIME_EXPORT -HeapObject *(*_swift_tryRetain)(HeapObject *object); +HeapObject *(*SWIFT_RT_DECLARE_ENTRY _swift_tryRetain)(HeapObject *object); SWIFT_RUNTIME_EXPORT -void (*_swift_release)(HeapObject *object); +void (*SWIFT_RT_DECLARE_ENTRY _swift_release)(HeapObject *object); SWIFT_RUNTIME_EXPORT -void (*_swift_release_n)(HeapObject *object, uint32_t n); +void (*SWIFT_RT_DECLARE_ENTRY _swift_release_n)(HeapObject *object, uint32_t n); SWIFT_RUNTIME_EXPORT size_t swift_retainCount(HeapObject *object); diff --git a/include/swift/Runtime/Metadata.h b/include/swift/Runtime/Metadata.h index 4fcc015d4d4eb..09319d7b3a5af 100644 --- a/include/swift/Runtime/Metadata.h +++ b/include/swift/Runtime/Metadata.h @@ -97,6 +97,9 @@ struct EnumValueWitnessTable : ValueWitnessTable { #define WANT_ONLY_ENUM_VALUE_WITNESSES #define VALUE_WITNESS(LOWER_ID, UPPER_ID) \ ValueWitnessTypes::LOWER_ID LOWER_ID; +#define FUNCTION_VALUE_WITNESS(LOWER_ID, UPPER_ID, RET, PARAMS) \ + ValueWitnessTypes::LOWER_ID LOWER_ID; + #include "swift/ABI/ValueWitness.def" constexpr EnumValueWitnessTable() @@ -106,9 +109,11 @@ struct EnumValueWitnessTable : ValueWitnessTable { destructiveInjectEnumTag(nullptr) {} constexpr EnumValueWitnessTable( const ValueWitnessTable &base, - ValueWitnessTypes::getEnumTag getEnumTag, - ValueWitnessTypes::destructiveProjectEnumData destructiveProjectEnumData, - ValueWitnessTypes::destructiveInjectEnumTag destructiveInjectEnumTag) + ValueWitnessTypes::getEnumTagUnsigned getEnumTag, + ValueWitnessTypes::destructiveProjectEnumDataUnsigned + destructiveProjectEnumData, + ValueWitnessTypes::destructiveInjectEnumTagUnsigned + destructiveInjectEnumTag) : ValueWitnessTable(base), getEnumTag(getEnumTag), destructiveProjectEnumData(destructiveProjectEnumData), diff --git a/include/swift/SwiftRemoteMirror/MemoryReaderInterface.h b/include/swift/SwiftRemoteMirror/MemoryReaderInterface.h index 5dd6da9b289b2..65d383de00db8 100644 --- a/include/swift/SwiftRemoteMirror/MemoryReaderInterface.h +++ b/include/swift/SwiftRemoteMirror/MemoryReaderInterface.h @@ -86,6 +86,11 @@ typedef enum { /// bytes. DLQ_GetSizeSize, + /// The query should ignore inBuffer, and treat outBuffer as pointer-sized + /// buffer (the size of a target pointer, not a swift_addr_t) which should be + /// populated with the mask of pointer addressable bits. + DLQ_GetPtrAuthMask, + /// The query should ignore inBuffer, and treat outBuffer as uint8_t* which /// should be populated with the number of low-order bits in each pointer /// reserved by Obj-C in the remote process. This is generally zero except diff --git a/lib/AST/Builtins.cpp b/lib/AST/Builtins.cpp index c3f85c992b6d9..d1d3e27b280fa 100644 --- a/lib/AST/Builtins.cpp +++ b/lib/AST/Builtins.cpp @@ -892,6 +892,15 @@ static ValueDecl *getUnsafeGuaranteedEnd(ASTContext &C, Identifier Id) { return getBuiltinFunction(Id, { Int8Ty }, TupleType::getEmpty(C)); } +static ValueDecl *getTypePtrAuthDiscriminator(ASTContext &C, Identifier Id) { + // (T.Type) -> Int64 + BuiltinFunctionBuilder builder(C); + builder.addParameter(makeMetatype(makeGenericParam())); + Type Int64Ty = BuiltinIntegerType::get(64, C); + builder.setResult(makeConcrete(Int64Ty)); + return builder.build(Id); +} + static ValueDecl *getOnFastPath(ASTContext &Context, Identifier Id) { return getBuiltinFunction(Id, {}, TupleType::getEmpty(Context)); } @@ -2049,6 +2058,9 @@ ValueDecl *swift::getBuiltinValueDecl(ASTContext &Context, Identifier Id) { {}, TupleType::getEmpty(Context)); + case BuiltinValueKind::TypePtrAuthDiscriminator: + return getTypePtrAuthDiscriminator(Context, Id); + case BuiltinValueKind::TypeJoin: return getTypeJoinOperation(Context, Id); diff --git a/lib/Basic/LangOptions.cpp b/lib/Basic/LangOptions.cpp index 10346cb67abd3..682f6e1010c61 100644 --- a/lib/Basic/LangOptions.cpp +++ b/lib/Basic/LangOptions.cpp @@ -81,6 +81,11 @@ static const SupportedConditionalValue SupportedConditionalCompilationTargetEnvi "macCatalyst", // A synonym for "macabi" when compiling for iOS }; +static const SupportedConditionalValue SupportedConditionalCompilationPtrAuthSchemes[] = { + "_none", + "_arm64e", +}; + static const PlatformConditionKind AllPublicPlatformConditionKinds[] = { #define PLATFORM_CONDITION(LABEL, IDENTIFIER) PlatformConditionKind::LABEL, #define PLATFORM_CONDITION_(LABEL, IDENTIFIER) @@ -101,6 +106,8 @@ ArrayRef getSupportedConditionalCompilationValues(con return { }; case PlatformConditionKind::TargetEnvironment: return SupportedConditionalCompilationTargetEnvironments; + case PlatformConditionKind::PtrAuth: + return SupportedConditionalCompilationPtrAuthSchemes; } llvm_unreachable("Unhandled PlatformConditionKind in switch"); } @@ -162,6 +169,7 @@ checkPlatformConditionSupported(PlatformConditionKind Kind, StringRef Value, case PlatformConditionKind::Endianness: case PlatformConditionKind::Runtime: case PlatformConditionKind::TargetEnvironment: + case PlatformConditionKind::PtrAuth: return isMatching(Kind, Value, suggestedKind, suggestedValues); case PlatformConditionKind::CanImport: // All importable names are valid. @@ -343,6 +351,13 @@ std::pair LangOptions::setTarget(llvm::Triple triple) { addPlatformConditionValue(PlatformConditionKind::Runtime, EnableObjCInterop ? "_ObjC" : "_Native"); + // Set the pointer authentication scheme. + if (Target.getArchName() == "arm64e") { + addPlatformConditionValue(PlatformConditionKind::PtrAuth, "_arm64e"); + } else { + addPlatformConditionValue(PlatformConditionKind::PtrAuth, "_none"); + } + // Set the "targetEnvironment" platform condition if targeting a simulator // environment. Otherwise _no_ value is present for targetEnvironment; it's // an optional disambiguating refinement of the triple. @@ -359,4 +374,4 @@ std::pair LangOptions::setTarget(llvm::Triple triple) { // in the common case. return { false, false }; -} \ No newline at end of file +} diff --git a/lib/Basic/Platform.cpp b/lib/Basic/Platform.cpp index 6e9aaafc40f33..0ae286fffc297 100644 --- a/lib/Basic/Platform.cpp +++ b/lib/Basic/Platform.cpp @@ -287,6 +287,7 @@ getArchForAppleTargetSpecificModuleTriple(const llvm::Triple &triple) { // .Case ("armv7s", "armv7s") // .Case ("armv7k", "armv7k") // .Case ("armv7", "armv7") + // .Case ("arm64e", "arm64e") .Default(tripleArchName); } diff --git a/lib/ClangImporter/ClangImporter.cpp b/lib/ClangImporter/ClangImporter.cpp index 6e02778f69140..0851c4606ba24 100644 --- a/lib/ClangImporter/ClangImporter.cpp +++ b/lib/ClangImporter/ClangImporter.cpp @@ -718,9 +718,12 @@ addCommonInvocationArguments(std::vector &invocationArgStrs, } else if (triple.isOSDarwin()) { // Special case: arm64 defaults to the "cyclone" CPU for Darwin, + // and arm64e defaults to the "vortex" CPU for Darwin, // but Clang only detects this if we use -arch. - if (triple.getArch() == llvm::Triple::aarch64 || - triple.getArch() == llvm::Triple::aarch64_be) { + if (triple.getArchName() == "arm64e") + invocationArgStrs.push_back("-mcpu=vortex"); + else if (triple.getArch() == llvm::Triple::aarch64 || + triple.getArch() == llvm::Triple::aarch64_be) { invocationArgStrs.push_back("-mcpu=cyclone"); } } else if (triple.getArch() == llvm::Triple::systemz) { diff --git a/lib/IRGen/CMakeLists.txt b/lib/IRGen/CMakeLists.txt index 3c17f67add2aa..683a1ba91f145 100644 --- a/lib/IRGen/CMakeLists.txt +++ b/lib/IRGen/CMakeLists.txt @@ -27,6 +27,7 @@ add_swift_host_library(swiftIRGen STATIC GenMeta.cpp GenObjC.cpp GenOpaque.cpp + GenPointerAuth.cpp GenPoly.cpp GenProto.cpp GenReflection.cpp diff --git a/lib/IRGen/Callee.h b/lib/IRGen/Callee.h index a6e136a988657..5d134d4ac205d 100644 --- a/lib/IRGen/Callee.h +++ b/lib/IRGen/Callee.h @@ -19,16 +19,22 @@ #define SWIFT_IRGEN_CALLEE_H #include +#include "swift/AST/IRGenOptions.h" #include "llvm/IR/DerivedTypes.h" #include "swift/SIL/SILType.h" #include "IRGen.h" #include "Signature.h" +namespace llvm { + class ConstantInt; +} + namespace swift { namespace irgen { class Callee; class IRGenFunction; + class PointerAuthEntity; class CalleeInfo { public: @@ -50,31 +56,104 @@ namespace irgen { } }; + /// Information necessary for pointer authentication. + class PointerAuthInfo { + unsigned Signed : 1; + unsigned Key : 31; + llvm::Value *Discriminator; + public: + PointerAuthInfo() { + Signed = false; + } + PointerAuthInfo(unsigned key, llvm::Value *discriminator) + : Discriminator(discriminator) { + assert(discriminator->getType()->isIntegerTy() || + discriminator->getType()->isPointerTy()); + Signed = true; + Key = key; + } + + static PointerAuthInfo emit(IRGenFunction &IGF, + const PointerAuthSchema &schema, + llvm::Value *storageAddress, + const PointerAuthEntity &entity); + + static PointerAuthInfo forFunctionPointer(IRGenModule &IGM, + CanSILFunctionType fnType); + + static llvm::ConstantInt *getOtherDiscriminator(IRGenModule &IGM, + const PointerAuthSchema &schema, + const PointerAuthEntity &entity); + + explicit operator bool() const { + return isSigned(); + } + + bool isSigned() const { + return Signed; + } + + bool isConstant() const { + return (!isSigned() || isa(Discriminator)); + } + + unsigned getKey() const { + assert(isSigned()); + return Key; + } + llvm::Value *getDiscriminator() const { + assert(isSigned()); + return Discriminator; + } + + /// Are the auth infos obviously the same? + friend bool operator==(const PointerAuthInfo &lhs, + const PointerAuthInfo &rhs) { + if (!lhs.Signed) + return !rhs.Signed; + if (!rhs.Signed) + return false; + + return (lhs.Key == rhs.Key && lhs.Discriminator == rhs.Discriminator); + } + friend bool operator!=(const PointerAuthInfo &lhs, + const PointerAuthInfo &rhs) { + return !(lhs == rhs); + } + }; + /// A function pointer value. class FunctionPointer { /// The actual function pointer. llvm::Value *Value; + PointerAuthInfo AuthInfo; + Signature Sig; public: /// Construct a FunctionPointer for an arbitrary pointer value. /// We may add more arguments to this; try to use the other /// constructors/factories if possible. - explicit FunctionPointer(llvm::Value *value, const Signature &signature) - : Value(value), Sig(signature) { + explicit FunctionPointer(llvm::Value *value, PointerAuthInfo authInfo, + const Signature &signature) + : Value(value), AuthInfo(authInfo), Sig(signature) { // The function pointer should have function type. assert(value->getType()->getPointerElementType()->isFunctionTy()); // TODO: maybe assert similarity to signature.getType()? } + // Temporary only! + explicit FunctionPointer(llvm::Value *value, const Signature &signature) + : FunctionPointer(value, PointerAuthInfo(), signature) {} + static FunctionPointer forDirect(IRGenModule &IGM, llvm::Constant *value, CanSILFunctionType fnType); static FunctionPointer forDirect(llvm::Constant *value, const Signature &signature) { - return FunctionPointer(value, signature); + return FunctionPointer(value, PointerAuthInfo(), signature); } static FunctionPointer forExplosionValue(IRGenFunction &IGF, @@ -84,7 +163,7 @@ namespace irgen { /// Is this function pointer completely constant? That is, can it /// be safely moved to a different function context? bool isConstant() const { - return (isa(Value)); + return (isa(Value) && AuthInfo.isConstant()); } /// Return the actual function pointer. @@ -101,6 +180,10 @@ namespace irgen { Value->getType()->getPointerElementType()); } + const PointerAuthInfo &getAuthInfo() const { + return AuthInfo; + } + const Signature &getSignature() const { return Sig; } diff --git a/lib/IRGen/ConstantBuilder.h b/lib/IRGen/ConstantBuilder.h index 3bb9e7d1fb338..6bad070be1615 100644 --- a/lib/IRGen/ConstantBuilder.h +++ b/lib/IRGen/ConstantBuilder.h @@ -24,8 +24,13 @@ #include "IRGenModule.h" #include "IRGenFunction.h" +namespace clang { +class PointerAuthSchema; +} + namespace swift { namespace irgen { +class PointerAuthEntity; class ConstantAggregateBuilderBase; class ConstantStructBuilder; @@ -115,6 +120,15 @@ class ConstantAggregateBuilderBase llvm::ArrayType::get(IGM().Int8Ty, align.getValue() - misalignment.getValue()))); } + + using super::addSignedPointer; + void addSignedPointer(llvm::Constant *pointer, + const clang::PointerAuthSchema &schema, + const PointerAuthEntity &entity); + + void addSignedPointer(llvm::Constant *pointer, + const clang::PointerAuthSchema &schema, + uint16_t otherDiscriminator); }; class ConstantArrayBuilder diff --git a/lib/IRGen/GenBuiltin.cpp b/lib/IRGen/GenBuiltin.cpp index 0dae3c3f72bde..c0f771259286b 100644 --- a/lib/IRGen/GenBuiltin.cpp +++ b/lib/IRGen/GenBuiltin.cpp @@ -28,6 +28,7 @@ #include "Explosion.h" #include "GenCall.h" #include "GenCast.h" +#include "GenPointerAuth.h" #include "GenIntegerLiteral.h" #include "IRGenFunction.h" #include "IRGenModule.h" @@ -1020,6 +1021,17 @@ if (Builtin.ID == BuiltinValueKind::id) { \ entrypointArgs); return; } + + if (Builtin.ID == BuiltinValueKind::TypePtrAuthDiscriminator) { + (void)args.claimAll(); + Type valueTy = substitutions.getReplacementTypes()[0]; + + // The type should lower statically to a SILFunctionType. + auto loweredTy = IGF.IGM.getLoweredType(valueTy).castTo(); + + out.add(PointerAuthEntity(loweredTy).getTypeDiscriminator(IGF.IGM)); + return; + } if (Builtin.ID == BuiltinValueKind::IsSameMetatype) { auto metatypeLHS = args.claimNext(); diff --git a/lib/IRGen/GenCall.cpp b/lib/IRGen/GenCall.cpp index db623ab9f4694..9c962ce94d5e3 100644 --- a/lib/IRGen/GenCall.cpp +++ b/lib/IRGen/GenCall.cpp @@ -29,11 +29,13 @@ #include "swift/ABI/MetadataValues.h" #include "swift/Runtime/Config.h" #include "llvm/IR/CallSite.h" +#include "llvm/IR/GlobalPtrAuthInfo.h" #include "llvm/Support/Compiler.h" #include "CallEmission.h" #include "Explosion.h" #include "GenObjC.h" +#include "GenPointerAuth.h" #include "GenPoly.h" #include "GenProto.h" #include "GenType.h" @@ -1647,8 +1649,19 @@ llvm::CallSite CallEmission::emitCallSite() { llvm::CallInst *IRBuilder::CreateCall(const FunctionPointer &fn, ArrayRef args) { + SmallVector bundles; + + // Add a pointer-auth bundle if necessary. + if (const auto &authInfo = fn.getAuthInfo()) { + auto key = getInt32(authInfo.getKey()); + auto discriminator = authInfo.getDiscriminator(); + llvm::Value *bundleArgs[] = { key, discriminator }; + bundles.emplace_back("ptrauth", bundleArgs); + } + assert(!isTrapIntrinsic(fn.getPointer()) && "Use CreateNonMergeableTrap"); - llvm::CallInst *call = IRBuilderBase::CreateCall(fn.getPointer(), args); + llvm::CallInst *call = + IRBuilderBase::CreateCall(fn.getPointer(), args, bundles); call->setAttributes(fn.getAttributes()); call->setCallingConv(fn.getCallingConv()); return call; @@ -2559,6 +2572,22 @@ void irgen::emitForeignParameter(IRGenFunction &IGF, Explosion ¶ms, } } +std::pair +irgen::getCoroutineResumeFunctionPointerAuth(IRGenModule &IGM, + CanSILFunctionType fnType) { + switch (fnType->getCoroutineKind()) { + case SILCoroutineKind::None: + llvm_unreachable("not a coroutine"); + case SILCoroutineKind::YieldMany: + return { IGM.getOptions().PointerAuth.YieldManyResumeFunctions, + PointerAuthEntity::forYieldTypes(fnType) }; + case SILCoroutineKind::YieldOnce: + return { IGM.getOptions().PointerAuth.YieldOnceResumeFunctions, + PointerAuthEntity::forYieldTypes(fnType) }; + } + llvm_unreachable("bad coroutine kind"); +} + static void emitRetconCoroutineEntry(IRGenFunction &IGF, CanSILFunctionType fnType, Explosion &allParamValues, @@ -3473,7 +3502,12 @@ Callee irgen::getBlockPointerCallee(IRGenFunction &IGF, auto sig = emitCastOfFunctionPointer(IGF, invokeFnPtr, info.OrigFnType); - FunctionPointer fn(invokeFnPtr, sig); + auto &schema = IGF.getOptions().PointerAuth.BlockInvocationFunctionPointers; + auto authInfo = PointerAuthInfo::emit(IGF, schema, + invokeFnPtrAddr.getAddress(), + info.OrigFnType); + + FunctionPointer fn(invokeFnPtr, authInfo, sig); return Callee(std::move(info), fn, blockPtr); } @@ -3482,8 +3516,10 @@ Callee irgen::getSwiftFunctionPointerCallee( IRGenFunction &IGF, llvm::Value *fnPtr, llvm::Value *dataPtr, CalleeInfo &&calleeInfo, bool castOpaqueToRefcountedContext) { auto sig = emitCastOfFunctionPointer(IGF, fnPtr, calleeInfo.OrigFnType); + auto authInfo = + PointerAuthInfo::forFunctionPointer(IGF.IGM, calleeInfo.OrigFnType); - FunctionPointer fn(fnPtr, sig); + FunctionPointer fn(fnPtr, authInfo, sig); if (castOpaqueToRefcountedContext) { assert(dataPtr && dataPtr->getType() == IGF.IGM.OpaquePtrTy && "Expecting trivial closure context"); @@ -3496,8 +3532,10 @@ Callee irgen::getCFunctionPointerCallee(IRGenFunction &IGF, llvm::Value *fnPtr, CalleeInfo &&calleeInfo) { auto sig = emitCastOfFunctionPointer(IGF, fnPtr, calleeInfo.OrigFnType); + auto authInfo = + PointerAuthInfo::forFunctionPointer(IGF.IGM, calleeInfo.OrigFnType); - FunctionPointer fn(fnPtr, sig); + FunctionPointer fn(fnPtr, authInfo, sig); return Callee(std::move(calleeInfo), fn); } @@ -3514,16 +3552,24 @@ FunctionPointer::forExplosionValue(IRGenFunction &IGF, llvm::Value *fnPtr, // Bitcast out of an opaque pointer type. assert(fnPtr->getType() == IGF.IGM.Int8PtrTy); auto sig = emitCastOfFunctionPointer(IGF, fnPtr, fnType); + auto authInfo = PointerAuthInfo::forFunctionPointer(IGF.IGM, fnType); - return FunctionPointer(fnPtr, sig); + return FunctionPointer(fnPtr, authInfo, sig); } llvm::Value * FunctionPointer::getExplosionValue(IRGenFunction &IGF, CanSILFunctionType fnType) const { + llvm::Value *fnPtr = getPointer(); + + // Re-sign to the appropriate schema for this function pointer type. + auto resultAuthInfo = PointerAuthInfo::forFunctionPointer(IGF.IGM, fnType); + if (getAuthInfo() != resultAuthInfo) { + fnPtr = emitPointerAuthResign(IGF, fnPtr, getAuthInfo(), resultAuthInfo); + } + // Bitcast to an opaque pointer type. - llvm::Value *fnPtr = - IGF.Builder.CreateBitCast(getPointer(), IGF.IGM.Int8PtrTy); + fnPtr = IGF.Builder.CreateBitCast(fnPtr, IGF.IGM.Int8PtrTy); return fnPtr; } diff --git a/lib/IRGen/GenClass.cpp b/lib/IRGen/GenClass.cpp index a80fe7cbb7048..e57de5c373a49 100644 --- a/lib/IRGen/GenClass.cpp +++ b/lib/IRGen/GenClass.cpp @@ -46,6 +46,7 @@ #include "GenFunc.h" #include "GenMeta.h" #include "GenObjC.h" +#include "GenPointerAuth.h" #include "GenProto.h" #include "GenType.h" #include "IRGenDebugInfo.h" @@ -1377,9 +1378,12 @@ namespace { if (hasUpdater) { // Class _Nullable (*metadataUpdateCallback)(Class _Nonnull cls, // void * _Nullable arg); - b.add(IGM.getAddrOfObjCMetadataUpdateFunction( + auto *impl = IGM.getAddrOfObjCMetadataUpdateFunction( TheEntity.get(), - NotForDefinition)); + NotForDefinition); + const auto &schema = + IGM.getOptions().PointerAuth.ObjCMethodListFunctionPointers; + b.addSignedPointer(impl, schema, PointerAuthEntity()); } // }; @@ -2441,7 +2445,11 @@ FunctionPointer irgen::emitVirtualMethodValue(IRGenFunction &IGF, IGF.IGM.getPointerAlignment()); auto fnPtr = IGF.emitInvariantLoad(slot); - return FunctionPointer(fnPtr, signature); + auto &schema = IGF.getOptions().PointerAuth.SwiftClassMethods; + auto authInfo = + PointerAuthInfo::emit(IGF, schema, slot.getAddress(), method); + + return FunctionPointer(fnPtr, authInfo, signature); } FunctionPointer diff --git a/lib/IRGen/GenDecl.cpp b/lib/IRGen/GenDecl.cpp index 53c97d5d197fe..44a464db43560 100644 --- a/lib/IRGen/GenDecl.cpp +++ b/lib/IRGen/GenDecl.cpp @@ -60,6 +60,7 @@ #include "GenMeta.h" #include "GenObjC.h" #include "GenOpaque.h" +#include "GenPointerAuth.h" #include "GenProto.h" #include "GenType.h" #include "IRGenDebugInfo.h" @@ -1463,6 +1464,22 @@ static llvm::GlobalVariable *getChainEntryForDynamicReplacement( auto *funPtr = implFunction ? llvm::ConstantExpr::getBitCast(implFunction, IGM.Int8PtrTy) : llvm::ConstantExpr::getNullValue(IGM.Int8PtrTy); + + if (implFunction) { + llvm::Constant *indices[] = {llvm::ConstantInt::get(IGM.Int32Ty, 0), + llvm::ConstantInt::get(IGM.Int32Ty, 0)}; + auto *storageAddr = llvm::ConstantExpr::getInBoundsGetElementPtr( + nullptr, linkEntry, indices); + + auto &schema = IGM.getOptions().PointerAuth.SwiftDynamicReplacements; + assert(entity.hasSILFunction() || entity.isOpaqueTypeDescriptorAccessor()); + auto authEntity = entity.hasSILFunction() + ? PointerAuthEntity(entity.getSILFunction()) + : PointerAuthEntity::Special::TypeDescriptor; + funPtr = + IGM.getConstantSignedPointer(funPtr, schema, authEntity, storageAddr); + } + auto *nextEntry = llvm::ConstantExpr::getNullValue(IGM.DynamicReplacementLinkEntryPtrTy); llvm::Constant *fields[] = {funPtr, nextEntry}; @@ -2312,7 +2329,17 @@ static llvm::GlobalVariable *createGlobalForDynamicReplacementFunctionKey( ConstantInitBuilder builder(IGM); auto B = builder.beginStruct(IGM.DynamicReplacementKeyTy); B.addRelativeAddress(linkEntry); - B.addInt32(0); + auto schema = IGM.getOptions().PointerAuth.SwiftDynamicReplacements; + if (schema) { + assert(keyEntity.hasSILFunction() || + keyEntity.isOpaqueTypeDescriptorAccessor()); + auto authEntity = keyEntity.hasSILFunction() + ? PointerAuthEntity(keyEntity.getSILFunction()) + : PointerAuthEntity::Special::TypeDescriptor; + B.addInt32(PointerAuthInfo::getOtherDiscriminator(IGM, schema, authEntity) + ->getZExtValue()); + } else + B.addInt32(0); B.finishAndSetAsInitializer(key); key->setConstant(true); IGM.setTrueConstGlobal(key); @@ -2352,20 +2379,25 @@ void IRGenModule::createReplaceableProlog(IRGenFunction &IGF, SILFunction *f) { auto *FnAddr = llvm::ConstantExpr::getPointerBitCastOrAddrSpaceCast( IGF.CurFn, FunctionPtrTy); - llvm::Value *ReplFn = nullptr, *rhs = nullptr; + auto &schema = getOptions().PointerAuth.SwiftDynamicReplacements; + llvm::Value *ReplFn = nullptr, *hasReplFn = nullptr; if (UseBasicDynamicReplacement) { ReplFn = IGF.Builder.CreateLoad(fnPtrAddr, getPointerAlignment()); - rhs = FnAddr; + llvm::Value *lhs = ReplFn; + if (schema.isEnabled()) { + lhs = emitPointerAuthStrip(IGF, lhs, schema.getKey()); + } + hasReplFn = IGF.Builder.CreateICmpEQ(lhs, FnAddr); } else { // Call swift_getFunctionReplacement to check which function to call. auto *callRTFunc = IGF.Builder.CreateCall(getGetReplacementFn(), {ReplAddr, FnAddr}); callRTFunc->setDoesNotThrow(); ReplFn = callRTFunc; - rhs = llvm::ConstantExpr::getNullValue(ReplFn->getType()); + hasReplFn = IGF.Builder.CreateICmpEQ(ReplFn, + llvm::ConstantExpr::getNullValue(ReplFn->getType())); } - auto *hasReplFn = IGF.Builder.CreateICmpEQ(ReplFn, rhs); auto *replacedBB = IGF.createBasicBlock("forward_to_replaced"); auto *origEntryBB = IGF.createBasicBlock("original_entry"); @@ -2380,7 +2412,11 @@ void IRGenModule::createReplaceableProlog(IRGenFunction &IGF, SILFunction *f) { auto *fnType = signature.getType()->getPointerTo(); auto *realReplFn = IGF.Builder.CreateBitCast(ReplFn, fnType); - auto *Res = IGF.Builder.CreateCall(FunctionPointer(realReplFn, signature), + auto authEntity = PointerAuthEntity(f); + auto authInfo = PointerAuthInfo::emit(IGF, schema, fnPtrAddr, authEntity); + + auto *Res = IGF.Builder.CreateCall(FunctionPointer(realReplFn, authInfo, + signature), forwardedArgs); Res->setTailCall(); if (IGF.CurFn->getReturnType()->isVoidTy()) @@ -2417,16 +2453,26 @@ static void emitDynamicallyReplaceableThunk(IRGenModule &IGM, IGM.DebugInfo->emitArtificialFunction(IGF, dispatchFn); llvm::Constant *indices[] = {llvm::ConstantInt::get(IGM.Int32Ty, 0), llvm::ConstantInt::get(IGM.Int32Ty, 0)}; - auto *fnPtr = IGF.Builder.CreateLoad( - llvm::ConstantExpr::getInBoundsGetElementPtr(nullptr, linkEntry, indices), - IGM.getPointerAlignment()); - auto *typeFnPtr = - IGF.Builder.CreateBitOrPointerCast(fnPtr, implFn->getType()); + + auto *fnPtrAddr = + llvm::ConstantExpr::getInBoundsGetElementPtr(nullptr, linkEntry, indices); + auto *fnPtr = IGF.Builder.CreateLoad(fnPtrAddr, IGM.getPointerAlignment()); + auto *typeFnPtr = IGF.Builder.CreateBitOrPointerCast(fnPtr, implFn->getType()); + SmallVector forwardedArgs; for (auto &arg : dispatchFn->args()) forwardedArgs.push_back(&arg); - auto *Res = IGF.Builder.CreateCall(FunctionPointer(typeFnPtr, signature), - forwardedArgs); + + auto &schema = IGM.getOptions().PointerAuth.SwiftDynamicReplacements; + assert(keyEntity.hasSILFunction() || + keyEntity.isOpaqueTypeDescriptorAccessor()); + auto authEntity = keyEntity.hasSILFunction() + ? PointerAuthEntity(keyEntity.getSILFunction()) + : PointerAuthEntity::Special::TypeDescriptor; + auto authInfo = PointerAuthInfo::emit(IGF, schema, fnPtrAddr, authEntity); + auto *Res = IGF.Builder.CreateCall( + FunctionPointer(typeFnPtr, authInfo, signature), forwardedArgs); + Res->setTailCall(); if (implFn->getReturnType()->isVoidTy()) IGF.Builder.CreateRetVoid(); @@ -2535,8 +2581,13 @@ void IRGenModule::emitDynamicReplacementOriginalFunctionThunk(SILFunction *f) { SmallVector forwardedArgs; for (auto &arg : implFn->args()) forwardedArgs.push_back(&arg); - auto *Res = IGF.Builder.CreateCall(FunctionPointer(typeFnPtr, signature), - forwardedArgs); + + auto &schema = getOptions().PointerAuth.SwiftDynamicReplacements; + auto authInfo = PointerAuthInfo::emit( + IGF, schema, fnPtrAddr, + PointerAuthEntity(f->getDynamicallyReplacedFunction())); + auto *Res = IGF.Builder.CreateCall( + FunctionPointer(typeFnPtr, authInfo, signature), forwardedArgs); if (implFn->getReturnType()->isVoidTy()) IGF.Builder.CreateRetVoid(); @@ -2677,6 +2728,28 @@ static llvm::GlobalVariable *createGOTEquivalent(IRGenModule &IGM, .to(gotEquivalent); } + // Context descriptor pointers need to be signed. + // TODO: We should really sign a pointer to *any* code entity or true-const + // metadata structure that may reference data structures with function + // pointers inside them. + if (entity.isContextDescriptor()) { + auto schema = IGM.getOptions().PointerAuth.TypeDescriptors; + if (schema) { + auto signedValue = IGM.getConstantSignedPointer( + global, schema, PointerAuthEntity::Special::TypeDescriptor, + /*storageAddress*/ gotEquivalent); + gotEquivalent->setInitializer(signedValue); + } + } else if (entity.isDynamicallyReplaceableKey()) { + auto schema = IGM.getOptions().PointerAuth.SwiftDynamicReplacementKeys; + if (schema) { + auto signedValue = IGM.getConstantSignedPointer( + global, schema, PointerAuthEntity::Special::DynamicReplacementKey, + /*storageAddress*/ gotEquivalent); + gotEquivalent->setInitializer(signedValue); + } + } + return gotEquivalent; } diff --git a/lib/IRGen/GenFunc.cpp b/lib/IRGen/GenFunc.cpp index ae5fa16b7e15a..5888b9b65a874 100644 --- a/lib/IRGen/GenFunc.cpp +++ b/lib/IRGen/GenFunc.cpp @@ -100,6 +100,7 @@ #include "GenHeap.h" #include "GenMeta.h" #include "GenObjC.h" +#include "GenPointerAuth.h" #include "GenPoly.h" #include "GenProto.h" #include "GenType.h" @@ -962,6 +963,8 @@ static llvm::Function *emitPartialApplicationForwarder(IRGenModule &IGM, SILFunctionTypeRepresentation::WitnessMethod; Explosion witnessMethodSelfValue; + llvm::Value *lastCapturedFieldPtr = nullptr; + // If there's a data pointer required, but it's a swift-retainable // value being passed as the context, just forward it down. if (!layout) { @@ -1055,6 +1058,7 @@ static llvm::Function *emitPartialApplicationForwarder(IRGenModule &IGM, Address fieldAddr = fieldLayout.project(subIGF, data, offsets); auto &fieldTI = fieldLayout.getType(); auto fieldSchema = fieldTI.getSchema(); + lastCapturedFieldPtr = fieldAddr.getAddress(); Explosion param; switch (fieldConvention) { @@ -1173,7 +1177,13 @@ static llvm::Function *emitPartialApplicationForwarder(IRGenModule &IGM, // It comes out of the context as an i8*. Cast to the function type. fnPtr = subIGF.Builder.CreateBitCast(fnPtr, fnTy); - return FunctionPointer(fnPtr, origSig); + assert(lastCapturedFieldPtr); + auto authInfo = PointerAuthInfo::emit(subIGF, + IGM.getOptions().PointerAuth.PartialApplyCapture, + lastCapturedFieldPtr, + PointerAuthEntity::Special::PartialApplyCapture); + + return FunctionPointer(fnPtr, authInfo, origSig); }(); // Derive the context argument if needed. This is either: @@ -1416,6 +1426,8 @@ Optional irgen::emitFunctionPartialApplication( singleRefcountedConvention = origType->getCalleeConvention(); } } + + auto outAuthInfo = PointerAuthInfo::forFunctionPointer(IGF.IGM, outType); // If we have a single refcounted pointer context (and no polymorphic args // to capture), and the dest ownership semantics match the parameter's, @@ -1430,7 +1442,7 @@ Optional irgen::emitFunctionPartialApplication( hasSingleSwiftRefcountedContext == Yes && outType->getCalleeConvention() == *singleRefcountedConvention) { assert(args.size() == 1); - auto fnPtr = fn.getPointer(); + auto fnPtr = emitPointerAuthResign(IGF, fn, outAuthInfo).getPointer(); fnPtr = IGF.Builder.CreateBitCast(fnPtr, IGF.IGM.Int8PtrTy); out.add(fnPtr); llvm::Value *ctx = args.claimNext(); @@ -1469,6 +1481,7 @@ Optional irgen::emitFunctionPartialApplication( emitPartialApplicationForwarder(IGF.IGM, staticFn, fnContext != nullptr, origSig, origType, substType, outType, subs, nullptr, argConventions); + forwarder = emitPointerAuthSign(IGF, forwarder, outAuthInfo); forwarder = IGF.Builder.CreateBitCast(forwarder, IGF.IGM.Int8PtrTy); out.add(forwarder); @@ -1543,7 +1556,15 @@ Optional irgen::emitFunctionPartialApplication( // We don't add non-constant function pointers to the explosion above, // so we need to handle them specially now. if (i == nonStaticFnIndex) { - llvm::Value *fnPtr = fn.getPointer(); + llvm::Value *fnPtr; + if (auto &schema = IGF.getOptions().PointerAuth.PartialApplyCapture) { + auto schemaAuthInfo = + PointerAuthInfo::emit(IGF, schema, fieldAddr.getAddress(), + PointerAuthEntity::Special::PartialApplyCapture); + fnPtr = emitPointerAuthResign(IGF, fn, schemaAuthInfo).getPointer(); + } else { + fnPtr = fn.getPointer(); + } fnPtr = IGF.Builder.CreateBitCast(fnPtr, IGF.IGM.Int8PtrTy); IGF.Builder.CreateStore(fnPtr, fieldAddr); continue; @@ -1586,6 +1607,7 @@ Optional irgen::emitFunctionPartialApplication( subs, &layout, argConventions); + forwarder = emitPointerAuthSign(IGF, forwarder, outAuthInfo); forwarder = IGF.Builder.CreateBitCast(forwarder, IGF.IGM.Int8PtrTy); out.add(forwarder); out.add(data); @@ -1706,8 +1728,8 @@ void irgen::emitBlockHeader(IRGenFunction &IGF, // Collect the reserved and invoke pointer fields. auto reserved = llvm::ConstantInt::get(IGF.IGM.Int32Ty, 0); - auto invokeVal = llvm::ConstantExpr::getBitCast(invokeFunction, - IGF.IGM.FunctionPtrTy); + llvm::Value *invokeVal = llvm::ConstantExpr::getBitCast(invokeFunction, + IGF.IGM.FunctionPtrTy); // Build the block descriptor. ConstantInitBuilder builder(IGF.IGM); @@ -1723,8 +1745,14 @@ void irgen::emitBlockHeader(IRGenFunction &IGF, if (!isPOD) { // Define the copy and dispose helpers. - descriptorFields.add(emitBlockCopyHelper(IGF.IGM, blockTy, storageTL)); - descriptorFields.add(emitBlockDisposeHelper(IGF.IGM, blockTy, storageTL)); + descriptorFields.addSignedPointer( + emitBlockCopyHelper(IGF.IGM, blockTy, storageTL), + IGF.getOptions().PointerAuth.BlockHelperFunctionPointers, + PointerAuthEntity::Special::BlockCopyHelper); + descriptorFields.addSignedPointer( + emitBlockDisposeHelper(IGF.IGM, blockTy, storageTL), + IGF.getOptions().PointerAuth.BlockHelperFunctionPointers, + PointerAuthEntity::Special::BlockDisposeHelper); } // Build the descriptor signature. @@ -1747,8 +1775,17 @@ void irgen::emitBlockHeader(IRGenFunction &IGF, IGF.Builder.CreateStructGEP(headerAddr, 1, layout)); IGF.Builder.CreateStore(reserved, IGF.Builder.CreateStructGEP(headerAddr, 2, layout)); - IGF.Builder.CreateStore(invokeVal, - IGF.Builder.CreateStructGEP(headerAddr, 3, layout)); + + auto invokeAddr = IGF.Builder.CreateStructGEP(headerAddr, 3, layout); + if (auto &schema = + IGF.getOptions().PointerAuth.BlockInvocationFunctionPointers) { + auto invokeAuthInfo = PointerAuthInfo::emit(IGF, schema, + invokeAddr.getAddress(), + invokeTy); + invokeVal = emitPointerAuthSign(IGF, invokeVal, invokeAuthInfo); + } + IGF.Builder.CreateStore(invokeVal, invokeAddr); + IGF.Builder.CreateStore(descriptorVal, IGF.Builder.CreateStructGEP(headerAddr, 4, layout)); } diff --git a/lib/IRGen/GenHeap.cpp b/lib/IRGen/GenHeap.cpp index 4c0f5e96a2983..e871a7505299f 100644 --- a/lib/IRGen/GenHeap.cpp +++ b/lib/IRGen/GenHeap.cpp @@ -33,6 +33,7 @@ #include "ConstantBuilder.h" #include "Explosion.h" #include "GenClass.h" +#include "GenPointerAuth.h" #include "GenProto.h" #include "GenType.h" #include "IRGenDebugInfo.h" @@ -481,7 +482,8 @@ static llvm::Constant *buildPrivateMetadata(IRGenModule &IGM, ConstantInitBuilder builder(IGM); auto fields = builder.beginStruct(IGM.FullBoxMetadataStructTy); - fields.add(dtorFn); + fields.addSignedPointer(dtorFn, IGM.getOptions().PointerAuth.HeapDestructors, + PointerAuthEntity::Special::HeapDestructor); fields.addNullPointer(IGM.WitnessTablePtrTy); { auto kindStruct = fields.beginStruct(IGM.TypeMetadataStructTy); diff --git a/lib/IRGen/GenKeyPath.cpp b/lib/IRGen/GenKeyPath.cpp index 0e1cc81dc6ea9..a0b04d13269dd 100644 --- a/lib/IRGen/GenKeyPath.cpp +++ b/lib/IRGen/GenKeyPath.cpp @@ -22,6 +22,7 @@ #include "GenClass.h" #include "GenDecl.h" #include "GenMeta.h" +#include "GenPointerAuth.h" #include "GenProto.h" #include "GenStruct.h" #include "GenTuple.h" @@ -362,12 +363,11 @@ getWitnessTableForComputedComponent(IRGenModule &IGM, isTrivial &= ti.isPOD(ResilienceExpansion::Minimal); } - llvm::Constant *destroy; + llvm::Constant *destroy = nullptr; llvm::Constant *copy; if (isTrivial) { // We can use prefab witnesses for handling trivial copying and destruction. // A null destructor witness signals that the payload is trivial. - destroy = llvm::ConstantPointerNull::get(IGM.Int8PtrTy); copy = IGM.getCopyKeyPathTrivialIndicesFn(); } else { // Generate a destructor for this set of indices. @@ -500,12 +500,23 @@ getWitnessTableForComputedComponent(IRGenModule &IGM, genericEnv, requirements, !component.getSubscriptIndices().empty()); - auto witnesses = llvm::ConstantStruct::getAnon({destroy, copy, equals, hash}); - return new llvm::GlobalVariable(IGM.Module, witnesses->getType(), - /*constant*/ true, - llvm::GlobalValue::PrivateLinkage, - witnesses, - "keypath_witnesses"); + ConstantInitBuilder builder(IGM); + ConstantStructBuilder fields = builder.beginStruct(); + auto schemaKeyPath = IGM.getOptions().PointerAuth.KeyPaths; + if (destroy) + fields.addSignedPointer(destroy, schemaKeyPath, + PointerAuthEntity::Special::KeyPathDestroy); + else + fields.addNullPointer(IGM.FunctionPtrTy); + fields.addSignedPointer(copy, schemaKeyPath, + PointerAuthEntity::Special::KeyPathCopy); + fields.addSignedPointer(equals, schemaKeyPath, + PointerAuthEntity::Special::KeyPathEquals); + fields.addSignedPointer(hash, schemaKeyPath, + PointerAuthEntity::Special::KeyPathHash); + return fields.finishAndCreateGlobal( + "keypath_witnesses", IGM.getPointerAlignment(), /*constant*/ true, + llvm::GlobalVariable::PrivateLinkage); } /// Information about each index operand for a key path pattern that is used @@ -885,9 +896,10 @@ emitKeyPathComponent(IRGenModule &IGM, // Encode the settability. bool settable = kind == KeyPathPatternComponent::Kind::SettableProperty; + bool mutating = settable && component.isComputedSettablePropertyMutating(); KeyPathComponentHeader::ComputedPropertyKind componentKind; if (settable) { - componentKind = component.isComputedSettablePropertyMutating() + componentKind = mutating ? KeyPathComponentHeader::SettableMutating : KeyPathComponentHeader::SettableNonmutating; } else { @@ -902,6 +914,7 @@ emitKeyPathComponent(IRGenModule &IGM, switch (id.getKind()) { case KeyPathPatternComponent::ComputedPropertyId::Function: { idKind = KeyPathComponentHeader::Pointer; + // FIXME: Does this need to be signed? auto idRef = IGM.getAddrOfLLVMVariableOrGOTEquivalent( LinkEntity::forSILFunction(id.getFunction(), false)); diff --git a/lib/IRGen/GenMeta.cpp b/lib/IRGen/GenMeta.cpp index 9bb2799b9ff6c..ff16667e20450 100644 --- a/lib/IRGen/GenMeta.cpp +++ b/lib/IRGen/GenMeta.cpp @@ -51,6 +51,7 @@ #include "GenArchetype.h" #include "GenClass.h" #include "GenDecl.h" +#include "GenPointerAuth.h" #include "GenPoly.h" #include "GenStruct.h" #include "GenValueWitness.h" @@ -87,11 +88,13 @@ static Address emitAddressOfMetadataSlotAtIndex(IRGenFunction &IGF, /// Emit a load from the given metadata at a constant index. static llvm::LoadInst *emitLoadFromMetadataAtIndex(IRGenFunction &IGF, llvm::Value *metadata, + llvm::Value **slotPtr, int index, llvm::Type *objectTy, const llvm::Twine &suffix = "") { Address slot = emitAddressOfMetadataSlotAtIndex(IGF, metadata, index, objectTy); + if (slotPtr) *slotPtr = slot.getAddress(); // Load. return IGF.Builder.CreateLoad(slot, metadata->getName() + suffix); @@ -686,6 +689,11 @@ namespace { if (entry.isAssociatedType()) { auto flags = Flags(Flags::Kind::AssociatedTypeAccessFunction); + if (auto &schema = IGM.getOptions().PointerAuth + .ProtocolAssociatedTypeAccessFunctions) { + addDiscriminator(flags, schema, + AssociatedType(entry.getAssociatedType())); + } // Look for a default witness. llvm::Constant *defaultImpl = @@ -696,6 +704,13 @@ namespace { if (entry.isAssociatedConformance()) { auto flags = Flags(Flags::Kind::AssociatedConformanceAccessFunction); + if (auto &schema = IGM.getOptions().PointerAuth + .ProtocolAssociatedTypeWitnessTableAccessFunctions) { + addDiscriminator(flags, schema, + AssociatedConformance(Proto, + entry.getAssociatedConformancePath(), + entry.getAssociatedConformanceRequirement())); + } // Look for a default witness. llvm::Constant *defaultImpl = @@ -716,12 +731,29 @@ namespace { // Classify the function. auto flags = getMethodDescriptorFlags(func.getDecl()); + if (auto &schema = IGM.getOptions().PointerAuth.ProtocolWitnesses) { + SILDeclRef declRef(func.getDecl(), + isa(func.getDecl()) + ? SILDeclRef::Kind::Allocator + : SILDeclRef::Kind::Func); + addDiscriminator(flags, schema, declRef); + } + // Look for a default witness. llvm::Constant *defaultImpl = findDefaultWitness(func); return { flags, defaultImpl }; } + void addDiscriminator(ProtocolRequirementFlags &flags, + const PointerAuthSchema &schema, + const PointerAuthEntity &entity) { + assert(schema); + auto discriminator = + PointerAuthInfo::getOtherDiscriminator(IGM, schema, entity); + flags = flags.withExtraDiscriminator(discriminator->getZExtValue()); + } + void addRequirements() { auto &pi = IGM.getProtocolInfo(Proto, ProtocolInfoKind::Full); @@ -1522,6 +1554,13 @@ namespace { if (func->isObjCDynamic()) flags = flags.withIsDynamic(true); + // Include the pointer-auth discriminator. + if (auto &schema = IGM.getOptions().PointerAuth.SwiftClassMethods) { + auto discriminator = + PointerAuthInfo::getOtherDiscriminator(IGM, schema, fn); + flags = flags.withExtraDiscriminator(discriminator->getZExtValue()); + } + // TODO: final? open? descriptor.addInt(IGM.Int32Ty, flags.getIntValue()); @@ -2740,7 +2779,9 @@ namespace { void addDestructorFunction() { if (auto ptr = getAddrOfDestructorFunction(IGM, Target)) { - B.add(*ptr); + B.addSignedPointer(*ptr, + IGM.getOptions().PointerAuth.HeapDestructors, + PointerAuthEntity::Special::HeapDestructor); } else { // In case the optimizer removed the function. See comment in // addMethod(). @@ -2754,7 +2795,9 @@ namespace { /*isForeign=*/ false, NotForDefinition); if (dtorFunc) { - B.add(*dtorFunc); + B.addSignedPointer(*dtorFunc, + IGM.getOptions().PointerAuth.HeapDestructors, + PointerAuthEntity::Special::HeapDestructor); } else { B.addNullPointer(IGM.FunctionPtrTy); } @@ -2765,7 +2808,9 @@ namespace { } void addNominalTypeDescriptor() { - B.add(emitNominalTypeDescriptor()); + B.addSignedPointer(emitNominalTypeDescriptor(), + IGM.getOptions().PointerAuth.TypeDescriptors, + PointerAuthEntity::Special::TypeDescriptor); } bool canBeConstant() { @@ -2850,14 +2895,19 @@ namespace { auto entry = VTable->getEntry(IGM.getSILModule(), fn); // The class is fragile. Emit a direct reference to the vtable entry. + llvm::Constant *ptr; if (entry) { - B.add(IGM.getAddrOfSILFunction(entry->Implementation, NotForDefinition)); - return; + ptr = IGM.getAddrOfSILFunction(entry->Implementation, + NotForDefinition); + } else { + // The method is removed by dead method elimination. + // It should be never called. We add a pointer to an error function. + ptr = llvm::ConstantExpr::getBitCast(IGM.getDeletedMethodErrorFn(), + IGM.FunctionPtrTy); } - // The method is removed by dead method elimination. - // It should be never called. We add a pointer to an error function. - B.addBitCast(IGM.getDeletedMethodErrorFn(), IGM.FunctionPtrTy); + auto &schema = IGM.getOptions().PointerAuth.SwiftClassMethods; + B.addSignedPointer(ptr, schema, fn); } void addPlaceholder(MissingMemberDecl *m) { @@ -3198,6 +3248,15 @@ namespace { llvm::Value *descriptor, llvm::Value *arguments, llvm::Value *templatePointer) { + // Sign the descriptor. + auto schema = IGF.IGM.getOptions().PointerAuth.TypeDescriptorsAsArguments; + if (schema) { + auto authInfo = PointerAuthInfo::emit( + IGF, schema, nullptr, + PointerAuthEntity::Special::TypeDescriptorAsArgument); + descriptor = emitPointerAuthSign(IGF, descriptor, authInfo); + } + auto metadata = IGF.Builder.CreateCall(IGM.getAllocateGenericClassMetadataFn(), {descriptor, arguments, templatePointer}); @@ -3378,11 +3437,12 @@ void IRGenFunction::setDereferenceableLoad(llvm::LoadInst *load, static llvm::LoadInst * emitInvariantLoadFromMetadataAtIndex(IRGenFunction &IGF, llvm::Value *metadata, + llvm::Value **slotPtr, int index, llvm::Type *objectTy, const Twine &suffix = Twine::createNull()) { - auto result = emitLoadFromMetadataAtIndex(IGF, metadata, index, objectTy, - suffix); + auto result = emitLoadFromMetadataAtIndex(IGF, metadata, slotPtr, + index, objectTy, suffix); IGF.setInvariantLoad(result); return result; } @@ -3390,8 +3450,8 @@ emitInvariantLoadFromMetadataAtIndex(IRGenFunction &IGF, /// Given a type metadata pointer, load its value witness table. llvm::Value * IRGenFunction::emitValueWitnessTableRefForMetadata(llvm::Value *metadata) { - auto witness = emitInvariantLoadFromMetadataAtIndex(*this, metadata, -1, - IGM.WitnessTablePtrTy, + auto witness = emitInvariantLoadFromMetadataAtIndex(*this, metadata, nullptr, + -1, IGM.WitnessTablePtrTy, ".valueWitnesses"); // A value witness table is dereferenceable to the number of value witness // pointers. @@ -3520,7 +3580,10 @@ namespace { } void addNominalTypeDescriptor() { - B.add(asImpl().getNominalTypeDescriptor()); + auto descriptor = asImpl().getNominalTypeDescriptor(); + B.addSignedPointer(descriptor, + IGM.getOptions().PointerAuth.TypeDescriptors, + PointerAuthEntity::Special::TypeDescriptor); } ConstantReference emitValueWitnessTable(bool relativeReference) { @@ -3637,6 +3700,15 @@ namespace { - IGM.getOffsetOfStructTypeSpecificMetadataMembers(); auto extraSizeV = IGM.getSize(extraSize); + // Sign the descriptor. + auto schema = IGF.IGM.getOptions().PointerAuth.TypeDescriptorsAsArguments; + if (schema) { + auto authInfo = PointerAuthInfo::emit( + IGF, schema, nullptr, + PointerAuthEntity::Special::TypeDescriptorAsArgument); + descriptor = emitPointerAuthSign(IGF, descriptor, authInfo); + } + return IGF.Builder.CreateCall(IGM.getAllocateGenericValueMetadataFn(), {descriptor, arguments, templatePointer, extraSizeV}); @@ -3968,7 +4040,9 @@ namespace { } void addNominalTypeDescriptor() { - B.add(asImpl().getNominalTypeDescriptor()); + B.addSignedPointer(asImpl().getNominalTypeDescriptor(), + IGM.getOptions().PointerAuth.TypeDescriptors, + PointerAuthEntity::Special::TypeDescriptor); } void addGenericArgument(GenericRequirement requirement) { @@ -4083,6 +4157,15 @@ namespace { - IGM.getOffsetOfEnumTypeSpecificMetadataMembers(); auto extraSizeV = IGM.getSize(extraSize); + // Sign the descriptor. + auto schema = IGF.IGM.getOptions().PointerAuth.TypeDescriptorsAsArguments; + if (schema) { + auto authInfo = PointerAuthInfo::emit( + IGF, schema, nullptr, + PointerAuthEntity::Special::TypeDescriptorAsArgument); + descriptor = emitPointerAuthSign(IGF, descriptor, authInfo); + } + auto metadata = IGF.Builder.CreateCall(IGM.getAllocateGenericValueMetadataFn(), {descriptor, arguments, templatePointer, @@ -4356,7 +4439,9 @@ namespace { void addNominalTypeDescriptor() { auto descriptor = ClassContextDescriptorBuilder(this->IGM, Target, RequireMetadata).emit(); - B.add(descriptor); + B.addSignedPointer(descriptor, + IGM.getOptions().PointerAuth.TypeDescriptors, + PointerAuthEntity::Special::TypeDescriptor); } void addSuperclass() { @@ -4706,7 +4791,7 @@ llvm::Value *irgen::emitMetatypeInstanceType(IRGenFunction &IGF, llvm::Value *metatypeMetadata) { // The instance type field of MetatypeMetadata is immediately after // the isa field. - return emitInvariantLoadFromMetadataAtIndex(IGF, metatypeMetadata, 1, + return emitInvariantLoadFromMetadataAtIndex(IGF, metatypeMetadata, nullptr, 1, IGF.IGM.TypeMetadataPtrTy); } diff --git a/lib/IRGen/GenObjC.cpp b/lib/IRGen/GenObjC.cpp index cb719840d5549..0cc9795325e10 100644 --- a/lib/IRGen/GenObjC.cpp +++ b/lib/IRGen/GenObjC.cpp @@ -41,6 +41,7 @@ #include "GenClass.h" #include "GenFunc.h" #include "GenHeap.h" +#include "GenPointerAuth.h" #include "GenProto.h" #include "GenType.h" #include "HeapTypeInfo.h" @@ -898,17 +899,19 @@ void irgen::emitObjCPartialApplication(IRGenFunction &IGF, fieldType, false); // Create the forwarding stub. - llvm::Function *forwarder = emitObjCPartialApplicationForwarder(IGF.IGM, + llvm::Value *forwarder = emitObjCPartialApplicationForwarder(IGF.IGM, method, origMethodType, resultType, layout, selfType); - llvm::Value *forwarderValue = IGF.Builder.CreateBitCast(forwarder, - IGF.IGM.Int8PtrTy); - + forwarder = + IGF.IGM.getConstantSignedFunctionPointer(cast(forwarder), + resultType); + forwarder = IGF.Builder.CreateBitCast(forwarder, IGF.IGM.Int8PtrTy); + // Emit the result explosion. - out.add(forwarderValue); + out.add(forwarder); out.add(data); } @@ -1283,25 +1286,32 @@ irgen::emitObjCSetterDescriptorParts(IRGenModule &IGM, llvm_unreachable("unknown storage!"); } -static void buildMethodDescriptor(ConstantArrayBuilder &descriptors, +static void buildMethodDescriptor(IRGenModule &IGM, + ConstantArrayBuilder &descriptors, ObjCMethodDescriptor &parts) { auto descriptor = descriptors.beginStruct(); descriptor.add(parts.selectorRef); descriptor.add(parts.typeEncoding); - descriptor.add(parts.impl); + if (parts.impl->isNullValue()) { + descriptor.add(parts.impl); + } else { + descriptor.addSignedPointer(parts.impl, + IGM.getOptions().PointerAuth.ObjCMethodListFunctionPointers, + PointerAuthEntity()); + } descriptor.finishAndAddTo(descriptors); } static void emitObjCDescriptor(IRGenModule &IGM, ConstantArrayBuilder &descriptors, ObjCMethodDescriptor &descriptor) { - buildMethodDescriptor(descriptors, descriptor); + buildMethodDescriptor(IGM, descriptors, descriptor); auto *silFn = descriptor.silFunction; if (silFn && silFn->hasObjCReplacement()) { auto replacedSelector = IGM.getAddrOfObjCMethodName(silFn->getObjCReplacement().str()); descriptor.selectorRef = replacedSelector; - buildMethodDescriptor(descriptors, descriptor); + buildMethodDescriptor(IGM, descriptors, descriptor); } } @@ -1346,7 +1356,7 @@ void irgen::emitObjCIVarInitDestroyDescriptor(IRGenModule &IGM, descriptor.impl = llvm::ConstantExpr::getBitCast(objcImpl, IGM.Int8PtrTy); // Form the method_t instance. - buildMethodDescriptor(descriptors, descriptor); + buildMethodDescriptor(IGM, descriptors, descriptor); } llvm::Constant * diff --git a/lib/IRGen/GenOpaque.cpp b/lib/IRGen/GenOpaque.cpp index c8c34e891ebcd..25d2635b1c195 100644 --- a/lib/IRGen/GenOpaque.cpp +++ b/lib/IRGen/GenOpaque.cpp @@ -31,6 +31,7 @@ #include "Callee.h" #include "Explosion.h" #include "FixedTypeInfo.h" +#include "GenPointerAuth.h" #include "IRGenFunction.h" #include "IRGenModule.h" #include "ProtocolInfo.h" @@ -312,7 +313,8 @@ llvm::PointerType *IRGenModule::getEnumValueWitnessTablePtrTy() { /// always an i8*. llvm::Value *irgen::emitInvariantLoadOfOpaqueWitness(IRGenFunction &IGF, llvm::Value *table, - WitnessIndex index) { + WitnessIndex index, + llvm::Value **slotPtr) { assert(table->getType() == IGF.IGM.WitnessTablePtrTy); // GEP to the appropriate index, avoiding spurious IR in the trivial case. @@ -321,6 +323,8 @@ llvm::Value *irgen::emitInvariantLoadOfOpaqueWitness(IRGenFunction &IGF, slot = IGF.Builder.CreateConstInBoundsGEP1_32( /*Ty=*/nullptr, table, index.getValue()); + if (slotPtr) *slotPtr = slot; + auto witness = IGF.Builder.CreateLoad(Address(slot, IGF.IGM.getPointerAlignment())); IGF.setInvariantLoad(witness); @@ -331,12 +335,15 @@ llvm::Value *irgen::emitInvariantLoadOfOpaqueWitness(IRGenFunction &IGF, /// always an i8*. llvm::Value *irgen::emitInvariantLoadOfOpaqueWitness(IRGenFunction &IGF, llvm::Value *table, - llvm::Value *index) { + llvm::Value *index, + llvm::Value **slotPtr) { assert(table->getType() == IGF.IGM.WitnessTablePtrTy); // GEP to the appropriate index. llvm::Value *slot = IGF.Builder.CreateInBoundsGEP(table, index); + if (slotPtr) *slotPtr = slot; + auto witness = IGF.Builder.CreateLoad(Address(slot, IGF.IGM.getPointerAlignment())); IGF.setInvariantLoad(witness); @@ -396,7 +403,6 @@ static FunctionPointer emitLoadOfValueWitnessFunction(IRGenFunction &IGF, llvm::Value *table, ValueWitness index) { assert(isValueWitnessFunction(index)); - WitnessIndex windex = [&] { unsigned i = unsigned(index); if (i > unsigned(ValueWitness::Flags)) { @@ -412,14 +418,20 @@ static FunctionPointer emitLoadOfValueWitnessFunction(IRGenFunction &IGF, return WitnessIndex(i, false); }(); - llvm::Value *witness = emitInvariantLoadOfOpaqueWitness(IGF, table, windex); + llvm::Value *slot; + llvm::Value *witness = + emitInvariantLoadOfOpaqueWitness(IGF, table, windex, &slot); auto label = getValueWitnessLabel(index); auto signature = IGF.IGM.getValueWitnessSignature(index); auto type = signature.getType()->getPointerTo(); witness = IGF.Builder.CreateBitCast(witness, type, label); - return FunctionPointer(witness, signature); + auto authInfo = PointerAuthInfo::emit(IGF, + IGF.getOptions().PointerAuth.ValueWitnesses, + slot, index); + + return FunctionPointer(witness, authInfo, signature); } /// Given a type metadata pointer, load one of the function @@ -457,12 +469,26 @@ IRGenFunction::emitValueWitnessFunctionRef(SILType type, if (auto witness = tryGetLocalTypeDataForLayout(type, key)) { metadataSlot = emitTypeMetadataRefForLayout(type); auto signature = IGM.getValueWitnessSignature(index); - return FunctionPointer(witness, signature); + PointerAuthInfo authInfo; + if (auto &schema = getOptions().PointerAuth.ValueWitnesses) { + auto discriminator = + tryGetLocalTypeDataForLayout(type, + LocalTypeDataKind::forValueWitnessDiscriminator(index)); + assert(discriminator && "no saved discriminator for value witness fn!"); + authInfo = PointerAuthInfo(schema.getKey(), discriminator); + } + return FunctionPointer(witness, authInfo, signature); } auto vwtable = emitValueWitnessTableRef(type, &metadataSlot); auto witness = emitLoadOfValueWitnessFunction(*this, vwtable, index); setScopedLocalTypeDataForLayout(type, key, witness.getPointer()); + if (auto &authInfo = witness.getAuthInfo()) { + setScopedLocalTypeDataForLayout(type, + LocalTypeDataKind::forValueWitnessDiscriminator(index), + authInfo.getDiscriminator()); + } + return witness; } @@ -1287,6 +1313,8 @@ irgen::emitGetEnumTagSinglePayloadGenericCall(IRGenFunction &IGF, auto getExtraInhabitantTagFn = getOrCreateGetExtraInhabitantTagFunction(IGF.IGM, payloadType, payloadTI, emitter); + getExtraInhabitantTagFn = + IGF.IGM.getConstantSignedCFunctionPointer(getExtraInhabitantTagFn); // We assume this is never a reabstracted type. auto type = payloadType.getASTType(); @@ -1359,6 +1387,8 @@ irgen::emitStoreEnumTagSinglePayloadGenericCall(IRGenFunction &IGF, auto storeExtraInhabitantTagFn = getOrCreateStoreExtraInhabitantTagFunction(IGF.IGM, payloadType, payloadTI, emitter); + storeExtraInhabitantTagFn = + IGF.IGM.getConstantSignedCFunctionPointer(storeExtraInhabitantTagFn); // We assume this is never a reabstracted type. auto type = payloadType.getASTType(); diff --git a/lib/IRGen/GenOpaque.h b/lib/IRGen/GenOpaque.h index ea7733e662aab..d1421098d42bb 100644 --- a/lib/IRGen/GenOpaque.h +++ b/lib/IRGen/GenOpaque.h @@ -45,7 +45,8 @@ namespace irgen { /// the referenced witness table is still undergoing initialization. llvm::Value *emitInvariantLoadOfOpaqueWitness(IRGenFunction &IGF, llvm::Value *table, - WitnessIndex index); + WitnessIndex index, + llvm::Value **slot = nullptr); /// Given a witness table (protocol or value), load one of the /// witnesses. @@ -54,7 +55,8 @@ namespace irgen { /// the referenced witness table is still undergoing initialization. llvm::Value *emitInvariantLoadOfOpaqueWitness(IRGenFunction &IGF, llvm::Value *table, - llvm::Value *index); + llvm::Value *index, + llvm::Value **slot = nullptr); /// Emit a call to do an 'initializeBufferWithCopyOfBuffer' operation. llvm::Value *emitInitializeBufferWithCopyOfBufferCall(IRGenFunction &IGF, diff --git a/lib/IRGen/GenPointerAuth.cpp b/lib/IRGen/GenPointerAuth.cpp new file mode 100644 index 0000000000000..4506c6a63810b --- /dev/null +++ b/lib/IRGen/GenPointerAuth.cpp @@ -0,0 +1,690 @@ +//===--- GenPointerAuth.cpp - IRGen for pointer authentication ------------===// +// +// This source file is part of the Swift.org open source project +// +// Copyright (c) 2014 - 2017 Apple Inc. and the Swift project authors +// Licensed under Apache License v2.0 with Runtime Library Exception +// +// See https://swift.org/LICENSE.txt for license information +// See https://swift.org/CONTRIBUTORS.txt for the list of Swift project authors +// +//===----------------------------------------------------------------------===// +// +// This file implements general support for pointer authentication in Swift. +// +//===----------------------------------------------------------------------===// + +#include "GenPointerAuth.h" +#include "Callee.h" +#include "ConstantBuilder.h" +#include "GenType.h" +#include "IRGenFunction.h" +#include "IRGenMangler.h" +#include "IRGenModule.h" +#include "swift/AST/GenericEnvironment.h" +#include "swift/SIL/TypeLowering.h" +#include "clang/CodeGen/CodeGenABITypes.h" +#include "llvm/ADT/APInt.h" +#include "llvm/Support/raw_ostream.h" + +using namespace swift; +using namespace irgen; + +/**************************** INTRINSIC OPERATIONS ****************************/ + +/// Return the key and discriminator value for the given auth info, +/// as demanded by the ptrauth intrinsics. +static std::pair +getPointerAuthPair(IRGenFunction &IGF, const PointerAuthInfo &authInfo) { + auto key = llvm::ConstantInt::get(IGF.IGM.Int32Ty, authInfo.getKey()); + llvm::Value *discriminator = authInfo.getDiscriminator(); + if (discriminator->getType()->isPointerTy()) { + discriminator = IGF.Builder.CreatePtrToInt(discriminator, IGF.IGM.IntPtrTy); + } + return { key, discriminator }; +} + +llvm::Value *irgen::emitPointerAuthBlend(IRGenFunction &IGF, + llvm::Value *address, + llvm::Value *other) { + address = IGF.Builder.CreatePtrToInt(address, IGF.IGM.IntPtrTy); + auto intrinsic = + llvm::Intrinsic::getDeclaration(&IGF.IGM.Module, + llvm::Intrinsic::ptrauth_blend, + { IGF.IGM.IntPtrTy }); + return IGF.Builder.CreateCall(intrinsic, {address, other}); +} + +llvm::Value *irgen::emitPointerAuthStrip(IRGenFunction &IGF, + llvm::Value *fnPtr, + unsigned Key) { + auto fnVal = IGF.Builder.CreatePtrToInt(fnPtr, IGF.IGM.IntPtrTy); + auto keyArg = llvm::ConstantInt::get(IGF.IGM.Int32Ty, Key); + auto intrinsic = + llvm::Intrinsic::getDeclaration(&IGF.IGM.Module, + llvm::Intrinsic::ptrauth_strip, + { IGF.IGM.IntPtrTy }); + auto strippedPtr = IGF.Builder.CreateCall(intrinsic, {fnVal, keyArg}); + return IGF.Builder.CreateIntToPtr(strippedPtr, fnPtr->getType()); +} + +FunctionPointer irgen::emitPointerAuthResign(IRGenFunction &IGF, + const FunctionPointer &fn, + const PointerAuthInfo &newAuthInfo) { + llvm::Value *fnPtr = emitPointerAuthResign(IGF, fn.getPointer(), + fn.getAuthInfo(), newAuthInfo); + return FunctionPointer(fnPtr, newAuthInfo, fn.getSignature()); +} + +llvm::Value *irgen::emitPointerAuthResign(IRGenFunction &IGF, + llvm::Value *fnPtr, + const PointerAuthInfo &oldAuthInfo, + const PointerAuthInfo &newAuthInfo) { + // If the signatures match, there's nothing to do. + if (oldAuthInfo == newAuthInfo) + return fnPtr; + + // If the pointer is not currently signed, sign it. + if (!oldAuthInfo.isSigned()) { + return emitPointerAuthSign(IGF, fnPtr, newAuthInfo); + } + + // If the pointer is not supposed to be signed, auth it. + if (!newAuthInfo.isSigned()) { + return emitPointerAuthAuth(IGF, fnPtr, oldAuthInfo); + } + + // Otherwise, auth and resign it. + auto origTy = fnPtr->getType(); + fnPtr = IGF.Builder.CreatePtrToInt(fnPtr, IGF.IGM.IntPtrTy); + + auto oldPair = getPointerAuthPair(IGF, oldAuthInfo); + auto newPair = getPointerAuthPair(IGF, newAuthInfo); + + auto intrinsic = + llvm::Intrinsic::getDeclaration(&IGF.IGM.Module, + llvm::Intrinsic::ptrauth_resign, + { IGF.IGM.IntPtrTy }); + llvm::Value *args[] = { + fnPtr, oldPair.first, oldPair.second, newPair.first, newPair.second + }; + fnPtr = IGF.Builder.CreateCall(intrinsic, args); + return IGF.Builder.CreateIntToPtr(fnPtr, origTy); +} + +llvm::Value *irgen::emitPointerAuthAuth(IRGenFunction &IGF, llvm::Value *fnPtr, + const PointerAuthInfo &oldAuthInfo) { + auto origTy = fnPtr->getType(); + fnPtr = IGF.Builder.CreatePtrToInt(fnPtr, IGF.IGM.IntPtrTy); + + auto oldPair = getPointerAuthPair(IGF, oldAuthInfo); + + auto intrinsic = + llvm::Intrinsic::getDeclaration(&IGF.IGM.Module, + llvm::Intrinsic::ptrauth_auth, + { IGF.IGM.IntPtrTy }); + llvm::Value *args[] = { + fnPtr, oldPair.first, oldPair.second + }; + fnPtr = IGF.Builder.CreateCall(intrinsic, args); + return IGF.Builder.CreateIntToPtr(fnPtr, origTy); +} + +llvm::Value *irgen::emitPointerAuthSign(IRGenFunction &IGF, llvm::Value *fnPtr, + const PointerAuthInfo &newAuthInfo) { + if (!newAuthInfo.isSigned()) + return fnPtr; + + // Special-case constants. + if (auto constantFnPtr = dyn_cast(fnPtr)) { + if (auto constantDiscriminator = + dyn_cast(newAuthInfo.getDiscriminator())) { + llvm::Constant *other = nullptr, *address = nullptr; + if (constantDiscriminator->getType()->isPointerTy()) + address = constantDiscriminator; + else + other = constantDiscriminator; + return IGF.IGM.getConstantSignedPointer(constantFnPtr, + newAuthInfo.getKey(), + address, other); + } + } + + auto origTy = fnPtr->getType(); + fnPtr = IGF.Builder.CreatePtrToInt(fnPtr, IGF.IGM.IntPtrTy); + + auto newPair = getPointerAuthPair(IGF, newAuthInfo); + + auto intrinsic = + llvm::Intrinsic::getDeclaration(&IGF.IGM.Module, + llvm::Intrinsic::ptrauth_sign, + { IGF.IGM.IntPtrTy }); + llvm::Value *args[] = { + fnPtr, newPair.first, newPair.second + }; + fnPtr = IGF.Builder.CreateCall(intrinsic, args); + return IGF.Builder.CreateIntToPtr(fnPtr, origTy); +} + +/******************************* DISCRIMINATORS *******************************/ + +struct IRGenModule::PointerAuthCachesType { + llvm::DenseMap Decls; + llvm::DenseMap Types; + llvm::DenseMap YieldTypes; + llvm::DenseMap AssociatedTypes; + llvm::DenseMap AssociatedConformances; +}; + +IRGenModule::PointerAuthCachesType &IRGenModule::getPointerAuthCaches() { + if (!PointerAuthCaches) + PointerAuthCaches = new PointerAuthCachesType(); + return *PointerAuthCaches; +} + +void IRGenModule::destroyPointerAuthCaches() { + delete PointerAuthCaches; +} + +static const PointerAuthSchema &getFunctionPointerSchema(IRGenModule &IGM, + CanSILFunctionType fnType) { + auto &options = IGM.getOptions().PointerAuth; + switch (fnType->getRepresentation()) { + case SILFunctionTypeRepresentation::CFunctionPointer: + return options.FunctionPointers; + + case SILFunctionTypeRepresentation::Thin: + case SILFunctionTypeRepresentation::Thick: + case SILFunctionTypeRepresentation::Method: + case SILFunctionTypeRepresentation::WitnessMethod: + case SILFunctionTypeRepresentation::Closure: + return options.SwiftFunctionPointers; + + case SILFunctionTypeRepresentation::ObjCMethod: + case SILFunctionTypeRepresentation::Block: + llvm_unreachable("not just a function pointer"); + } + llvm_unreachable("bad representation"); +} + +PointerAuthInfo PointerAuthInfo::forFunctionPointer(IRGenModule &IGM, + CanSILFunctionType fnType) { + auto &schema = getFunctionPointerSchema(IGM, fnType); + + // If the target doesn't sign function pointers, we're done. + if (!schema) return PointerAuthInfo(); + + assert(!schema.isAddressDiscriminated() && + "function pointer cannot be address-discriminated"); + + auto discriminator = getOtherDiscriminator(IGM, schema, fnType); + return PointerAuthInfo(schema.getKey(), discriminator); +} + +PointerAuthInfo PointerAuthInfo::emit(IRGenFunction &IGF, + const PointerAuthSchema &schema, + llvm::Value *storageAddress, + const PointerAuthEntity &entity) { + if (!schema) return PointerAuthInfo(); + + unsigned key = schema.getKey(); + + // Produce the 'other' discriminator. + auto otherDiscriminator = getOtherDiscriminator(IGF.IGM, schema, entity); + llvm::Value *discriminator = otherDiscriminator; + + // Factor in the address. + if (schema.isAddressDiscriminated()) { + assert(storageAddress && + "no storage address for address-discriminated schema"); + + if (!otherDiscriminator->isZero()) { + discriminator = emitPointerAuthBlend(IGF, storageAddress, discriminator); + } else { + discriminator = + IGF.Builder.CreatePtrToInt(storageAddress, IGF.IGM.IntPtrTy); + } + } + + return PointerAuthInfo(key, discriminator); +} + +llvm::ConstantInt * +PointerAuthInfo::getOtherDiscriminator(IRGenModule &IGM, + const PointerAuthSchema &schema, + const PointerAuthEntity &entity) { + assert(schema); + switch (schema.getOtherDiscrimination()) { + case PointerAuthSchema::Discrimination::None: + return llvm::ConstantInt::get(IGM.IntPtrTy, 0); + + case PointerAuthSchema::Discrimination::Decl: + return entity.getDeclDiscriminator(IGM); + + case PointerAuthSchema::Discrimination::Type: + return entity.getTypeDiscriminator(IGM); + + case PointerAuthSchema::Discrimination::Constant: + return llvm::ConstantInt::get(IGM.IntPtrTy, + schema.getConstantDiscrimination()); + } + llvm_unreachable("bad kind"); +} + +static llvm::ConstantInt *getDiscriminatorForHash(IRGenModule &IGM, + uint64_t rawHash) { + uint16_t reducedHash = (rawHash % 0xFFFF) + 1; + return IGM.getSize(Size(reducedHash)); +} + +static llvm::ConstantInt *getDiscriminatorForString(IRGenModule &IGM, + StringRef string) { + uint64_t rawHash = clang::CodeGen::computeStableStringHash(string); + return getDiscriminatorForHash(IGM, rawHash); +} + +static std::string mangle(AssociatedType association) { + return IRGenMangler() + .mangleAssociatedTypeAccessFunctionDiscriminator(association); +} + +static std::string mangle(const AssociatedConformance &association) { + return IRGenMangler() + .mangleAssociatedTypeWitnessTableAccessFunctionDiscriminator(association); +} + +llvm::ConstantInt * +PointerAuthEntity::getDeclDiscriminator(IRGenModule &IGM) const { + switch (StoredKind) { + case Kind::None: + case Kind::CanSILFunctionType: + case Kind::CoroutineYieldTypes: + llvm_unreachable("no declaration for schema using decl discrimination"); + + case Kind::Special: { + auto getSpecialDiscriminator = [](Special special) -> uint16_t { + switch (special) { + case Special::HeapDestructor: + return SpecialPointerAuthDiscriminators::HeapDestructor; + case Special::TypeDescriptor: + case Special::TypeDescriptorAsArgument: + return SpecialPointerAuthDiscriminators::TypeDescriptor; + case Special::PartialApplyCapture: + return PointerAuthDiscriminator_PartialApplyCapture; + case Special::KeyPathDestroy: + return SpecialPointerAuthDiscriminators::KeyPathDestroy; + case Special::KeyPathCopy: + return SpecialPointerAuthDiscriminators::KeyPathCopy; + case Special::KeyPathEquals: + return SpecialPointerAuthDiscriminators::KeyPathEquals; + case Special::KeyPathHash: + return SpecialPointerAuthDiscriminators::KeyPathHash; + case Special::KeyPathGetter: + return SpecialPointerAuthDiscriminators::KeyPathGetter; + case Special::KeyPathNonmutatingSetter: + return SpecialPointerAuthDiscriminators::KeyPathNonmutatingSetter; + case Special::KeyPathMutatingSetter: + return SpecialPointerAuthDiscriminators::KeyPathMutatingSetter; + case Special::KeyPathGetLayout: + return SpecialPointerAuthDiscriminators::KeyPathGetLayout; + case Special::KeyPathInitializer: + return SpecialPointerAuthDiscriminators::KeyPathInitializer; + case Special::KeyPathMetadataAccessor: + return SpecialPointerAuthDiscriminators::KeyPathMetadataAccessor; + case Special::DynamicReplacementKey: + return SpecialPointerAuthDiscriminators::DynamicReplacementKey; + case Special::BlockCopyHelper: + case Special::BlockDisposeHelper: + llvm_unreachable("no known discriminator for these foreign entities"); + } + llvm_unreachable("bad kind"); + }; + auto specialKind = Storage.get(StoredKind); + return IGM.getSize(Size(getSpecialDiscriminator(specialKind))); + } + + case Kind::ValueWitness: { + auto getValueWitnessDiscriminator = [](ValueWitness witness) -> uint16_t { + switch (witness) { +#define WANT_ALL_VALUE_WITNESSES +#define DATA_VALUE_WITNESS(LOWER, UPPER, TYPE) +#define FUNCTION_VALUE_WITNESS(LOWER, ID, RET, PARAMS) \ + case ValueWitness::ID: return SpecialPointerAuthDiscriminators::ID; +#include "swift/ABI/ValueWitness.def" + case ValueWitness::Size: + case ValueWitness::Flags: + case ValueWitness::Stride: + case ValueWitness::ExtraInhabitantCount: + llvm_unreachable("not a function value witness"); + } + llvm_unreachable("bad kind"); + }; + auto witness = Storage.get(StoredKind); + return IGM.getSize(Size(getValueWitnessDiscriminator(witness))); + } + + case Kind::AssociatedType: { + auto association = Storage.get(StoredKind); + llvm::ConstantInt *&cache = + IGM.getPointerAuthCaches().AssociatedTypes[association]; + if (cache) return cache; + + auto mangling = mangle(association); + cache = getDiscriminatorForString(IGM, mangling); + return cache; + } + + case Kind::AssociatedConformance: { + auto conformance = Storage.get(StoredKind); + llvm::ConstantInt *&cache = + IGM.getPointerAuthCaches().AssociatedConformances[conformance]; + if (cache) return cache; + + auto mangling = mangle(conformance); + cache = getDiscriminatorForString(IGM, mangling); + return cache; + } + + case Kind::SILDeclRef: { + auto constant = Storage.get(StoredKind); + llvm::ConstantInt *&cache = IGM.getPointerAuthCaches().Decls[constant]; + if (cache) return cache; + + // Getting the discriminator for a foreign SILDeclRef just means + // converting it to a foreign declaration and asking Clang IRGen + // for the corresponding discriminator, but that's not completely + // trivial. + assert(!constant.isForeign && + "discriminator for foreign declaration not supported yet!"); + + auto mangling = constant.mangle(); + cache = getDiscriminatorForString(IGM, mangling); + return cache; + } + case Kind::SILFunction: { + auto fn = Storage.get(StoredKind); + return getDiscriminatorForString(IGM, fn->getName()); + } + } + llvm_unreachable("bad kind"); +} + +static void hashStringForFunctionType(IRGenModule &IGM, CanSILFunctionType type, + raw_ostream &Out, + GenericEnvironment *genericEnv); + +static void hashStringForType(IRGenModule &IGM, CanType Ty, raw_ostream &Out, + GenericEnvironment *genericEnv) { + if (Ty->isAnyClassReferenceType()) { + // Any class type has to be hashed opaquely. + Out << "-class"; + } else if (isa(Ty)) { + // Any metatype has to be hashed opaquely. + Out << "-metatype"; + } else if (auto UnwrappedTy = Ty->getOptionalObjectType()) { + if (UnwrappedTy->isBridgeableObjectType()) { + // Optional is compatible with T when T is class-based. + hashStringForType(IGM, UnwrappedTy->getCanonicalType(), Out, genericEnv); + } else if (UnwrappedTy->is()) { + // Optional is compatible with T when T is a metatype. + hashStringForType(IGM, UnwrappedTy->getCanonicalType(), Out, genericEnv); + } else { + // Optional is direct if and only if T is. + Out << "Optional<"; + hashStringForType(IGM, UnwrappedTy->getCanonicalType(), Out, genericEnv); + Out << ">"; + } + } else if (auto GTy = dyn_cast(Ty)) { + // For generic and non-generic value types, use the mangled declaration + // name, and ignore all generic arguments. + NominalTypeDecl *nominal = cast(GTy->getDecl()); + Out << Mangle::ASTMangler().mangleNominalType(nominal); + } else if (auto FTy = dyn_cast(Ty)) { + Out << "("; + hashStringForFunctionType(IGM, FTy, Out, genericEnv); + Out << ")"; + } else { + Out << "-"; + } +} + +template +static void hashStringForList(IRGenModule &IGM, const ArrayRef &list, + raw_ostream &Out, GenericEnvironment *genericEnv, + const SILFunctionType *fnType) { + for (auto paramOrRetVal : list) { + if (paramOrRetVal.isFormalIndirect()) { + // Indirect params and return values have to be opaque. + Out << "-indirect"; + } else { + CanType Ty = paramOrRetVal.getArgumentType(IGM.getSILModule(), fnType); + if (Ty->hasTypeParameter()) + Ty = genericEnv->mapTypeIntoContext(Ty)->getCanonicalType(); + hashStringForType(IGM, Ty, Out, genericEnv); + } + Out << ":"; + } +} + +static void hashStringForList(IRGenModule &IGM, + const ArrayRef &list, + raw_ostream &Out, GenericEnvironment *genericEnv, + const SILFunctionType *fnType) { + for (auto paramOrRetVal : list) { + if (paramOrRetVal.isFormalIndirect()) { + // Indirect params and return values have to be opaque. + Out << "-indirect"; + } else { + CanType Ty = paramOrRetVal.getReturnValueType(IGM.getSILModule(), fnType); + if (Ty->hasTypeParameter()) + Ty = genericEnv->mapTypeIntoContext(Ty)->getCanonicalType(); + hashStringForType(IGM, Ty, Out, genericEnv); + } + Out << ":"; + } +} + +static void hashStringForFunctionType(IRGenModule &IGM, CanSILFunctionType type, + raw_ostream &Out, + GenericEnvironment *genericEnv) { + Out << (type->isCoroutine() ? "coroutine" : "function") << ":"; + Out << type->getNumParameters() << ":"; + hashStringForList(IGM, type->getParameters(), Out, genericEnv, type); + Out << type->getNumResults() << ":"; + hashStringForList(IGM, type->getResults(), Out, genericEnv, type); + if (type->isCoroutine()) { + Out << type->getNumYields() << ":"; + hashStringForList(IGM, type->getYields(), Out, genericEnv, type); + } +} + +static uint64_t getTypeHash(IRGenModule &IGM, CanSILFunctionType type) { + // The hash we need to do here ignores: + // - thickness, so that we can promote thin-to-thick without rehashing; + // - error results, so that we can promote nonthrowing-to-throwing + // without rehashing; + // - types of indirect arguments/retvals, so they can be substituted freely; + // - types of class arguments/retvals + // - types of metatype arguments/retvals + // See isABICompatibleWith and areABICompatibleParamsOrReturns in + // SILFunctionType.cpp. + + SmallString<32> Buffer; + llvm::raw_svector_ostream Out(Buffer); + auto genericSig = type->getInvocationGenericSignature(); + hashStringForFunctionType( + IGM, type, Out, + genericSig ? genericSig->getCanonicalSignature()->getGenericEnvironment() + : nullptr); + return clang::CodeGen::computeStableStringHash(Out.str()); +} + +static uint64_t getYieldTypesHash(IRGenModule &IGM, CanSILFunctionType type) { + SmallString<32> buffer; + llvm::raw_svector_ostream out(buffer); + auto genericSig = type->getInvocationGenericSignature(); + GenericEnvironment *genericEnv = + genericSig ? genericSig->getCanonicalSignature()->getGenericEnvironment() + : nullptr; + + out << [&]() -> StringRef { + switch (type->getCoroutineKind()) { + case SILCoroutineKind::YieldMany: return "yield_many:"; + case SILCoroutineKind::YieldOnce: return "yield_once:"; + case SILCoroutineKind::None: llvm_unreachable("not a coroutine"); + } + llvm_unreachable("bad coroutine kind"); + }(); + + out << type->getNumYields() << ":"; + + for (auto yield: type->getYields()) { + // We can't mangle types on inout and indirect yields because they're + // absractable. + if (yield.isIndirectInOut()) { + out << "inout"; + } else if (yield.isFormalIndirect()) { + out << "indirect"; + } else { + CanType Ty = yield.getArgumentType(IGM.getSILModule(), type); + if (Ty->hasTypeParameter()) + Ty = genericEnv->mapTypeIntoContext(Ty)->getCanonicalType(); + hashStringForType(IGM, Ty, out, genericEnv); + } + out << ":"; + } + + return clang::CodeGen::computeStableStringHash(out.str()); +} + +llvm::ConstantInt * +PointerAuthEntity::getTypeDiscriminator(IRGenModule &IGM) const { + auto getTypeDiscriminator = [&](CanSILFunctionType fnType) { + switch (fnType->getRepresentation()) { + // Swift function types are type-discriminated. + case SILFunctionTypeRepresentation::Thick: + case SILFunctionTypeRepresentation::Thin: + case SILFunctionTypeRepresentation::Method: + case SILFunctionTypeRepresentation::WitnessMethod: + case SILFunctionTypeRepresentation::Closure: { + llvm::ConstantInt *&cache = IGM.getPointerAuthCaches().Types[fnType]; + if (cache) return cache; + + auto hash = getTypeHash(IGM, fnType); + cache = getDiscriminatorForHash(IGM, hash); + return cache; + } + + // C function pointers are undiscriminated. + case SILFunctionTypeRepresentation::CFunctionPointer: + return llvm::ConstantInt::get(IGM.Int64Ty, 0); + + case SILFunctionTypeRepresentation::ObjCMethod: + case SILFunctionTypeRepresentation::Block: { + llvm_unreachable("not type discriminated"); + } + } + }; + + auto getCoroutineYieldTypesDiscriminator = [&](CanSILFunctionType fnType) { + llvm::ConstantInt *&cache = IGM.getPointerAuthCaches().Types[fnType]; + if (cache) return cache; + + auto hash = getYieldTypesHash(IGM, fnType); + cache = getDiscriminatorForHash(IGM, hash); + return cache; + }; + + switch (StoredKind) { + case Kind::None: + case Kind::Special: + case Kind::ValueWitness: + case Kind::AssociatedType: + case Kind::AssociatedConformance: + case Kind::SILFunction: + llvm_unreachable("no type for schema using type discriminiation"); + + case Kind::CoroutineYieldTypes: { + auto fnType = Storage.get(StoredKind); + return getCoroutineYieldTypesDiscriminator(fnType); + } + + case Kind::CanSILFunctionType: { + auto fnType = Storage.get(StoredKind); + return getTypeDiscriminator(fnType); + } + + case Kind::SILDeclRef: { + SILDeclRef decl = Storage.get(StoredKind); + auto fnType = IGM.getSILTypes().getConstantFunctionType( + TypeExpansionContext::minimal(), decl); + return getTypeDiscriminator(fnType); + } + } + llvm_unreachable("bad kind"); +} + +llvm::Constant * +IRGenModule::getConstantSignedFunctionPointer(llvm::Constant *fn, + CanSILFunctionType fnType) { + if (auto &schema = getFunctionPointerSchema(*this, fnType)) { + return getConstantSignedPointer(fn, schema, fnType, nullptr); + } + return fn; +} + +llvm::Constant * +IRGenModule::getConstantSignedCFunctionPointer(llvm::Constant *fn) { + if (auto &schema = getOptions().PointerAuth.FunctionPointers) { + assert(!schema.hasOtherDiscrimination()); + return getConstantSignedPointer(fn, schema, PointerAuthEntity(), nullptr); + } + return fn; +} + +llvm::Constant *IRGenModule::getConstantSignedPointer(llvm::Constant *pointer, + unsigned key, + llvm::Constant *storageAddress, + llvm::Constant *otherDiscriminator) { + return clang::CodeGen::getConstantSignedPointer(getClangCGM(), pointer, key, + storageAddress, + otherDiscriminator); +} + +llvm::Constant *IRGenModule::getConstantSignedPointer(llvm::Constant *pointer, + const PointerAuthSchema &schema, + const PointerAuthEntity &entity, + llvm::Constant *storageAddress) { + // If the schema doesn't sign pointers, do nothing. + if (!schema) + return pointer; + + auto otherDiscriminator = + PointerAuthInfo::getOtherDiscriminator(*this, schema, entity); + return getConstantSignedPointer(pointer, schema.getKey(), storageAddress, + otherDiscriminator); +} + +void ConstantAggregateBuilderBase::addSignedPointer(llvm::Constant *pointer, + const PointerAuthSchema &schema, + const PointerAuthEntity &entity) { + // If the schema doesn't sign pointers, do nothing. + if (!schema) + return add(pointer); + + auto otherDiscriminator = + PointerAuthInfo::getOtherDiscriminator(IGM(), schema, entity); + addSignedPointer(pointer, schema.getKey(), schema.isAddressDiscriminated(), + otherDiscriminator); +} + +void ConstantAggregateBuilderBase::addSignedPointer(llvm::Constant *pointer, + const PointerAuthSchema &schema, + uint16_t otherDiscriminator) { + // If the schema doesn't sign pointers, do nothing. + if (!schema) + return add(pointer); + + addSignedPointer(pointer, schema.getKey(), schema.isAddressDiscriminated(), + llvm::ConstantInt::get(IGM().IntPtrTy, otherDiscriminator)); +} diff --git a/lib/IRGen/GenPointerAuth.h b/lib/IRGen/GenPointerAuth.h new file mode 100644 index 0000000000000..c30e4daf50668 --- /dev/null +++ b/lib/IRGen/GenPointerAuth.h @@ -0,0 +1,206 @@ +//===--- GenPointerAuth.h - IRGen for pointer authentication ----*- C++ -*-===// +// +// This source file is part of the Swift.org open source project +// +// Copyright (c) 2014 - 2017 Apple Inc. and the Swift project authors +// Licensed under Apache License v2.0 with Runtime Library Exception +// +// See https://swift.org/LICENSE.txt for license information +// See https://swift.org/CONTRIBUTORS.txt for the list of Swift project authors +// +//===----------------------------------------------------------------------===// +// +// This file defines the basic interface for generating LLVM IR for pointer +// authentication. +// +//===----------------------------------------------------------------------===// + +#ifndef SWIFT_IRGEN_GENPOINTERAUTH_H +#define SWIFT_IRGEN_GENPOINTERAUTH_H + +#include "swift/IRGen/ValueWitness.h" +#include "swift/Basic/ExternalUnion.h" +#include "swift/AST/IRGenOptions.h" +#include "swift/AST/ProtocolAssociations.h" +#include "swift/AST/Types.h" +#include "swift/SIL/SILDeclRef.h" + +namespace llvm { +class ConstantInt; +class Value; +} + +namespace clang { +class PointerAuthSchema; +} + +namespace swift { +namespace irgen { +class FunctionPointer; +class IRGenFunction; +class IRGenModule; +class PointerAuthInfo; + +/// Additional information about the source of a function pointer. +class PointerAuthEntity { +public: + enum class Special { + BlockCopyHelper, + BlockDisposeHelper, + HeapDestructor, + PartialApplyCapture, + TypeDescriptor, + TypeDescriptorAsArgument, + KeyPathDestroy, + KeyPathCopy, + KeyPathEquals, + KeyPathHash, + KeyPathGetter, + KeyPathNonmutatingSetter, + KeyPathMutatingSetter, + KeyPathGetLayout, + KeyPathInitializer, + KeyPathMetadataAccessor, + DynamicReplacementKey, + }; + +private: + enum class Kind { + None, + Special, + ValueWitness, + AssociatedType, + AssociatedConformance, + CanSILFunctionType, + CoroutineYieldTypes, + SILDeclRef, + SILFunction, + } StoredKind; + + using Members = ExternalUnionMembers; + static Members::Index getStorageIndexForKind(Kind kind) { + switch (kind) { + case Kind::None: + return Members::indexOf(); + case Kind::Special: + return Members::indexOf(); + case Kind::ValueWitness: + return Members::indexOf(); + case Kind::CoroutineYieldTypes: + case Kind::CanSILFunctionType: + return Members::indexOf(); + case Kind::SILDeclRef: + return Members::indexOf(); + case Kind::AssociatedType: + return Members::indexOf(); + case Kind::AssociatedConformance: + return Members::indexOf(); + case Kind::SILFunction: + return Members::indexOf(); + } + llvm_unreachable("bad kind"); + } + ExternalUnion Storage; + + static_assert(decltype(Storage)::union_is_trivially_copyable, + "please add copy/move/dtor if you need a non-trivial type"); + +public: + PointerAuthEntity() + : StoredKind(Kind::None) { + } + PointerAuthEntity(Special specialKind) + : StoredKind(Kind::Special) { + Storage.emplace(StoredKind, specialKind); + } + PointerAuthEntity(CanSILFunctionType type) + : StoredKind(Kind::CanSILFunctionType) { + Storage.emplace(StoredKind, type); + } + PointerAuthEntity(SILDeclRef decl) + : StoredKind(Kind::SILDeclRef) { + Storage.emplace(StoredKind, decl); + } + PointerAuthEntity(ValueWitness witness) + : StoredKind(Kind::ValueWitness) { + assert(isValueWitnessFunction(witness)); + Storage.emplace(StoredKind, witness); + } + PointerAuthEntity(AssociatedType association) + : StoredKind(Kind::AssociatedType) { + Storage.emplaceAggregate(StoredKind, association); + } + PointerAuthEntity(const AssociatedConformance &association) + : StoredKind(Kind::AssociatedConformance) { + Storage.emplaceAggregate(StoredKind, association); + } + PointerAuthEntity(SILFunction *f) + : StoredKind(Kind::SILFunction) { + Storage.emplace(StoredKind, f); + } + + static PointerAuthEntity forYieldTypes(CanSILFunctionType fnType) { + assert(fnType->isCoroutine()); + PointerAuthEntity result; + result.StoredKind = Kind::CoroutineYieldTypes; + result.Storage.emplace(result.StoredKind, fnType); + return result; + } + + llvm::ConstantInt *getDeclDiscriminator(IRGenModule &IGM) const; + llvm::ConstantInt *getTypeDiscriminator(IRGenModule &IGM) const; +}; + +std::pair +getCoroutineResumeFunctionPointerAuth(IRGenModule &IGM, + CanSILFunctionType coroutineFnType); + +/// Blend a small integer discriminator with the given address value +/// in a way that is assumed to maximally preserve entropy from both. +llvm::Value *emitPointerAuthBlend(IRGenFunction &IGF, + llvm::Value *address, + llvm::Value *discriminator); + +/// Strip the signature of a signed pointer value. +/// The return value has the same type as the input. +llvm::Value *emitPointerAuthStrip(IRGenFunction &IGF, llvm::Value *fnPtr, + unsigned Key); + +/// Sign the given pointer value, which is assumed to be unsigned. +/// The return value has the same type as the input. This is a no-op if +/// the target auth info has disabled signing. +llvm::Value *emitPointerAuthSign(IRGenFunction &IGF, llvm::Value *fnPtr, + const PointerAuthInfo &newAuth); + +/// Authenticate the given pointer value and return an unsigned value. +llvm::Value *emitPointerAuthAuth(IRGenFunction &IGF, llvm::Value *fnPtr, + const PointerAuthInfo &oldAuth); + +/// Resign the given function pointer. +FunctionPointer emitPointerAuthResign(IRGenFunction &IGF, + const FunctionPointer &fn, + const PointerAuthInfo &newAuth); + +/// Resign the given pointer value. This function does the right thing +/// for unsigned input and result schemas. The result will have the same +/// type as the input. +llvm::Value *emitPointerAuthResign(IRGenFunction &IGF, + llvm::Value *fnPtr, + const PointerAuthInfo &oldAuth, + const PointerAuthInfo &newAuth); + +/// The (non-ABI) discriminator used for non-constant captures of +/// partial apply functions. +const uint16_t PointerAuthDiscriminator_PartialApplyCapture = 7185; + +} // end namespace irgen +} // end namespace swift + +#endif diff --git a/lib/IRGen/GenProto.cpp b/lib/IRGen/GenProto.cpp index e29f60a352f83..e48a792156641 100644 --- a/lib/IRGen/GenProto.cpp +++ b/lib/IRGen/GenProto.cpp @@ -65,6 +65,7 @@ #include "GenHeap.h" #include "GenMeta.h" #include "GenOpaque.h" +#include "GenPointerAuth.h" #include "GenPoly.h" #include "GenType.h" #include "GenericRequirement.h" @@ -789,6 +790,12 @@ namespace { void addMethod(SILDeclRef func) { auto decl = cast(func.getDecl()); + // If this assert needs to be changed, be sure to also change + // ProtocolDescriptorBuilder::getRequirementInfo. + assert((isa(decl) + ? (func.kind == SILDeclRef::Kind::Allocator) + : (func.kind == SILDeclRef::Kind::Func)) + && "unexpected kind for protocol witness declaration ref"); Entries.push_back(WitnessTableEntry::forFunction(decl)); } @@ -1275,7 +1282,10 @@ class AccessorConformanceInfo : public ConformanceInfo { // It should be never called. We add a pointer to an error function. witness = IGM.getDeletedMethodErrorFn(); } - Table.addBitCast(witness, IGM.Int8PtrTy); + witness = llvm::ConstantExpr::getBitCast(witness, IGM.Int8PtrTy); + + auto &schema = IGM.getOptions().PointerAuth.ProtocolWitnesses; + Table.addSignedPointer(witness, schema, requirement); return; } @@ -1312,7 +1322,11 @@ class AccessorConformanceInfo : public ConformanceInfo { associate, Conformance.getDeclContext()->getGenericSignatureOfContext(), /*inProtocolContext=*/false); - Table.addBitCast(witness, IGM.Int8PtrTy); + witness = llvm::ConstantExpr::getBitCast(witness, IGM.Int8PtrTy); + + auto &schema = IGM.getOptions().PointerAuth + .ProtocolAssociatedTypeAccessFunctions; + Table.addSignedPointer(witness, schema, requirement); } void addAssociatedConformance(AssociatedConformance requirement) { @@ -1352,7 +1366,10 @@ class AccessorConformanceInfo : public ConformanceInfo { llvm::Constant *witnessEntry = getAssociatedConformanceWitness(requirement, associate, associatedConformance); - Table.addBitCast(witnessEntry, IGM.Int8PtrTy); + + auto &schema = IGM.getOptions().PointerAuth + .ProtocolAssociatedTypeWitnessTableAccessFunctions; + Table.addSignedPointer(witnessEntry, schema, requirement); } /// Build the instantiation function that runs at the end of witness @@ -1456,11 +1473,11 @@ llvm::Constant *IRGenModule::getAssociatedTypeWitness(Type type, auto typeRef = getTypeRef(type, sig, role).first; // Set the low bit to indicate that this is a mangled name. - auto witness = llvm::ConstantExpr::getPtrToInt(typeRef, IntPtrTy); + auto witness = llvm::ConstantExpr::getBitCast(typeRef, Int8PtrTy); unsigned bit = ProtocolRequirementFlags::AssociatedTypeMangledNameBit; auto bitConstant = llvm::ConstantInt::get(IntPtrTy, bit); - witness = llvm::ConstantExpr::getAdd(witness, bitConstant); - return llvm::ConstantExpr::getIntToPtr(witness, Int8PtrTy); + return llvm::ConstantExpr::getInBoundsGetElementPtr(nullptr, witness, + bitConstant); } static void buildAssociatedTypeValueName(CanType depAssociatedType, @@ -3280,9 +3297,10 @@ FunctionPointer irgen::emitWitnessMethodValue(IRGenFunction &IGF, // Find the witness we're interested in. auto &fnProtoInfo = IGF.IGM.getProtocolInfo(proto, ProtocolInfoKind::Full); auto index = fnProtoInfo.getFunctionIndex(fn); + llvm::Value *slot; llvm::Value *witnessFnPtr = emitInvariantLoadOfOpaqueWitness(IGF, wtable, - index.forProtocolWitnessTable()); + index.forProtocolWitnessTable(), &slot); auto fnType = IGF.IGM.getSILTypes().getConstantFunctionType( IGF.IGM.getMaximalTypeExpansionContext(), member); @@ -3290,7 +3308,10 @@ FunctionPointer irgen::emitWitnessMethodValue(IRGenFunction &IGF, witnessFnPtr = IGF.Builder.CreateBitCast(witnessFnPtr, signature.getType()->getPointerTo()); - return FunctionPointer(witnessFnPtr, signature); + auto &schema = IGF.getOptions().PointerAuth.ProtocolWitnesses; + auto authInfo = PointerAuthInfo::emit(IGF, schema, slot, member); + + return FunctionPointer(witnessFnPtr, authInfo, signature); } FunctionPointer irgen::emitWitnessMethodValue( diff --git a/lib/IRGen/GenValueWitness.cpp b/lib/IRGen/GenValueWitness.cpp index 14e27122d7fcc..6c951ed3eece4 100644 --- a/lib/IRGen/GenValueWitness.cpp +++ b/lib/IRGen/GenValueWitness.cpp @@ -37,6 +37,7 @@ #include "GenEnum.h" #include "GenMeta.h" #include "GenOpaque.h" +#include "GenPointerAuth.h" #include "IRGenDebugInfo.h" #include "IRGenFunction.h" #include "IRGenModule.h" @@ -800,7 +801,8 @@ static void addValueWitness(IRGenModule &IGM, SILType concreteType, const TypeInfo &concreteTI) { auto addFunction = [&](llvm::Constant *fn) { - B.addBitCast(fn, IGM.Int8PtrTy); + fn = llvm::ConstantExpr::getBitCast(fn, IGM.Int8PtrTy); + B.addSignedPointer(fn, IGM.getOptions().PointerAuth.ValueWitnesses, index); }; // Try to use a standard function. diff --git a/lib/IRGen/IRGen.cpp b/lib/IRGen/IRGen.cpp index 36fb7ca21504e..10bda54352bd1 100644 --- a/lib/IRGen/IRGen.cpp +++ b/lib/IRGen/IRGen.cpp @@ -39,6 +39,7 @@ #include "swift/Subsystems.h" #include "../Serialization/ModuleFormat.h" #include "clang/Basic/TargetInfo.h" +#include "clang/Frontend/CompilerInstance.h" #include "llvm/ADT/StringSet.h" #include "llvm/Analysis/AliasAnalysis.h" #include "llvm/Bitcode/BitcodeWriter.h" @@ -659,6 +660,67 @@ bool swift::performLLVM(const IRGenOptions &Opts, return false; } +static void setPointerAuthOptions(PointerAuthOptions &opts, + const clang::PointerAuthOptions &clangOpts){ + // Intentionally do a slice-assignment to copy over the clang options. + static_cast(opts) = clangOpts; + + assert(clangOpts.FunctionPointers); + if (clangOpts.FunctionPointers.getKind() != PointerAuthSchema::Kind::ARM8_3) + return; + + using Discrimination = PointerAuthSchema::Discrimination; + auto key = clangOpts.FunctionPointers.getARM8_3Key(); + auto nonABIKey = PointerAuthSchema::ARM8_3Key::ASIB; + + // If you change anything here, be sure to update . + opts.SwiftFunctionPointers = + PointerAuthSchema(key, /*address*/ false, Discrimination::Type); + opts.KeyPaths = + PointerAuthSchema(key, /*address*/ true, Discrimination::Decl); + opts.ValueWitnesses = + PointerAuthSchema(key, /*address*/ true, Discrimination::Decl); + opts.ProtocolWitnesses = + PointerAuthSchema(key, /*address*/ true, Discrimination::Decl); + opts.ProtocolAssociatedTypeAccessFunctions = + PointerAuthSchema(key, /*address*/ true, Discrimination::Decl); + opts.ProtocolAssociatedTypeWitnessTableAccessFunctions = + PointerAuthSchema(key, /*address*/ true, Discrimination::Decl); + opts.SwiftClassMethods = + PointerAuthSchema(key, /*address*/ true, Discrimination::Decl); + opts.SwiftClassMethodPointers = + PointerAuthSchema(key, /*address*/ false, Discrimination::Decl); + opts.HeapDestructors = + PointerAuthSchema(key, /*address*/ true, Discrimination::Decl); + + // Partial-apply captures are not ABI and can use a more aggressive key. + opts.PartialApplyCapture = + PointerAuthSchema(nonABIKey, /*address*/ true, Discrimination::Decl); + + opts.TypeDescriptors = + PointerAuthSchema(PointerAuthSchema::ARM8_3Key::ASDA, /*address*/ true, + Discrimination::Decl); + opts.TypeDescriptorsAsArguments = + PointerAuthSchema(PointerAuthSchema::ARM8_3Key::ASDA, /*address*/ false, + Discrimination::Decl); + + opts.SwiftDynamicReplacements = + PointerAuthSchema(key, /*address*/ true, Discrimination::Decl); + opts.SwiftDynamicReplacementKeys = + PointerAuthSchema(PointerAuthSchema::ARM8_3Key::ASDA, /*address*/ true, + 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. + // The address used in the discrimination is not the address where the + // function pointer is signed, but the address of the coroutine buffer. + opts.YieldManyResumeFunctions = + PointerAuthSchema(key, /*address*/ true, Discrimination::Type); + opts.YieldOnceResumeFunctions = + PointerAuthSchema(key, /*address*/ true, Discrimination::Type); +} + std::unique_ptr swift::createTargetMachine(const IRGenOptions &Opts, ASTContext &Ctx) { CodeGenOpt::Level OptLevel = Opts.shouldOptimize() @@ -683,6 +745,18 @@ swift::createTargetMachine(const IRGenOptions &Opts, ASTContext &Ctx) { targetFeatures = features.getString(); } + // Set up pointer-authentication. + if (auto loader = Ctx.getClangModuleLoader()) { + auto &clangInstance = loader->getClangInstance(); + if (clangInstance.getLangOpts().PointerAuthCalls) { + // FIXME: This is gross. This needs to be done in the Frontend + // after the module loaders are set up, and where these options are + // formally not const. + setPointerAuthOptions(const_cast(Opts).PointerAuth, + clangInstance.getCodeGenOpts().PointerAuth); + } + } + std::string Error; const Target *Target = TargetRegistry::lookupTarget(EffectiveTriple.str(), Error); diff --git a/lib/IRGen/IRGenMangler.h b/lib/IRGen/IRGenMangler.h index aa4d644d0095b..2f79d355aa437 100644 --- a/lib/IRGen/IRGenMangler.h +++ b/lib/IRGen/IRGenMangler.h @@ -15,6 +15,7 @@ #include "IRGenModule.h" #include "swift/AST/ASTMangler.h" +#include "swift/AST/ProtocolAssociations.h" #include "swift/IRGen/ValueWitness.h" #include "llvm/Support/SaveAndRestore.h" @@ -347,6 +348,25 @@ class IRGenMangler : public Mangle::ASTMangler { return mangleConformanceSymbol(type, C, "WL"); } + std::string + mangleAssociatedTypeAccessFunctionDiscriminator(AssociatedType association) { + beginMangling(); + appendAnyGenericType(association.getSourceProtocol()); + appendIdentifier(association.getAssociation()->getNameStr()); + return finalize(); + } + + std::string mangleAssociatedTypeWitnessTableAccessFunctionDiscriminator( + const AssociatedConformance &conf) { + beginMangling(); + appendAnyGenericType(conf.getSourceProtocol()); + bool isFirstAssociatedTypeIdentifier = true; + appendAssociatedTypePath(conf.getAssociation(), + isFirstAssociatedTypeIdentifier); + appendAnyGenericType(conf.getAssociatedRequirement()); + return finalize(); + } + std::string mangleAssociatedTypeWitnessTableAccessFunction( const ProtocolConformance *Conformance, CanType AssociatedType, diff --git a/lib/IRGen/IRGenModule.cpp b/lib/IRGen/IRGenModule.cpp index 28aa23b514ec9..04c83b269af9c 100644 --- a/lib/IRGen/IRGenModule.cpp +++ b/lib/IRGen/IRGenModule.cpp @@ -18,6 +18,7 @@ #include "swift/AST/ASTContext.h" #include "swift/AST/Module.h" #include "swift/AST/DiagnosticsIRGen.h" +#include "swift/AST/GenericSignature.h" #include "swift/AST/IRGenOptions.h" #include "swift/Basic/Dwarf.h" #include "swift/Demangling/ManglingMacros.h" @@ -49,9 +50,11 @@ #include "llvm/Support/ErrorHandling.h" #include "llvm/Support/MD5.h" +#include "Callee.h" #include "ConformanceDescription.h" #include "GenDecl.h" #include "GenEnum.h" +#include "GenPointerAuth.h" #include "GenIntegerLiteral.h" #include "GenType.h" #include "IRGenModule.h" @@ -141,6 +144,52 @@ static clang::CodeGenerator *createClangCodeGenerator(ASTContext &Context, return ClangCodeGen; } +#ifndef NDEBUG +static ValueDecl *lookupSimple(ModuleDecl *module, ArrayRef declPath) { + DeclContext *dc = module; + for (;; declPath = declPath.drop_front()) { + SmallVector results; + module->lookupMember(results, dc, module->getASTContext().getIdentifier(declPath.front()), Identifier()); + if (results.size() != 1) return nullptr; + if (declPath.size() == 1) return results.front(); + dc = dyn_cast(results.front()); + if (!dc) return nullptr; + } +} + +static void checkPointerAuthWitnessDiscriminator(IRGenModule &IGM, ArrayRef declPath, uint16_t expected) { + auto &schema = IGM.getOptions().PointerAuth.ProtocolWitnesses; + if (!schema.isEnabled()) return; + + auto decl = lookupSimple(IGM.getSwiftModule(), declPath); + assert(decl && "decl not found"); + auto discriminator = PointerAuthInfo::getOtherDiscriminator(IGM, schema, SILDeclRef(decl)); + assert(discriminator->getZExtValue() == expected && "discriminator value doesn't match"); +} + +static void checkPointerAuthAssociatedTypeDiscriminator(IRGenModule &IGM, ArrayRef declPath, uint16_t expected) { + auto &schema = IGM.getOptions().PointerAuth.ProtocolAssociatedTypeAccessFunctions; + if (!schema.isEnabled()) return; + + auto decl = dyn_cast_or_null(lookupSimple(IGM.getSwiftModule(), declPath)); + assert(decl && "decl not found"); + auto discriminator = PointerAuthInfo::getOtherDiscriminator(IGM, schema, AssociatedType(decl)); + assert(discriminator->getZExtValue() == expected && "discriminator value doesn't match"); +} + +static void sanityCheckStdlib(IRGenModule &IGM) { + if (!IGM.getSwiftModule()->isStdlibModule()) return; + + // Only run the sanity check when we're building the real stdlib. + if (!lookupSimple(IGM.getSwiftModule(), { "String" })) return; + + checkPointerAuthAssociatedTypeDiscriminator(IGM, { "_ObjectiveCBridgeable", "_ObjectiveCType" }, SpecialPointerAuthDiscriminators::ObjectiveCTypeDiscriminator); + checkPointerAuthWitnessDiscriminator(IGM, { "_ObjectiveCBridgeable", "_bridgeToObjectiveC" }, SpecialPointerAuthDiscriminators::bridgeToObjectiveCDiscriminator); + checkPointerAuthWitnessDiscriminator(IGM, { "_ObjectiveCBridgeable", "_forceBridgeFromObjectiveC" }, SpecialPointerAuthDiscriminators::forceBridgeFromObjectiveCDiscriminator); + checkPointerAuthWitnessDiscriminator(IGM, { "_ObjectiveCBridgeable", "_conditionallyBridgeFromObjectiveC" }, SpecialPointerAuthDiscriminators::conditionallyBridgeFromObjectiveCDiscriminator); +} +#endif + IRGenModule::IRGenModule(IRGenerator &irgen, std::unique_ptr &&target, SourceFile *SF, llvm::LLVMContext &LLVMContext, @@ -508,6 +557,10 @@ IRGenModule::IRGenModule(IRGenerator &irgen, clang::CodeGen::swiftcall::isSwiftErrorLoweredInRegister( ClangCodeGen->CGM()); +#ifndef NDEBUG + sanityCheckStdlib(*this); +#endif + DynamicReplacementsTy = llvm::StructType::get(getLLVMContext(), {Int8PtrPtrTy, Int8PtrTy}); DynamicReplacementsPtrTy = DynamicReplacementsTy->getPointerTo(DefaultAS); @@ -532,6 +585,7 @@ IRGenModule::IRGenModule(IRGenerator &irgen, IRGenModule::~IRGenModule() { destroyClangTypeConverter(); destroyMetadataLayoutMap(); + destroyPointerAuthCaches(); delete &Types; } @@ -963,6 +1017,12 @@ void IRGenModule::constructInitialFnAttributes(llvm::AttrBuilder &Attrs, FuncOptMode = IRGen.Opts.OptMode; if (FuncOptMode == OptimizationMode::ForSize) Attrs.addAttribute(llvm::Attribute::MinSize); + + auto triple = llvm::Triple(ClangOpts.Triple); + if (triple.getArchName() == "arm64e") { + Attrs.addAttribute("ptrauth-returns"); + Attrs.addAttribute("ptrauth-calls"); + } } llvm::AttributeList IRGenModule::constructInitialAttributes() { @@ -976,7 +1036,7 @@ llvm::ConstantInt *IRGenModule::getInt32(uint32_t value) { return llvm::ConstantInt::get(Int32Ty, value); } -llvm::Constant *IRGenModule::getSize(Size size) { +llvm::ConstantInt *IRGenModule::getSize(Size size) { return llvm::ConstantInt::get(SizeTy, size.getValue()); } diff --git a/lib/IRGen/IRGenModule.h b/lib/IRGen/IRGenModule.h index d59328d773b49..9570deb2596ae 100644 --- a/lib/IRGen/IRGenModule.h +++ b/lib/IRGen/IRGenModule.h @@ -73,6 +73,7 @@ namespace clang { class Decl; class GlobalDecl; class Type; + class PointerAuthSchema; namespace CodeGen { class CGFunctionInfo; class CodeGenModule; @@ -139,6 +140,7 @@ namespace irgen { class NecessaryBindings; class NominalMetadataLayout; class OutliningMetadataCollector; + class PointerAuthEntity; class ProtocolInfo; enum class ProtocolInfoKind : uint8_t; class Signature; @@ -952,6 +954,20 @@ class IRGenModule { llvm::Constant *emitTypeMetadataRecords(); llvm::Constant *emitFieldDescriptors(); + llvm::Constant *getConstantSignedFunctionPointer(llvm::Constant *fn, + CanSILFunctionType fnType); + + llvm::Constant *getConstantSignedCFunctionPointer(llvm::Constant *fn); + + llvm::Constant *getConstantSignedPointer(llvm::Constant *pointer, + unsigned key, + llvm::Constant *addrDiscriminator, + llvm::Constant *otherDiscriminator); + llvm::Constant *getConstantSignedPointer(llvm::Constant *pointer, + const clang::PointerAuthSchema &schema, + const PointerAuthEntity &entity, + llvm::Constant *storageAddress); + llvm::Constant *getOrCreateHelperFunction(StringRef name, llvm::Type *resultType, ArrayRef paramTypes, @@ -1021,6 +1037,12 @@ class IRGenModule { llvm::StringMap GlobalConstantStrings; llvm::StringMap GlobalConstantUTF16Strings; + struct PointerAuthCachesType; + PointerAuthCachesType *PointerAuthCaches = nullptr; + PointerAuthCachesType &getPointerAuthCaches(); + void destroyPointerAuthCaches(); + friend class PointerAuthEntity; + /// LLVMUsed - List of global values which are required to be /// present in the object file; bitcast to i8*. This is used for /// forcing visibility of symbols which may otherwise be optimized @@ -1300,7 +1322,7 @@ private: \ ForeignFunctionInfo getForeignFunctionInfo(CanSILFunctionType type); llvm::ConstantInt *getInt32(uint32_t value); - llvm::Constant *getSize(Size size); + llvm::ConstantInt *getSize(Size size); llvm::Constant *getAlignment(Alignment align); llvm::Constant *getBool(bool condition); diff --git a/lib/IRGen/IRGenSIL.cpp b/lib/IRGen/IRGenSIL.cpp index ba0156a45cf31..c3b2fd60cc206 100644 --- a/lib/IRGen/IRGenSIL.cpp +++ b/lib/IRGen/IRGenSIL.cpp @@ -70,6 +70,7 @@ #include "GenObjC.h" #include "GenOpaque.h" #include "GenPoly.h" +#include "GenPointerAuth.h" #include "GenProto.h" #include "GenStruct.h" #include "GenTuple.h" @@ -2719,7 +2720,13 @@ void IRGenSILFunction::visitEndApply(BeginApplyInst *i, bool isAbort) { continuation = Builder.CreateBitCast(continuation, sig.getType()->getPointerTo()); - FunctionPointer callee(continuation, sig); + + auto schemaAndEntity = + getCoroutineResumeFunctionPointerAuth(IGM, i->getOrigCalleeType()); + auto pointerAuth = PointerAuthInfo::emit(*this, schemaAndEntity.first, + coroutine.Buffer.getAddress(), + schemaAndEntity.second); + FunctionPointer callee(continuation, pointerAuth, sig); Builder.CreateCall(callee, { coroutine.Buffer.getAddress(), @@ -5577,7 +5584,11 @@ void IRGenSILFunction::visitSuperMethodInst(swift::SuperMethodInst *i) { auto sig = IGM.getSignature(methodType); fnPtr = Builder.CreateBitCast(fnPtr, sig.getType()->getPointerTo()); - FunctionPointer fn(fnPtr, sig); + auto &schema = getOptions().PointerAuth.SwiftClassMethodPointers; + auto authInfo = + PointerAuthInfo::emit(*this, schema, /*storageAddress=*/nullptr, method); + + FunctionPointer fn(fnPtr, authInfo, sig); setLoweredFunctionPointer(i, fn); return; diff --git a/lib/IRGen/Linking.cpp b/lib/IRGen/Linking.cpp index 02eea30c2fc28..55aa404058897 100644 --- a/lib/IRGen/Linking.cpp +++ b/lib/IRGen/Linking.cpp @@ -672,6 +672,75 @@ SILLinkage LinkEntity::getLinkage(ForDefinition_t forDefinition) const { llvm_unreachable("bad link entity kind"); } +bool LinkEntity::isContextDescriptor() const { + switch (getKind()) { + case Kind::ModuleDescriptor: + case Kind::ExtensionDescriptor: + case Kind::AnonymousDescriptor: + case Kind::NominalTypeDescriptor: + case Kind::ProtocolDescriptor: + case Kind::OpaqueTypeDescriptor: + return true; + case Kind::PropertyDescriptor: + case Kind::DispatchThunk: + case Kind::DispatchThunkInitializer: + case Kind::DispatchThunkAllocator: + case Kind::MethodDescriptor: + case Kind::MethodDescriptorInitializer: + case Kind::MethodDescriptorAllocator: + case Kind::MethodLookupFunction: + case Kind::EnumCase: + case Kind::FieldOffset: + case Kind::ObjCClass: + case Kind::ObjCClassRef: + case Kind::ObjCMetaclass: + case Kind::ObjCMetadataUpdateFunction: + case Kind::ObjCResilientClassStub: + case Kind::SwiftMetaclassStub: + case Kind::ClassMetadataBaseOffset: + case Kind::TypeMetadataPattern: + case Kind::TypeMetadataInstantiationCache: + case Kind::TypeMetadataInstantiationFunction: + case Kind::TypeMetadataSingletonInitializationCache: + case Kind::TypeMetadataCompletionFunction: + case Kind::ProtocolRequirementsBaseDescriptor: + case Kind::AssociatedTypeDescriptor: + case Kind::AssociatedConformanceDescriptor: + case Kind::BaseConformanceDescriptor: + case Kind::DefaultAssociatedConformanceAccessor: + case Kind::SILFunction: + case Kind::SILGlobalVariable: + case Kind::ProtocolWitnessTable: + case Kind::ProtocolWitnessTablePattern: + case Kind::GenericProtocolWitnessTableInstantiationFunction: + case Kind::AssociatedTypeWitnessTableAccessFunction: + case Kind::ReflectionAssociatedTypeDescriptor: + case Kind::ProtocolConformanceDescriptor: + case Kind::ProtocolWitnessTableLazyAccessFunction: + case Kind::ProtocolWitnessTableLazyCacheVariable: + case Kind::ValueWitness: + case Kind::ValueWitnessTable: + case Kind::TypeMetadata: + case Kind::TypeMetadataAccessFunction: + case Kind::TypeMetadataLazyCacheVariable: + case Kind::TypeMetadataDemanglingCacheVariable: + case Kind::ReflectionBuiltinDescriptor: + case Kind::ReflectionFieldDescriptor: + case Kind::CoroutineContinuationPrototype: + case Kind::DynamicallyReplaceableFunctionVariableAST: + case Kind::DynamicallyReplaceableFunctionKeyAST: + case Kind::DynamicallyReplaceableFunctionImpl: + case Kind::DynamicallyReplaceableFunctionKey: + case Kind::DynamicallyReplaceableFunctionVariable: + case Kind::OpaqueTypeDescriptorAccessor: + case Kind::OpaqueTypeDescriptorAccessorImpl: + case Kind::OpaqueTypeDescriptorAccessorKey: + case Kind::OpaqueTypeDescriptorAccessorVar: + case Kind::DifferentiabilityWitness: + return false; + } +} + llvm::Type *LinkEntity::getDefaultDeclarationType(IRGenModule &IGM) const { switch (getKind()) { case Kind::ModuleDescriptor: diff --git a/lib/IRGen/LocalTypeData.cpp b/lib/IRGen/LocalTypeData.cpp index 7ca002c90de82..28d0b71fc7e70 100644 --- a/lib/IRGen/LocalTypeData.cpp +++ b/lib/IRGen/LocalTypeData.cpp @@ -708,6 +708,11 @@ void LocalTypeDataKind::print(llvm::raw_ostream &out) const { out << "ValueWitnessTable"; } else { assert(isSingletonKind()); + if (Value >= ValueWitnessDiscriminatorBase) { + auto witness = ValueWitness(Value - ValueWitnessDiscriminatorBase); + out << "Discriminator(" << getValueWitnessName(witness) << ")"; + return; + } ValueWitness witness = ValueWitness(Value - ValueWitnessBase); out << getValueWitnessName(witness); } diff --git a/lib/IRGen/LocalTypeDataKind.h b/lib/IRGen/LocalTypeDataKind.h index b20657e85d479..f45aa30cb1755 100644 --- a/lib/IRGen/LocalTypeDataKind.h +++ b/lib/IRGen/LocalTypeDataKind.h @@ -21,6 +21,7 @@ #include "swift/AST/ProtocolConformanceRef.h" #include "swift/AST/Type.h" +#include "swift/IRGen/ValueWitness.h" #include #include "llvm/ADT/DenseMapInfo.h" @@ -28,7 +29,6 @@ namespace swift { class ProtocolDecl; namespace irgen { - enum class ValueWitness : unsigned; /// The kind of local type data we might want to store for a type. class LocalTypeDataKind { @@ -54,6 +54,9 @@ class LocalTypeDataKind { // The first enumerator for an individual value witness. ValueWitnessBase, + // The first enumerator for an individual value witness discriminator. + ValueWitnessDiscriminatorBase = ValueWitnessBase + MaxNumValueWitnesses, + FirstPayloadValue = 2048, Kind_Decl = 0, Kind_Conformance = 1, @@ -86,6 +89,11 @@ class LocalTypeDataKind { static LocalTypeDataKind forValueWitness(ValueWitness witness) { return LocalTypeDataKind(ValueWitnessBase + (unsigned)witness); } + + /// The discriminator for a specific value witness. + static LocalTypeDataKind forValueWitnessDiscriminator(ValueWitness witness) { + return LocalTypeDataKind(ValueWitnessDiscriminatorBase + (unsigned)witness); + } /// A reference to a protocol witness table for an archetype. /// diff --git a/lib/IRGen/MetadataRequest.cpp b/lib/IRGen/MetadataRequest.cpp index 5756469372db6..3cace6ed56ff9 100644 --- a/lib/IRGen/MetadataRequest.cpp +++ b/lib/IRGen/MetadataRequest.cpp @@ -16,12 +16,14 @@ #include "MetadataRequest.h" +#include "Callee.h" #include "ConstantBuilder.h" #include "Explosion.h" #include "FixedTypeInfo.h" #include "GenArchetype.h" #include "GenClass.h" #include "GenMeta.h" +#include "GenPointerAuth.h" #include "GenProto.h" #include "GenType.h" #include "GenericArguments.h" @@ -1881,9 +1883,18 @@ MetadataResponse irgen::emitGenericTypeMetadataAccessFunction( GenericArguments &genericArgs) { auto &IGM = IGF.IGM; - llvm::Constant *descriptor = + llvm::Value *descriptor = IGM.getAddrOfTypeContextDescriptor(nominal, RequireMetadata); + // Sign the descriptor. + auto schema = IGF.IGM.getOptions().PointerAuth.TypeDescriptorsAsArguments; + if (schema) { + auto authInfo = PointerAuthInfo::emit( + IGF, schema, nullptr, + PointerAuthEntity::Special::TypeDescriptorAsArgument); + descriptor = emitPointerAuthSign(IGF, descriptor, authInfo); + } + auto request = params.claimNext(); auto numArguments = genericArgs.Types.size(); diff --git a/lib/Parse/ParseIfConfig.cpp b/lib/Parse/ParseIfConfig.cpp index b9abdc9800447..f8799b2ec9c43 100644 --- a/lib/Parse/ParseIfConfig.cpp +++ b/lib/Parse/ParseIfConfig.cpp @@ -296,6 +296,8 @@ class ValidateIfConfigCondition : DiagName = "import conditional"; break; case PlatformConditionKind::TargetEnvironment: DiagName = "target environment"; break; + case PlatformConditionKind::PtrAuth: + DiagName = "pointer authentication scheme"; break; case PlatformConditionKind::Runtime: llvm_unreachable("handled above"); } diff --git a/lib/SIL/OperandOwnership.cpp b/lib/SIL/OperandOwnership.cpp index 4e28d03d97bf3..04e0d5050f32f 100644 --- a/lib/SIL/OperandOwnership.cpp +++ b/lib/SIL/OperandOwnership.cpp @@ -1023,6 +1023,7 @@ ANY_OWNERSHIP_BUILTIN(ZeroInitializer) ANY_OWNERSHIP_BUILTIN(Swift3ImplicitObjCEntrypoint) ANY_OWNERSHIP_BUILTIN(PoundAssert) ANY_OWNERSHIP_BUILTIN(GlobalStringTablePointer) +ANY_OWNERSHIP_BUILTIN(TypePtrAuthDiscriminator) #undef ANY_OWNERSHIP_BUILTIN // This is correct today since we do not have any builtins which return diff --git a/lib/SIL/ValueOwnership.cpp b/lib/SIL/ValueOwnership.cpp index 2ed019d8da2ad..5700ec8f4d79a 100644 --- a/lib/SIL/ValueOwnership.cpp +++ b/lib/SIL/ValueOwnership.cpp @@ -522,6 +522,7 @@ CONSTANT_OWNERSHIP_BUILTIN(None, OnceWithContext) CONSTANT_OWNERSHIP_BUILTIN(None, TSanInoutAccess) CONSTANT_OWNERSHIP_BUILTIN(None, Swift3ImplicitObjCEntrypoint) CONSTANT_OWNERSHIP_BUILTIN(None, PoundAssert) +CONSTANT_OWNERSHIP_BUILTIN(None, TypePtrAuthDiscriminator) CONSTANT_OWNERSHIP_BUILTIN(None, GlobalStringTablePointer) #undef CONSTANT_OWNERSHIP_BUILTIN diff --git a/lib/SILOptimizer/Transforms/AccessEnforcementReleaseSinking.cpp b/lib/SILOptimizer/Transforms/AccessEnforcementReleaseSinking.cpp index f28a9c32ff6cf..ee73a35d78a92 100644 --- a/lib/SILOptimizer/Transforms/AccessEnforcementReleaseSinking.cpp +++ b/lib/SILOptimizer/Transforms/AccessEnforcementReleaseSinking.cpp @@ -136,6 +136,7 @@ static bool isBarrier(SILInstruction *inst) { case BuiltinValueKind::WillThrow: case BuiltinValueKind::CondFailMessage: case BuiltinValueKind::PoundAssert: + case BuiltinValueKind::TypePtrAuthDiscriminator: case BuiltinValueKind::GlobalStringTablePointer: return false; diff --git a/lib/Serialization/SerializedModuleLoader.cpp b/lib/Serialization/SerializedModuleLoader.cpp index e8c15720e89f1..db2649c069be2 100644 --- a/lib/Serialization/SerializedModuleLoader.cpp +++ b/lib/Serialization/SerializedModuleLoader.cpp @@ -46,11 +46,17 @@ void forEachTargetModuleBasename(const ASTContext &Ctx, // FIXME: We used to use "major architecture" names for these files---the // names checked in "#if arch(...)". Fall back to that name in the one case - // where it's different from what Swift 4.2 supported: 32-bit ARM platforms. + // where it's different from what Swift 4.2 supported: + // - 32-bit ARM platforms (formerly "arm") + // - arm64e (formerly shared with "arm64") // We should be able to drop this once there's an Xcode that supports the // new names. if (Ctx.LangOpts.Target.getArch() == llvm::Triple::ArchType::arm) body("arm"); + else if (Ctx.LangOpts.Target.getSubArch() == + llvm::Triple::SubArchType::AArch64SubArch_E) { + body("arm64"); + } } enum class SearchPathKind { diff --git a/stdlib/public/SwiftShims/KeyPath.h b/stdlib/public/SwiftShims/KeyPath.h index 61c7749fb458d..9b6ba3bd40214 100644 --- a/stdlib/public/SwiftShims/KeyPath.h +++ b/stdlib/public/SwiftShims/KeyPath.h @@ -109,11 +109,26 @@ static const __swift_uint32_t _SwiftKeyPathComponentHeader_ComputedIDUnresolvedI static const __swift_uint32_t _SwiftKeyPathComponentHeader_ComputedIDUnresolvedFunctionCall = 0x00000001U; +#ifndef __cplusplus extern const void *_Nonnull (swift_keyPathGenericWitnessTable[]); static inline const void *_Nonnull __swift_keyPathGenericWitnessTable_addr(void) { return swift_keyPathGenericWitnessTable; } +#endif + +// Discriminators for pointer authentication in key path patterns and objects + +static const __swift_uint16_t _SwiftKeyPath_ptrauth_ArgumentDestroy = 0x7072; +static const __swift_uint16_t _SwiftKeyPath_ptrauth_ArgumentCopy = 0x6f66; +static const __swift_uint16_t _SwiftKeyPath_ptrauth_ArgumentEquals = 0x756e; +static const __swift_uint16_t _SwiftKeyPath_ptrauth_ArgumentHash = 0x6374; +static const __swift_uint16_t _SwiftKeyPath_ptrauth_Getter = 0x6f72; +static const __swift_uint16_t _SwiftKeyPath_ptrauth_NonmutatingSetter = 0x6f70; +static const __swift_uint16_t _SwiftKeyPath_ptrauth_MutatingSetter = 0x7469; +static const __swift_uint16_t _SwiftKeyPath_ptrauth_ArgumentLayout = 0x6373; +static const __swift_uint16_t _SwiftKeyPath_ptrauth_ArgumentInit = 0x6275; +static const __swift_uint16_t _SwiftKeyPath_ptrauth_MetadataAccessor = 0x7474; #ifdef __cplusplus } // extern "C" diff --git a/stdlib/public/core/CMakeLists.txt b/stdlib/public/core/CMakeLists.txt index dd1ef587f2d12..95ee7f07826a5 100644 --- a/stdlib/public/core/CMakeLists.txt +++ b/stdlib/public/core/CMakeLists.txt @@ -108,6 +108,7 @@ set(SWIFTLIB_ESSENTIAL Policy.swift PrefixWhile.swift Print.swift + PtrAuth.swift Random.swift RandomAccessCollection.swift Range.swift diff --git a/stdlib/public/core/GroupInfo.json b/stdlib/public/core/GroupInfo.json index c900b93b9410d..1b9a209004e67 100644 --- a/stdlib/public/core/GroupInfo.json +++ b/stdlib/public/core/GroupInfo.json @@ -226,7 +226,8 @@ "Comparable.swift", "Codable.swift", "LegacyABI.swift", - "MigrationSupport.swift" + "MigrationSupport.swift", + "PtrAuth.swift" ], "Result": [ "Result.swift" diff --git a/stdlib/public/core/KeyPath.swift b/stdlib/public/core/KeyPath.swift index 414d3e09d290e..baef0f9eb53e9 100644 --- a/stdlib/public/core/KeyPath.swift +++ b/stdlib/public/core/KeyPath.swift @@ -456,7 +456,119 @@ internal struct ComputedPropertyID: Hashable { } } -internal struct ComputedArgumentWitnesses { +internal struct ComputedAccessorsPtr { +#if INTERNAL_CHECKS_ENABLED + internal let header: RawKeyPathComponent.Header +#endif + internal let _value: UnsafeRawPointer + + init(header: RawKeyPathComponent.Header, value: UnsafeRawPointer) { +#if INTERNAL_CHECKS_ENABLED + self.header = header +#endif + self._value = value + } + + @_transparent + static var getterPtrAuthKey: UInt64 { + return UInt64(_SwiftKeyPath_ptrauth_Getter) + } + @_transparent + static var nonmutatingSetterPtrAuthKey: UInt64 { + return UInt64(_SwiftKeyPath_ptrauth_NonmutatingSetter) + } + @_transparent + static var mutatingSetterPtrAuthKey: UInt64 { + return UInt64(_SwiftKeyPath_ptrauth_MutatingSetter) + } + + internal typealias Getter = @convention(thin) + (CurValue, UnsafeRawPointer, Int) -> NewValue + internal typealias NonmutatingSetter = @convention(thin) + (NewValue, CurValue, UnsafeRawPointer, Int) -> () + internal typealias MutatingSetter = @convention(thin) + (NewValue, inout CurValue, UnsafeRawPointer, Int) -> () + + internal var getterPtr: UnsafeRawPointer { +#if INTERNAL_CHECKS_ENABLED + _internalInvariant(header.kind == .computed, + "not a computed property") +#endif + return _value + } + internal var setterPtr: UnsafeRawPointer { +#if INTERNAL_CHECKS_ENABLED + _internalInvariant(header.isComputedSettable, + "not a settable property") +#endif + return _value + MemoryLayout.size + } + + internal func getter() + -> Getter { + + return getterPtr._loadAddressDiscriminatedFunctionPointer( + as: Getter.self, + discriminator: ComputedAccessorsPtr.getterPtrAuthKey) + } + + internal func nonmutatingSetter() + -> NonmutatingSetter { +#if INTERNAL_CHECKS_ENABLED + _internalInvariant(header.isComputedSettable && !header.isComputedMutating, + "not a nonmutating settable property") +#endif + + return setterPtr._loadAddressDiscriminatedFunctionPointer( + as: NonmutatingSetter.self, + discriminator: ComputedAccessorsPtr.nonmutatingSetterPtrAuthKey) + } + + internal func mutatingSetter() + -> MutatingSetter { +#if INTERNAL_CHECKS_ENABLED + _internalInvariant(header.isComputedSettable && header.isComputedMutating, + "not a mutating settable property") +#endif + + return setterPtr._loadAddressDiscriminatedFunctionPointer( + as: MutatingSetter.self, + discriminator: ComputedAccessorsPtr.mutatingSetterPtrAuthKey) + } +} + +internal struct ComputedArgumentWitnessesPtr { + internal let _value: UnsafeRawPointer + + init(_ value: UnsafeRawPointer) { + self._value = value + } + + @_transparent + static var destroyPtrAuthKey: UInt64 { + return UInt64(_SwiftKeyPath_ptrauth_ArgumentDestroy) + } + @_transparent + static var copyPtrAuthKey: UInt64 { + return UInt64(_SwiftKeyPath_ptrauth_ArgumentCopy) + } + @_transparent + static var equalsPtrAuthKey: UInt64 { + return UInt64(_SwiftKeyPath_ptrauth_ArgumentEquals) + } + @_transparent + static var hashPtrAuthKey: UInt64 { + return UInt64(_SwiftKeyPath_ptrauth_ArgumentHash) + } + @_transparent + static var layoutPtrAuthKey: UInt64 { + return UInt64(_SwiftKeyPath_ptrauth_ArgumentLayout) + } + @_transparent + static var initPtrAuthKey: UInt64 { + return UInt64(_SwiftKeyPath_ptrauth_ArgumentInit) + } + internal typealias Destroy = @convention(thin) (_ instanceArguments: UnsafeMutableRawPointer, _ size: Int) -> () internal typealias Copy = @convention(thin) @@ -472,17 +584,39 @@ internal struct ComputedArgumentWitnesses { (_ instanceArguments: UnsafeRawPointer, _ size: Int) -> Int - internal let destroy: Destroy? - internal let copy: Copy - internal let equals: Equals - internal let hash: Hash + // The witnesses are stored as address-discriminated authenticated + // pointers. + + internal var destroy: Destroy? { + return _value._loadAddressDiscriminatedFunctionPointer( + as: Optional.self, + discriminator: ComputedArgumentWitnessesPtr.destroyPtrAuthKey) + } + internal var copy: Copy { + return _value._loadAddressDiscriminatedFunctionPointer( + fromByteOffset: MemoryLayout.size, + as: Copy.self, + discriminator: ComputedArgumentWitnessesPtr.copyPtrAuthKey) + } + internal var equals: Equals { + return _value._loadAddressDiscriminatedFunctionPointer( + fromByteOffset: 2*MemoryLayout.size, + as: Equals.self, + discriminator: ComputedArgumentWitnessesPtr.equalsPtrAuthKey) + } + internal var hash: Hash { + return _value._loadAddressDiscriminatedFunctionPointer( + fromByteOffset: 3*MemoryLayout.size, + as: Hash.self, + discriminator: ComputedArgumentWitnessesPtr.hashPtrAuthKey) + } } internal enum KeyPathComponent: Hashable { internal struct ArgumentRef { internal init( data: UnsafeRawBufferPointer, - witnesses: UnsafePointer, + witnesses: ComputedArgumentWitnessesPtr, witnessSizeAdjustment: Int ) { self.data = data @@ -491,7 +625,7 @@ internal enum KeyPathComponent: Hashable { } internal var data: UnsafeRawBufferPointer - internal var witnesses: UnsafePointer + internal var witnesses: ComputedArgumentWitnessesPtr internal var witnessSizeAdjustment: Int } @@ -503,16 +637,17 @@ internal enum KeyPathComponent: Hashable { case `class`(offset: Int) /// The keypath projects using a getter. case get(id: ComputedPropertyID, - get: UnsafeRawPointer, argument: ArgumentRef?) + accessors: ComputedAccessorsPtr, + argument: ArgumentRef?) /// The keypath projects using a getter/setter pair. The setter can mutate /// the base value in-place. case mutatingGetSet(id: ComputedPropertyID, - get: UnsafeRawPointer, set: UnsafeRawPointer, + accessors: ComputedAccessorsPtr, argument: ArgumentRef?) /// The keypath projects using a getter/setter pair that does not mutate its /// base. case nonmutatingGetSet(id: ComputedPropertyID, - get: UnsafeRawPointer, set: UnsafeRawPointer, + accessors: ComputedAccessorsPtr, argument: ArgumentRef?) /// The keypath optional-chains, returning nil immediately if the input is /// nil, or else proceeding by projecting the value inside. @@ -532,19 +667,19 @@ internal enum KeyPathComponent: Hashable { (.optionalForce, .optionalForce), (.optionalWrap, .optionalWrap): return true - case (.get(id: let id1, get: _, argument: let argument1), - .get(id: let id2, get: _, argument: let argument2)), + case (.get(id: let id1, accessors: _, argument: let argument1), + .get(id: let id2, accessors: _, argument: let argument2)), - (.mutatingGetSet(id: let id1, get: _, set: _, argument: let argument1), - .mutatingGetSet(id: let id2, get: _, set: _, argument: let argument2)), + (.mutatingGetSet(id: let id1, accessors: _, argument: let argument1), + .mutatingGetSet(id: let id2, accessors: _, argument: let argument2)), - (.nonmutatingGetSet(id: let id1, get: _, set: _, argument: let argument1), - .nonmutatingGetSet(id: let id2, get: _, set: _, argument: let argument2)): + (.nonmutatingGetSet(id: let id1, accessors: _, argument: let argument1), + .nonmutatingGetSet(id: let id2, accessors: _, argument: let argument2)): if id1 != id2 { return false } if let arg1 = argument1, let arg2 = argument2 { - return arg1.witnesses.pointee.equals( + return arg1.witnesses.equals( arg1.data.baseAddress.unsafelyUnwrapped, arg2.data.baseAddress.unsafelyUnwrapped, arg1.data.count - arg1.witnessSizeAdjustment) @@ -571,7 +706,7 @@ internal enum KeyPathComponent: Hashable { _ argument: KeyPathComponent.ArgumentRef? ) { if let argument = argument { - let hash = argument.witnesses.pointee.hash( + let hash = argument.witnesses.hash( argument.data.baseAddress.unsafelyUnwrapped, argument.data.count - argument.witnessSizeAdjustment) // Returning 0 indicates that the arguments should not impact the @@ -595,15 +730,15 @@ internal enum KeyPathComponent: Hashable { hasher.combine(3) case .optionalWrap: hasher.combine(4) - case .get(id: let id, get: _, argument: let argument): + case .get(id: let id, accessors: _, argument: let argument): hasher.combine(5) hasher.combine(id) appendHashFromArgument(argument) - case .mutatingGetSet(id: let id, get: _, set: _, argument: let argument): + case .mutatingGetSet(id: let id, accessors: _, argument: let argument): hasher.combine(6) hasher.combine(id) appendHashFromArgument(argument) - case .nonmutatingGetSet(id: let id, get: _, set: _, argument: let argument): + case .nonmutatingGetSet(id: let id, accessors: _, argument: let argument): hasher.combine(7) hasher.combine(id) appendHashFromArgument(argument) @@ -676,7 +811,7 @@ internal final class ClassHolder { internal final class MutatingWritebackBuffer { internal let previous: AnyObject? internal let base: UnsafeMutablePointer - internal let set: @convention(thin) (NewValue, inout CurValue, UnsafeRawPointer, Int) -> () + internal let set: ComputedAccessorsPtr.MutatingSetter internal let argument: UnsafeRawPointer internal let argumentSize: Int internal var value: NewValue @@ -687,7 +822,7 @@ internal final class MutatingWritebackBuffer { internal init(previous: AnyObject?, base: UnsafeMutablePointer, - set: @escaping @convention(thin) (NewValue, inout CurValue, UnsafeRawPointer, Int) -> (), + set: @escaping ComputedAccessorsPtr.MutatingSetter, argument: UnsafeRawPointer, argumentSize: Int, value: NewValue) { @@ -704,7 +839,7 @@ internal final class MutatingWritebackBuffer { internal final class NonmutatingWritebackBuffer { internal let previous: AnyObject? internal let base: CurValue - internal let set: @convention(thin) (NewValue, CurValue, UnsafeRawPointer, Int) -> () + internal let set: ComputedAccessorsPtr.NonmutatingSetter internal let argument: UnsafeRawPointer internal let argumentSize: Int internal var value: NewValue @@ -716,7 +851,7 @@ internal final class NonmutatingWritebackBuffer { internal init(previous: AnyObject?, base: CurValue, - set: @escaping @convention(thin) (NewValue, CurValue, UnsafeRawPointer, Int) -> (), + set: @escaping ComputedAccessorsPtr.NonmutatingSetter, argument: UnsafeRawPointer, argumentSize: Int, value: NewValue) { @@ -756,6 +891,11 @@ internal struct RawKeyPathComponent { internal var header: Header internal var body: UnsafeRawBufferPointer + @_transparent + static var metadataAccessorPtrAuthKey: UInt64 { + return UInt64(_SwiftKeyPath_ptrauth_MetadataAccessor) + } + internal struct Header { internal static var payloadMask: UInt32 { return _SwiftKeyPathComponentHeader_PayloadMask @@ -1189,22 +1329,14 @@ internal struct RawKeyPathComponent { kind: header.computedIDKind) } - internal var _computedGetter: UnsafeRawPointer { + internal var _computedAccessors: ComputedAccessorsPtr { _internalInvariant(header.kind == .computed, "not a computed property") - return body.load( - fromByteOffset: Header.pointerAlignmentSkew + MemoryLayout.size, - as: UnsafeRawPointer.self) - } - - internal var _computedSetter: UnsafeRawPointer { - _internalInvariant(header.isComputedSettable, - "not a settable property") - - return body.load( - fromByteOffset: Header.pointerAlignmentSkew + MemoryLayout.size * 2, - as: UnsafeRawPointer.self) + return ComputedAccessorsPtr( + header: header, + value: body.baseAddress.unsafelyUnwrapped + + Header.pointerAlignmentSkew + MemoryLayout.size) } internal var _computedArgumentHeaderPointer: UnsafeRawPointer { @@ -1220,10 +1352,10 @@ internal struct RawKeyPathComponent { return _computedArgumentHeaderPointer.load(as: Int.self) } internal - var _computedArgumentWitnesses: UnsafePointer { + var _computedArgumentWitnesses: ComputedArgumentWitnessesPtr { return _computedArgumentHeaderPointer.load( fromByteOffset: MemoryLayout.size, - as: UnsafePointer.self) + as: ComputedArgumentWitnessesPtr.self) } internal var _computedArguments: UnsafeRawPointer { @@ -1266,7 +1398,7 @@ internal struct RawKeyPathComponent { let isMutating = header.isComputedMutating let id = _computedID - let get = _computedGetter + let accessors = _computedAccessors // Argument value is unused if there are no arguments. let argument: KeyPathComponent.ArgumentRef? if header.hasComputedArguments { @@ -1281,16 +1413,14 @@ internal struct RawKeyPathComponent { switch (isSettable, isMutating) { case (false, false): - return .get(id: id, get: get, argument: argument) + return .get(id: id, accessors: accessors, argument: argument) case (true, false): return .nonmutatingGetSet(id: id, - get: get, - set: _computedSetter, + accessors: accessors, argument: argument) case (true, true): return .mutatingGetSet(id: id, - get: get, - set: _computedSetter, + accessors: accessors, argument: argument) case (false, true): _internalInvariantFailure("impossible") @@ -1312,7 +1442,7 @@ internal struct RawKeyPathComponent { case .computed: // Run destructor, if any if header.hasComputedArguments, - let destructor = _computedArgumentWitnesses.pointee.destroy { + let destructor = _computedArgumentWitnesses.destroy { destructor(_computedMutableArguments, _computedArgumentSize - _computedArgumentWitnessSizeAdjustment) } @@ -1348,16 +1478,22 @@ internal struct RawKeyPathComponent { toByteOffset: componentSize, as: Int.self) componentSize += MemoryLayout.size - buffer.storeBytes(of: _computedGetter, - toByteOffset: componentSize, - as: UnsafeRawPointer.self) - componentSize += MemoryLayout.size + let accessors = _computedAccessors + (buffer.baseAddress.unsafelyUnwrapped + MemoryLayout.size * 2) + ._copyAddressDiscriminatedFunctionPointer( + from: accessors.getterPtr, + discriminator: ComputedAccessorsPtr.getterPtrAuthKey) + + componentSize += MemoryLayout.size if header.isComputedSettable { - buffer.storeBytes(of: _computedSetter, - toByteOffset: MemoryLayout.size * 3, - as: UnsafeRawPointer.self) + (buffer.baseAddress.unsafelyUnwrapped + MemoryLayout.size * 3) + ._copyAddressDiscriminatedFunctionPointer( + from: accessors.setterPtr, + discriminator: header.isComputedMutating + ? ComputedAccessorsPtr.mutatingSetterPtrAuthKey + : ComputedAccessorsPtr.nonmutatingSetterPtrAuthKey) componentSize += MemoryLayout.size } @@ -1370,7 +1506,7 @@ internal struct RawKeyPathComponent { componentSize += MemoryLayout.size buffer.storeBytes(of: _computedArgumentWitnesses, toByteOffset: componentSize, - as: UnsafePointer.self) + as: ComputedArgumentWitnessesPtr.self) componentSize += MemoryLayout.size if header.isComputedInstantiatedFromExternalWithArguments { @@ -1384,7 +1520,7 @@ internal struct RawKeyPathComponent { let adjustedSize = argumentSize - _computedArgumentWitnessSizeAdjustment let argumentDest = buffer.baseAddress.unsafelyUnwrapped + componentSize - _computedArgumentWitnesses.pointee.copy( + _computedArgumentWitnesses.copy( arguments, argumentDest, adjustedSize) @@ -1448,7 +1584,7 @@ internal struct RawKeyPathComponent { let offsetAddress = basePtr.advanced(by: offset) - // Perform an instaneous record access on the address in order to + // Perform an instantaneous record access on the address in order to // ensure that the read will not conflict with an already in-progress // 'modify' access. Builtin.performInstantaneousReadAccess(offsetAddress._rawValue, @@ -1457,15 +1593,12 @@ internal struct RawKeyPathComponent { .assumingMemoryBound(to: NewValue.self) .pointee) - case .get(id: _, get: let rawGet, argument: let argument), - .mutatingGetSet(id: _, get: let rawGet, set: _, argument: let argument), - .nonmutatingGetSet(id: _, get: let rawGet, set: _, argument: let argument): - typealias Getter - = @convention(thin) (CurValue, UnsafeRawPointer, Int) -> NewValue - let get = unsafeBitCast(rawGet, to: Getter.self) - return .continue(get(base, - argument?.data.baseAddress ?? rawGet, - argument?.data.count ?? 0)) + case .get(id: _, accessors: let accessors, argument: let argument), + .mutatingGetSet(id: _, accessors: let accessors, argument: let argument), + .nonmutatingGetSet(id: _, accessors: let accessors, argument: let argument): + return .continue(accessors.getter()(base, + argument?.data.baseAddress ?? accessors._value, + argument?.data.count ?? 0)) case .optionalChain: _internalInvariant(CurValue.self == Optional.self, @@ -1522,55 +1655,42 @@ internal struct RawKeyPathComponent { return offsetAddress - case .mutatingGetSet(id: _, get: let rawGet, set: let rawSet, + case .mutatingGetSet(id: _, accessors: let accessors, argument: let argument): - typealias Getter - = @convention(thin) (CurValue, UnsafeRawPointer, Int) -> NewValue - typealias Setter - = @convention(thin) (NewValue, inout CurValue, UnsafeRawPointer, Int) -> () - let get = unsafeBitCast(rawGet, to: Getter.self) - let set = unsafeBitCast(rawSet, to: Setter.self) - let baseTyped = UnsafeMutablePointer( mutating: base.assumingMemoryBound(to: CurValue.self)) - let argValue = argument?.data.baseAddress ?? rawGet + let argValue = argument?.data.baseAddress ?? accessors._value let argSize = argument?.data.count ?? 0 - let writeback = MutatingWritebackBuffer(previous: keepAlive, - base: baseTyped, - set: set, - argument: argValue, - argumentSize: argSize, - value: get(baseTyped.pointee, argValue, argSize)) + let writeback = MutatingWritebackBuffer( + previous: keepAlive, + base: baseTyped, + set: accessors.mutatingSetter(), + argument: argValue, + argumentSize: argSize, + value: accessors.getter()(baseTyped.pointee, argValue, argSize)) keepAlive = writeback // A maximally-abstracted, final, stored class property should have // a stable address. return UnsafeRawPointer(Builtin.addressof(&writeback.value)) - case .nonmutatingGetSet(id: _, get: let rawGet, set: let rawSet, + case .nonmutatingGetSet(id: _, accessors: let accessors, argument: let argument): // A nonmutating property should only occur at the root of a mutation, // since otherwise it would be part of the reference prefix. _internalInvariant(isRoot, "nonmutating component should not appear in the middle of mutation") - typealias Getter - = @convention(thin) (CurValue, UnsafeRawPointer, Int) -> NewValue - typealias Setter - = @convention(thin) (NewValue, CurValue, UnsafeRawPointer, Int) -> () - - let get = unsafeBitCast(rawGet, to: Getter.self) - let set = unsafeBitCast(rawSet, to: Setter.self) - let baseValue = base.assumingMemoryBound(to: CurValue.self).pointee - let argValue = argument?.data.baseAddress ?? rawGet + let argValue = argument?.data.baseAddress ?? accessors._value let argSize = argument?.data.count ?? 0 - let writeback = NonmutatingWritebackBuffer(previous: keepAlive, - base: baseValue, - set: set, - argument: argValue, - argumentSize: argSize, - value: get(baseValue, argValue, argSize)) + let writeback = NonmutatingWritebackBuffer( + previous: keepAlive, + base: baseValue, + set: accessors.nonmutatingSetter(), + argument: argValue, + argumentSize: argSize, + value: accessors.getter()(baseValue, argValue, argSize)) keepAlive = writeback // A maximally-abstracted, final, stored class property should have // a stable address. @@ -2467,6 +2587,26 @@ internal func _resolveKeyPathGenericArgReference( // Adjust the reference. let referenceStart = reference - 1 + // If we have a symbolic reference to an accessor, call it. + let first = referenceStart.load(as: UInt8.self) + if first == 255 && reference.load(as: UInt8.self) == 9 { + typealias MetadataAccessor = + @convention(c) (UnsafeRawPointer?) -> UnsafeRawPointer + + // Unaligned load of the offset. + let pointerReference = reference + 1 + var offset: Int32 = 0 + _memcpy(dest: &offset, src: pointerReference, size: 4) + + let accessorPtrRaw = _resolveRelativeAddress(pointerReference, offset) + let accessorPtrSigned = + _PtrAuth.sign(pointer: accessorPtrRaw, + key: .processIndependentCode, + discriminator: _PtrAuth.discriminator(for: MetadataAccessor.self)) + let accessor = unsafeBitCast(accessorPtrSigned, to: MetadataAccessor.self) + return accessor(arguments) + } + let nameLength = _getSymbolicMangledNameLength(referenceStart) let namePtr = referenceStart.bindMemory(to: UInt8.self, capacity: nameLength + 1) @@ -2511,7 +2651,7 @@ internal enum KeyPathPatternStoredOffset { } internal struct KeyPathPatternComputedArguments { var getLayout: KeyPathComputedArgumentLayoutFn - var witnesses: UnsafePointer + var witnesses: ComputedArgumentWitnessesPtr var initializer: KeyPathComputedArgumentInitializerFn } @@ -2643,7 +2783,10 @@ internal func _walkKeyPathPattern( let getLayoutBase = componentBuffer.baseAddress.unsafelyUnwrapped let getLayoutRef = _pop(from: &componentBuffer, as: Int32.self) let getLayoutRaw = _resolveRelativeAddress(getLayoutBase, getLayoutRef) - let getLayout = unsafeBitCast(getLayoutRaw, + let getLayoutSigned = _PtrAuth.sign(pointer: getLayoutRaw, + key: .processIndependentCode, + discriminator: _PtrAuth.discriminator(for: KeyPathComputedArgumentLayoutFn.self)) + let getLayout = unsafeBitCast(getLayoutSigned, to: KeyPathComputedArgumentLayoutFn.self) let witnessesBase = componentBuffer.baseAddress.unsafelyUnwrapped @@ -2659,12 +2802,15 @@ internal func _walkKeyPathPattern( let initializerRef = _pop(from: &componentBuffer, as: Int32.self) let initializerRaw = _resolveRelativeAddress(initializerBase, initializerRef) - let initializer = unsafeBitCast(initializerRaw, + let initializerSigned = _PtrAuth.sign(pointer: initializerRaw, + key: .processIndependentCode, + discriminator: _PtrAuth.discriminator(for: KeyPathComputedArgumentInitializerFn.self)) + + let initializer = unsafeBitCast(initializerSigned, to: KeyPathComputedArgumentInitializerFn.self) return KeyPathPatternComputedArguments(getLayout: getLayout, - witnesses: - witnesses.assumingMemoryBound(to: ComputedArgumentWitnesses.self), + witnesses: ComputedArgumentWitnessesPtr(witnesses), initializer: initializer) } else { return nil @@ -3073,9 +3219,10 @@ internal struct InstantiateKeyPathBuffer: KeyPathPatternVisitor { var endOfReferencePrefixComponent: UnsafeMutableRawPointer? = nil var previousComponentAddr: UnsafeMutableRawPointer? = nil - mutating func pushDest(_ value: T) { - _internalInvariant(_isPOD(T.self)) - let size = MemoryLayout.size + mutating func adjustDestForAlignment(of: T.Type) -> ( + baseAddress: UnsafeMutableRawPointer, + misalign: Int + ) { let alignment = MemoryLayout.alignment var baseAddress = destData.baseAddress.unsafelyUnwrapped var misalign = Int(bitPattern: baseAddress) % alignment @@ -3083,6 +3230,13 @@ internal struct InstantiateKeyPathBuffer: KeyPathPatternVisitor { misalign = alignment - misalign baseAddress = baseAddress.advanced(by: misalign) } + return (baseAddress, misalign) + } + mutating func pushDest(_ value: T) { + _internalInvariant(_isPOD(T.self)) + let size = MemoryLayout.size + let alignment = MemoryLayout.alignment + let (baseAddress, misalign) = adjustDestForAlignment(of: T.self) withUnsafeBytes(of: value) { _memcpy(dest: baseAddress, src: $0.baseAddress.unsafelyUnwrapped, size: UInt(size)) @@ -3091,6 +3245,19 @@ internal struct InstantiateKeyPathBuffer: KeyPathPatternVisitor { start: baseAddress + size, count: destData.count - size - misalign) } + mutating func pushAddressDiscriminatedFunctionPointer( + _ unsignedPointer: UnsafeRawPointer, + discriminator: UInt64 + ) { + let size = MemoryLayout.size + let (baseAddress, misalign) = + adjustDestForAlignment(of: UnsafeRawPointer.self) + baseAddress._storeFunctionPointerWithAddressDiscrimination( + unsignedPointer, discriminator: discriminator) + destData = UnsafeMutableRawBufferPointer( + start: baseAddress + size, + count: destData.count - size - misalign) + } mutating func updatePreviousComponentAddr() -> UnsafeMutableRawPointer? { let oldValue = previousComponentAddr @@ -3207,7 +3374,11 @@ internal struct InstantiateKeyPathBuffer: KeyPathPatternVisitor { // The pointer in the pattern is to a function that generates the // identifier pointer. typealias Resolver = @convention(c) (UnsafeRawPointer?) -> UnsafeRawPointer? - let resolverFn = unsafeBitCast(absoluteID.unsafelyUnwrapped, + let resolverSigned = _PtrAuth.sign( + pointer: absoluteID.unsafelyUnwrapped, + key: .processIndependentCode, + discriminator: _PtrAuth.discriminator(for: Resolver.self)) + let resolverFn = unsafeBitCast(resolverSigned, to: Resolver.self) absoluteID = resolverFn(patternArgs) @@ -3224,9 +3395,12 @@ internal struct InstantiateKeyPathBuffer: KeyPathPatternVisitor { arguments != nil && externalArgs != nil) pushDest(header) pushDest(resolvedID) - pushDest(getter) + pushAddressDiscriminatedFunctionPointer(getter, + discriminator: ComputedAccessorsPtr.getterPtrAuthKey) if let setter = setter { - pushDest(setter) + pushAddressDiscriminatedFunctionPointer(setter, + discriminator: mutating ? ComputedAccessorsPtr.mutatingSetterPtrAuthKey + : ComputedAccessorsPtr.nonmutatingSetterPtrAuthKey) } if let arguments = arguments { @@ -3250,7 +3424,7 @@ internal struct InstantiateKeyPathBuffer: KeyPathPatternVisitor { // A nonnull destructor in the witnesses file indicates the instantiated // payload is nontrivial. - if let _ = arguments.witnesses.pointee.destroy { + if let _ = arguments.witnesses.destroy { isTrivial = false } diff --git a/stdlib/public/core/PtrAuth.swift b/stdlib/public/core/PtrAuth.swift new file mode 100644 index 0000000000000..f2beaebc3a736 --- /dev/null +++ b/stdlib/public/core/PtrAuth.swift @@ -0,0 +1,261 @@ +//===----------------------------------------------------------------------===// +// +// This source file is part of the Swift.org open source project +// +// Copyright (c) 2014 - 2017 Apple Inc. and the Swift project authors +// Licensed under Apache License v2.0 with Runtime Library Exception +// +// See https://swift.org/LICENSE.txt for license information +// See https://swift.org/CONTRIBUTORS.txt for the list of Swift project authors +// +//===----------------------------------------------------------------------===// + +/// Pseudo-namespace for pointer authentication primitives. +internal enum _PtrAuth { + internal struct Key { + var _value: Int32 + + @_transparent + init(_value: Int32) { + self._value = _value + } + +#if _ptrauth(_arm64e) + @_transparent + static var ASIA: Key { return Key(_value: 0) } + @_transparent + static var ASIB: Key { return Key(_value: 1) } + @_transparent + static var ASDA: Key { return Key(_value: 2) } + @_transparent + static var ASDB: Key { return Key(_value: 3) } + + /// A process-independent key which can be used to sign code pointers. + /// Signing and authenticating with this key is a no-op in processes + /// which disable ABI pointer authentication. + @_transparent + static var processIndependentCode: Key { return .ASIA } + + /// A process-specific key which can be used to sign code pointers. + /// Signing and authenticating with this key is enforced even in processes + /// which disable ABI pointer authentication. + @_transparent + static var processDependentCode: Key { return .ASIB } + + /// A process-independent key which can be used to sign data pointers. + /// Signing and authenticating with this key is a no-op in processes + /// which disable ABI pointer authentication. + @_transparent + static var processIndependentData: Key { return .ASDA } + + /// A process-specific key which can be used to sign data pointers. + /// Signing and authenticating with this key is a no-op in processes + /// which disable ABI pointer authentication. + @_transparent + static var processDependentData: Key { return .ASDB } +#elseif _ptrauth(_none) + /// A process-independent key which can be used to sign code pointers. + /// Signing and authenticating with this key is a no-op in processes + /// which disable ABI pointer authentication. + @_transparent + static var processIndependentCode: Key { return Key(_value: 0) } + + /// A process-specific key which can be used to sign code pointers. + /// Signing and authenticating with this key is enforced even in processes + /// which disable ABI pointer authentication. + @_transparent + static var processDependentCode: Key { return Key(_value: 0) } + + /// A process-independent key which can be used to sign data pointers. + /// Signing and authenticating with this key is a no-op in processes + /// which disable ABI pointer authentication. + @_transparent + static var processIndependentData: Key { return Key(_value: 0) } + + /// A process-specific key which can be used to sign data pointers. + /// Signing and authenticating with this key is a no-op in processes + /// which disable ABI pointer authentication. + @_transparent + static var processDependentData: Key { return Key(_value: 0) } +#else + #error("unsupported ptrauth scheme") +#endif + } + +#if _ptrauth(_arm64e) + /// Blend a pointer and a small integer to form a new extra-data + /// discriminator. Not all bits of the inputs are guaranteed to + /// contribute to the result. + @_transparent + static func blend(pointer: UnsafeRawPointer, + discriminator: UInt64) -> UInt64 { + return UInt64(Builtin.int_ptrauth_blend_Int64( + UInt64(UInt(bitPattern: pointer))._value, + discriminator._value)) + } + + /// Sign an unauthenticated pointer. + @_transparent + static func sign(pointer: UnsafeRawPointer, + key: Key, + discriminator: UInt64) -> UnsafeRawPointer { + let bitPattern = UInt64(Builtin.int_ptrauth_sign_Int64( + UInt64(UInt(bitPattern: pointer))._value, + key._value._value, + discriminator._value)) + + return UnsafeRawPointer(bitPattern: + UInt(truncatingIfNeeded: bitPattern)).unsafelyUnwrapped + } + + /// Authenticate a pointer using one scheme and resign it using another. + @_transparent + static func authenticateAndResign(pointer: UnsafeRawPointer, + oldKey: Key, + oldDiscriminator: UInt64, + newKey: Key, + newDiscriminator: UInt64) -> UnsafeRawPointer { + let bitPattern = UInt64(Builtin.int_ptrauth_resign_Int64( + UInt64(UInt(bitPattern: pointer))._value, + oldKey._value._value, + oldDiscriminator._value, + newKey._value._value, + newDiscriminator._value)) + + return UnsafeRawPointer(bitPattern: + UInt(truncatingIfNeeded: bitPattern)).unsafelyUnwrapped + } + + /// Get the type-specific discriminator for a function type. + @_transparent + static func discriminator(for type: T.Type) -> UInt64 { + return UInt64(Builtin.typePtrAuthDiscriminator(type)) + } + +#elseif _ptrauth(_none) + /// Blend a pointer and a small integer to form a new extra-data + /// discriminator. Not all bits of the inputs are guaranteed to + /// contribute to the result. + @_transparent + static func blend(pointer _: UnsafeRawPointer, + discriminator _: UInt64) -> UInt64{ + return 0 + } + + /// Sign an unauthenticated pointer. + @_transparent + static func sign(pointer: UnsafeRawPointer, + key: Key, + discriminator: UInt64) -> UnsafeRawPointer { + return pointer + } + + /// Authenticate a pointer using one scheme and resign it using another. + @_transparent + static func authenticateAndResign(pointer: UnsafeRawPointer, + oldKey: Key, + oldDiscriminator: UInt64, + newKey: Key, + newDiscriminator: UInt64) -> UnsafeRawPointer { + return pointer + } + + /// Get the type-specific discriminator for a function type. + @_transparent + static func discriminator(for type: T.Type) -> UInt64 { + return 0 + } +#else + #error("Unsupported ptrauth scheme") +#endif +} + +// Helpers for working with authenticated function pointers. + +extension UnsafeRawPointer { + /// Load a function pointer from memory that has been authenticated + /// specifically for its given address. + @_transparent + internal func _loadAddressDiscriminatedFunctionPointer( + fromByteOffset offset: Int = 0, + as type: T.Type, + discriminator: UInt64 + ) -> T { + let src = self + offset + + let srcDiscriminator = _PtrAuth.blend(pointer: src, + discriminator: discriminator) + let ptr = src.load(as: UnsafeRawPointer.self) + let resigned = _PtrAuth.authenticateAndResign( + pointer: ptr, + oldKey: .processIndependentCode, + oldDiscriminator: srcDiscriminator, + newKey: .processIndependentCode, + newDiscriminator: _PtrAuth.discriminator(for: type)) + + return unsafeBitCast(resigned, to: type) + } + + @_transparent + internal func _loadAddressDiscriminatedFunctionPointer( + fromByteOffset offset: Int = 0, + as type: Optional.Type, + discriminator: UInt64 + ) -> Optional { + let src = self + offset + + let srcDiscriminator = _PtrAuth.blend(pointer: src, + discriminator: discriminator) + guard let ptr = src.load(as: Optional.self) else { + return nil + } + let resigned = _PtrAuth.authenticateAndResign( + pointer: ptr, + oldKey: .processIndependentCode, + oldDiscriminator: srcDiscriminator, + newKey: .processIndependentCode, + newDiscriminator: _PtrAuth.discriminator(for: T.self)) + + return .some(unsafeBitCast(resigned, to: T.self)) + } + +} + +extension UnsafeMutableRawPointer { + /// Copy a function pointer from memory that has been authenticated + /// specifically for its given address. + internal func _copyAddressDiscriminatedFunctionPointer( + from src: UnsafeRawPointer, + discriminator: UInt64 + ) { + if src == UnsafeRawPointer(self) { return } + + let srcDiscriminator = _PtrAuth.blend(pointer: src, + discriminator: discriminator) + let destDiscriminator = _PtrAuth.blend(pointer: self, + discriminator: discriminator) + + let ptr = src.load(as: UnsafeRawPointer.self) + let resigned = _PtrAuth.authenticateAndResign( + pointer: ptr, + oldKey: .processIndependentCode, + oldDiscriminator: srcDiscriminator, + newKey: .processIndependentCode, + newDiscriminator: destDiscriminator) + + storeBytes(of: resigned, as: UnsafeRawPointer.self) + } + + @_transparent + internal func _storeFunctionPointerWithAddressDiscrimination( + _ unsignedPointer: UnsafeRawPointer, + discriminator: UInt64 + ) { + let destDiscriminator = _PtrAuth.blend(pointer: self, + discriminator: discriminator) + let signed = _PtrAuth.sign(pointer: unsignedPointer, + key: .processIndependentCode, + discriminator: destDiscriminator) + storeBytes(of: signed, as: UnsafeRawPointer.self) + } +} diff --git a/stdlib/public/runtime/Casting.cpp b/stdlib/public/runtime/Casting.cpp index dc2144fac59f7..7a7d1a3058f94 100644 --- a/stdlib/public/runtime/Casting.cpp +++ b/stdlib/public/runtime/Casting.cpp @@ -2525,22 +2525,24 @@ namespace { // protocol _ObjectiveCBridgeable { struct _ObjectiveCBridgeableWitnessTable : WitnessTable { + #define _protocolWitnessSignedPointer(n) \ + __ptrauth_swift_protocol_witness_function_pointer(SpecialPointerAuthDiscriminators::n##Discriminator) n + static_assert(WitnessTableFirstRequirementOffset == 1, "Witness table layout changed"); - // associatedtype _ObjectiveCType : class void *_ObjectiveCType; // func _bridgeToObjectiveC() -> _ObjectiveCType SWIFT_CC(swift) - HeapObject *(*bridgeToObjectiveC)( + HeapObject *(*_protocolWitnessSignedPointer(bridgeToObjectiveC))( SWIFT_CONTEXT OpaqueValue *self, const Metadata *Self, const _ObjectiveCBridgeableWitnessTable *witnessTable); // class func _forceBridgeFromObjectiveC(x: _ObjectiveCType, // inout result: Self?) SWIFT_CC(swift) - void (*forceBridgeFromObjectiveC)( + void (*_protocolWitnessSignedPointer(forceBridgeFromObjectiveC))( HeapObject *sourceValue, OpaqueValue *result, SWIFT_CONTEXT const Metadata *self, @@ -2550,7 +2552,7 @@ struct _ObjectiveCBridgeableWitnessTable : WitnessTable { // class func _conditionallyBridgeFromObjectiveC(x: _ObjectiveCType, // inout result: Self?) -> Bool SWIFT_CC(swift) - bool (*conditionallyBridgeFromObjectiveC)( + bool (*_protocolWitnessSignedPointer(conditionallyBridgeFromObjectiveC))( HeapObject *sourceValue, OpaqueValue *result, SWIFT_CONTEXT const Metadata *self, diff --git a/stdlib/public/runtime/Exclusivity.cpp b/stdlib/public/runtime/Exclusivity.cpp index dfff68f105f0f..d96b516b73695 100644 --- a/stdlib/public/runtime/Exclusivity.cpp +++ b/stdlib/public/runtime/Exclusivity.cpp @@ -341,8 +341,14 @@ void swift::swift_endAccess(ValueBuffer *buffer) { char *swift::swift_getFunctionReplacement(char **ReplFnPtr, char *CurrFn) { char *ReplFn = *ReplFnPtr; - if (ReplFn == CurrFn) + char *RawReplFn = ReplFn; + +#if SWIFT_PTRAUTH + RawReplFn = ptrauth_strip(RawReplFn, ptrauth_key_function_pointer); +#endif + if (RawReplFn == CurrFn) return nullptr; + SwiftTLSContext &ctx = getTLSContext(); if (ctx.CallOriginalOfReplacedFunction) { ctx.CallOriginalOfReplacedFunction = false; diff --git a/stdlib/public/runtime/HeapObject.cpp b/stdlib/public/runtime/HeapObject.cpp index 13a97355fb326..7fcb0e1edf184 100644 --- a/stdlib/public/runtime/HeapObject.cpp +++ b/stdlib/public/runtime/HeapObject.cpp @@ -80,8 +80,29 @@ static inline bool isValidPointerForNativeRetain(const void *p) { // the default implementation. This allows the compiler to inline the default // implementation and avoid the performance penalty of indirecting through // the function pointer in the common case. +// +// NOTE: the memcpy and asm("") naming shenanigans are to convince the compiler +// not to emit a bunch of ptrauth instructions just to perform the comparison. +// We only want to authenticate the function pointer if we actually call it. We +// can revert to a straight comparison once rdar://problem/55267009 is fixed. +static HeapObject *_swift_allocObject_(HeapMetadata const *metadata, + size_t requiredSize, + size_t requiredAlignmentMask) + asm("__swift_allocObject_"); +static HeapObject *_swift_retain_(HeapObject *object) asm("__swift_retain_"); +static HeapObject *_swift_retain_n_(HeapObject *object, uint32_t n) + asm("__swift_retain_n_"); +static void _swift_release_(HeapObject *object) asm("__swift_release_"); +static void _swift_release_n_(HeapObject *object, uint32_t n) + asm("__swift_release_n_"); +static HeapObject *_swift_tryRetain_(HeapObject *object) + asm("__swift_tryRetain_"); #define CALL_IMPL(name, args) do { \ - if (SWIFT_UNLIKELY(_ ## name != _ ## name ## _)) \ + void *fptr; \ + memcpy(&fptr, (void *)&_ ## name, sizeof(fptr)); \ + extern char _ ## name ## _as_char asm("__" #name "_"); \ + fptr = __ptrauth_swift_runtime_function_entry_strip(fptr); \ + if (SWIFT_UNLIKELY(fptr != &_ ## name ## _as_char)) \ return _ ## name args; \ return _ ## name ## _ args; \ } while(0) @@ -112,10 +133,10 @@ HeapObject *swift::swift_allocObject(HeapMetadata const *metadata, CALL_IMPL(swift_allocObject, (metadata, requiredSize, requiredAlignmentMask)); } -HeapObject *(*swift::_swift_allocObject)(HeapMetadata const *metadata, - size_t requiredSize, - size_t requiredAlignmentMask) = - _swift_allocObject_; +SWIFT_RUNTIME_EXPORT +HeapObject *(*SWIFT_RT_DECLARE_ENTRY _swift_allocObject)( + HeapMetadata const *metadata, size_t requiredSize, + size_t requiredAlignmentMask) = _swift_allocObject_; HeapObject * swift::swift_initStackObject(HeapMetadata const *metadata, @@ -320,7 +341,9 @@ HeapObject *swift::swift_retain(HeapObject *object) { CALL_IMPL(swift_retain, (object)); } -HeapObject *(*swift::_swift_retain)(HeapObject *object) = _swift_retain_; +SWIFT_RUNTIME_EXPORT +HeapObject *(*SWIFT_RT_DECLARE_ENTRY _swift_retain)(HeapObject *object) = + _swift_retain_; HeapObject *swift::swift_nonatomic_retain(HeapObject *object) { SWIFT_RT_TRACK_INVOCATION(object, swift_nonatomic_retain); @@ -340,8 +363,9 @@ HeapObject *swift::swift_retain_n(HeapObject *object, uint32_t n) { CALL_IMPL(swift_retain_n, (object, n)); } -HeapObject *(*swift::_swift_retain_n)(HeapObject *object, uint32_t n) = - _swift_retain_n_; +SWIFT_RUNTIME_EXPORT +HeapObject *(*SWIFT_RT_DECLARE_ENTRY _swift_retain_n)( + HeapObject *object, uint32_t n) = _swift_retain_n_; HeapObject *swift::swift_nonatomic_retain_n(HeapObject *object, uint32_t n) { SWIFT_RT_TRACK_INVOCATION(object, swift_nonatomic_retain_n); @@ -360,7 +384,9 @@ void swift::swift_release(HeapObject *object) { CALL_IMPL(swift_release, (object)); } -void (*swift::_swift_release)(HeapObject *object) = _swift_release_; +SWIFT_RUNTIME_EXPORT +void (*SWIFT_RT_DECLARE_ENTRY _swift_release)(HeapObject *object) = + _swift_release_; void swift::swift_nonatomic_release(HeapObject *object) { SWIFT_RT_TRACK_INVOCATION(object, swift_nonatomic_release); @@ -378,8 +404,9 @@ void swift::swift_release_n(HeapObject *object, uint32_t n) { CALL_IMPL(swift_release_n, (object, n)); } -void (*swift::_swift_release_n)(HeapObject *object, uint32_t n) = - _swift_release_n_; +SWIFT_RUNTIME_EXPORT +void (*SWIFT_RT_DECLARE_ENTRY _swift_release_n)(HeapObject *object, + uint32_t n) = _swift_release_n_; void swift::swift_nonatomic_release_n(HeapObject *object, uint32_t n) { SWIFT_RT_TRACK_INVOCATION(object, swift_nonatomic_release_n); @@ -516,7 +543,9 @@ HeapObject *swift::swift_tryRetain(HeapObject *object) { CALL_IMPL(swift_tryRetain, (object)); } -HeapObject *(*swift::_swift_tryRetain)(HeapObject *object) = _swift_tryRetain_; +SWIFT_RUNTIME_EXPORT +HeapObject *(*SWIFT_RT_DECLARE_ENTRY _swift_tryRetain)(HeapObject *object) = + _swift_tryRetain_; bool swift::swift_isDeallocating(HeapObject *object) { if (!isValidPointerForNativeRetain(object)) diff --git a/stdlib/public/runtime/KeyPaths.cpp b/stdlib/public/runtime/KeyPaths.cpp index f0cad6a4dc1a2..ba3f221b923ac 100644 --- a/stdlib/public/runtime/KeyPaths.cpp +++ b/stdlib/public/runtime/KeyPaths.cpp @@ -39,14 +39,21 @@ static intptr_t hashGenericArguments(const void *src, size_t bytes) { return 0; } +struct KeyPathGenericWitnessTable { + void *destroy; + SWIFT_CC(swift) void (* __ptrauth_swift_runtime_function_entry_with_key(swift::SpecialPointerAuthDiscriminators::KeyPathCopy) copy)(const void *src, void *dest, size_t bytes); + SWIFT_CC(swift) bool (* __ptrauth_swift_runtime_function_entry_with_key(swift::SpecialPointerAuthDiscriminators::KeyPathEquals) equals)(const void *, const void *, size_t); + SWIFT_CC(swift) intptr_t (* __ptrauth_swift_runtime_function_entry_with_key(swift::SpecialPointerAuthDiscriminators::KeyPathHash) hash)(const void *src, size_t bytes); +}; + /// A prefab witness table for computed key path components that only include /// captured generic arguments. SWIFT_RUNTIME_EXPORT -void *(swift_keyPathGenericWitnessTable[]) = { - nullptr, // no destructor necessary - (void*)(uintptr_t)swift_copyKeyPathTrivialIndices, - (void*)(uintptr_t)equateGenericArguments, - (void*)(uintptr_t)hashGenericArguments, +KeyPathGenericWitnessTable swift_keyPathGenericWitnessTable = { + nullptr, + swift_copyKeyPathTrivialIndices, + equateGenericArguments, + hashGenericArguments, }; /****************************************************************************/ @@ -143,7 +150,9 @@ swift::swift_readAtKeyPath(YieldOnceBuffer *buffer, // Return a continuation that destroys the value in the buffer // and deallocates it. - return { &_destroy_temporary_continuation, result }; + return { swift_ptrauth_sign_opaque_read_resume_function( + &_destroy_temporary_continuation, buffer), + result }; } static SWIFT_CC(swift) @@ -158,7 +167,9 @@ swift::swift_modifyAtWritableKeyPath(YieldOnceBuffer *buffer, _swift_modifyAtWritableKeyPath_impl(root, keyPath); buffer->Data[0] = addrAndOwner.Owner; - return { &_release_owner_continuation, addrAndOwner.Addr }; + return { swift_ptrauth_sign_opaque_modify_resume_function( + &_release_owner_continuation, buffer), + addrAndOwner.Addr }; } YieldOnceResult @@ -169,5 +180,7 @@ swift::swift_modifyAtReferenceWritableKeyPath(YieldOnceBuffer *buffer, _swift_modifyAtReferenceWritableKeyPath_impl(root, keyPath); buffer->Data[0] = addrAndOwner.Owner; - return { &_release_owner_continuation, addrAndOwner.Addr }; + return { swift_ptrauth_sign_opaque_modify_resume_function( + &_release_owner_continuation, buffer), + addrAndOwner.Addr }; } diff --git a/stdlib/public/runtime/Metadata.cpp b/stdlib/public/runtime/Metadata.cpp index df4910eab656f..f00bac2a135d5 100644 --- a/stdlib/public/runtime/Metadata.cpp +++ b/stdlib/public/runtime/Metadata.cpp @@ -49,6 +49,11 @@ #include #endif // !defined(__wasi__) #endif +#if SWIFT_PTRAUTH +#include +extern "C" void _objc_setClassCopyFixupHandler(void (* _Nonnull newFixupHandler) + (Class _Nonnull oldClass, Class _Nonnull newClass)); +#endif #include "llvm/ADT/DenseMap.h" #include "llvm/ADT/Hashing.h" #include "CompatibilityOverride.h" @@ -76,6 +81,10 @@ using namespace swift; using namespace metadataimpl; +static ClassMetadata * +_swift_relocateClassMetadata(const ClassDescriptor *description, + const ResilientClassMetadataPattern *pattern); + template<> Metadata *TargetSingletonMetadataInitialization::allocate( const TypeContextDescriptor *description) const { @@ -91,7 +100,7 @@ Metadata *TargetSingletonMetadataInitialization::allocate( // Otherwise, use the default behavior. auto *classDescription = cast(description); - return swift_relocateClassMetadata(classDescription, pattern); + return _swift_relocateClassMetadata(classDescription, pattern); } // Otherwise, we have a static template that we can initialize in-place. @@ -153,7 +162,7 @@ computeMetadataBoundsForSuperclass(const void *ref, TypeReferenceKind refKind) { switch (refKind) { case TypeReferenceKind::IndirectTypeDescriptor: { - auto description = *reinterpret_cast(ref); + auto description = *reinterpret_cast(ref); if (!description) { swift::fatalError(0, "instantiating class metadata for class with " "missing weak-linked ancestor"); @@ -381,6 +390,48 @@ static GenericMetadataCache &unsafeGetInitializedCache( return lazyCache->unsafeGetAlreadyInitialized(); } +#if SWIFT_PTRAUTH +static void swift_objc_classCopyFixupHandler(Class oldClass, Class newClass) { + auto oldClassMetadata = reinterpret_cast(oldClass); + + // Bail out if this isn't a Swift. + if (!oldClassMetadata->isTypeMetadata()) + return; + + // Otherwise, re-sign v-table entries using the extra discriminators stored + // in the v-table descriptor. + + auto *srcWords = reinterpret_cast(oldClass); + auto *dstWords = reinterpret_cast(newClass); + + while (oldClassMetadata && oldClassMetadata->isTypeMetadata()) { + const auto *description = oldClassMetadata->getDescription(); + + // Copy the vtable entries. + if (description && description->hasVTable()) { + auto *vtable = description->getVTableDescriptor(); + auto descriptors = description->getMethodDescriptors(); + auto src = srcWords + vtable->getVTableOffset(description); + auto dest = dstWords + vtable->getVTableOffset(description); + for (size_t i = 0, e = vtable->VTableSize; i != e; ++i) { + swift_ptrauth_copy(reinterpret_cast(&dest[i]), + reinterpret_cast(&src[i]), + descriptors[i].Flags.getExtraDiscriminator()); + } + } + + oldClassMetadata = oldClassMetadata->Superclass; + } +} + +SWIFT_ALLOWED_RUNTIME_GLOBAL_CTOR_BEGIN +static bool fixupHandlerInstaller = [] { + _objc_setClassCopyFixupHandler(&swift_objc_classCopyFixupHandler); + return true; +}(); +SWIFT_ALLOWED_RUNTIME_GLOBAL_CTOR_END +#endif + #if SWIFT_OBJC_INTEROP extern "C" void *_objc_empty_cache; #endif @@ -507,6 +558,9 @@ ClassMetadata * swift::swift_allocateGenericClassMetadata(const ClassDescriptor *description, const void *arguments, const GenericClassMetadataPattern *pattern){ + description = swift_auth_data_non_address( + description, SpecialPointerAuthDiscriminators::TypeDescriptor); + auto &generics = description->getFullGenericContextHeader(); auto &cache = unsafeGetInitializedCache(generics); @@ -574,6 +628,8 @@ swift::swift_allocateGenericValueMetadata(const ValueTypeDescriptor *description const void *arguments, const GenericValueMetadataPattern *pattern, size_t extraDataSize) { + description = swift_auth_data_non_address(description, SpecialPointerAuthDiscriminators::TypeDescriptor); + auto &generics = description->getFullGenericContextHeader(); auto &cache = unsafeGetInitializedCache(generics); @@ -608,6 +664,7 @@ MetadataResponse swift::swift_getGenericMetadata(MetadataRequest request, const void * const *arguments, const TypeContextDescriptor *description) { + description = swift_auth_data_non_address(description, SpecialPointerAuthDiscriminators::TypeDescriptor); auto &cache = getCache(*description); assert(description->getFullGenericContextHeader().Base.NumKeyArguments == cache.NumKeyParameters + cache.NumWitnessTables); @@ -1219,7 +1276,7 @@ static void tuple_destroy(OpaqueValue *tuple, const Metadata *_metadata) { // The operation doesn't have to be initializeWithCopy, but they all // have basically the same type. -typedef ValueWitnessTypes::initializeWithCopy forEachOperation; +typedef ValueWitnessTypes::initializeWithCopyUnsigned forEachOperation; /// Perform an operation for each field of two tuples. static OpaqueValue *tuple_forEachField(OpaqueValue *destTuple, @@ -1488,7 +1545,6 @@ static void performBasicLayout(TypeLayout &layout, layout.stride = std::max(size_t(1), roundUpToAlignMask(size, alignMask)); } - size_t swift::swift_getTupleTypeLayout2(TypeLayout *result, const TypeLayout *elt0, const TypeLayout *elt1) { @@ -1547,7 +1603,7 @@ swift::swift_getTupleTypeMetadata(MetadataRequest request, // Bypass the cache for the empty tuple. We might reasonably get called // by generic code, like a demangler that produces type objects. if (numElements == 0) - return { &METADATA_SYM(EMPTY_TUPLE_MANGLING), MetadataState::Complete }; + return MetadataResponse{ &METADATA_SYM(EMPTY_TUPLE_MANGLING), MetadataState::Complete }; // Search the cache. TupleCacheEntry::Key key = { numElements, elements, labels }; @@ -1625,7 +1681,7 @@ TupleCacheEntry::tryInitialize(Metadata *metadata, auto request = MetadataRequest(MetadataState::LayoutComplete, /*non-blocking*/ true); auto eltType = Data.getElement(i).Type; - auto response = swift_checkMetadataState(request, eltType); + MetadataResponse response = swift_checkMetadataState(request, eltType); // Immediately continue in the most common scenario, which is that // the element is transitively complete. @@ -2064,6 +2120,15 @@ static MetadataAllocator &getResilientMetadataAllocator() { ClassMetadata * swift::swift_relocateClassMetadata(const ClassDescriptor *description, const ResilientClassMetadataPattern *pattern) { + description = swift_auth_data_non_address( + description, SpecialPointerAuthDiscriminators::TypeDescriptor); + + return _swift_relocateClassMetadata(description, pattern); +} + +static ClassMetadata * +_swift_relocateClassMetadata(const ClassDescriptor *description, + const ResilientClassMetadataPattern *pattern) { auto bounds = description->getMetadataBounds(); auto metadata = reinterpret_cast( @@ -2320,9 +2385,18 @@ static void copySuperclassMetadataToSubclass(ClassMetadata *theClass, if (description->hasVTable() && !hasStaticVTable(layoutFlags)) { auto *vtable = description->getVTableDescriptor(); auto vtableOffset = vtable->getVTableOffset(description); - memcpy(classWords + vtableOffset, - superWords + vtableOffset, - vtable->VTableSize * sizeof(uintptr_t)); + auto dest = classWords + vtableOffset; + auto src = superWords + vtableOffset; +#if SWIFT_PTRAUTH + auto descriptors = description->getMethodDescriptors(); + for (size_t i = 0, e = vtable->VTableSize; i != e; ++i) { + swift_ptrauth_copy(reinterpret_cast(&dest[i]), + reinterpret_cast(&src[i]), + descriptors[i].Flags.getExtraDiscriminator()); + } +#else + memcpy(dest, src, vtable->VTableSize * sizeof(uintptr_t)); +#endif } // Copy the field offsets. @@ -2360,8 +2434,13 @@ static void initClassVTable(ClassMetadata *self) { if (description->hasVTable()) { auto *vtable = description->getVTableDescriptor(); auto vtableOffset = vtable->getVTableOffset(description); - for (unsigned i = 0, e = vtable->VTableSize; i < e; ++i) - classWords[vtableOffset + i] = description->getMethod(i); + auto descriptors = description->getMethodDescriptors(); + for (unsigned i = 0, e = vtable->VTableSize; i < e; ++i) { + auto &methodDescription = descriptors[i]; + swift_ptrauth_init(&classWords[vtableOffset + i], + methodDescription.Impl.get(), + methodDescription.Flags.getExtraDiscriminator()); + } } if (description->hasOverrideTable()) { @@ -2396,9 +2475,12 @@ static void initClassVTable(ClassMetadata *self) { // Install the method override in our vtable. auto baseVTable = baseClass->getVTableDescriptor(); - auto offset = baseMethod - baseClassMethods.data(); - classWords[baseVTable->getVTableOffset(baseClass) + offset] - = descriptor.Impl.get(); + auto offset = (baseVTable->getVTableOffset(baseClass) + + (baseMethod - baseClassMethods.data())); + + swift_ptrauth_init(&classWords[offset], + descriptor.Impl.get(), + baseMethod->Flags.getExtraDiscriminator()); } } } @@ -2949,7 +3031,19 @@ swift::swift_lookUpClassMethod(const ClassMetadata *metadata, auto vtableOffset = vtable->getVTableOffset(description) + index; auto *words = reinterpret_cast(metadata); - return *(words + vtableOffset); + auto *const *methodPtr = (words + vtableOffset); + +#if SWIFT_PTRAUTH + // Re-sign the return value without the address. + unsigned extra = method->Flags.getExtraDiscriminator(); + return ptrauth_auth_and_resign(*methodPtr, + ptrauth_key_function_pointer, + ptrauth_blend_discriminator(methodPtr, extra), + ptrauth_key_function_pointer, + extra); +#else + return *methodPtr; +#endif } /***************************************************************************/ @@ -4207,6 +4301,110 @@ static bool doesNotRequireInstantiation( return true; } +static const unsigned swift_ptrauth_key_associated_type = + swift_ptrauth_key_associated_type; + +/// Given an unsigned pointer to an associated-type protocol witness, +/// fill in the appropriate slot in the witness table we're building. +static void initAssociatedTypeProtocolWitness(const Metadata **slot, + const Metadata *witness, + const ProtocolRequirement &reqt) { + assert(reqt.Flags.getKind() == + ProtocolRequirementFlags::Kind::AssociatedTypeAccessFunction); + // FIXME: this should use ptrauth_key_process_independent_data + // now that it no longer stores a function pointer. + swift_ptrauth_init(slot, witness, reqt.Flags.getExtraDiscriminator()); +} + +static const unsigned swift_ptrauth_key_associated_conformance = + swift_ptrauth_key_associated_conformance; + +#if SWIFT_PTRAUTH +/// Given an unsigned pointer to an associated-conformance protocol witness, +/// fill in the appropriate slot in the witness table we're building. +static void initAssociatedConformanceProtocolWitness(void **slot, void *witness, + const ProtocolRequirement &reqt) { + assert(reqt.Flags.getKind() == + ProtocolRequirementFlags::Kind::AssociatedConformanceAccessFunction); + // FIXME: this should use ptrauth_key_process_independent_data + // now that it no longer stores a function pointer. + swift_ptrauth_init(slot, witness, reqt.Flags.getExtraDiscriminator()); +} +#endif + +/// Given an unsigned pointer to an arbitrary protocol witness, fill +/// in a slot in the witness table we're building. +static void initProtocolWitness(void **slot, void *witness, + const ProtocolRequirement &reqt) { +#if SWIFT_PTRAUTH + switch (reqt.Flags.getKind()) { + // Base protocols use no signing at all right now. + case ProtocolRequirementFlags::Kind::BaseProtocol: + *slot = witness; + return; + + // Method requirements use address-discriminated signing with the + // function-pointer key. + case ProtocolRequirementFlags::Kind::Method: + case ProtocolRequirementFlags::Kind::Init: + case ProtocolRequirementFlags::Kind::Getter: + case ProtocolRequirementFlags::Kind::Setter: + case ProtocolRequirementFlags::Kind::ReadCoroutine: + case ProtocolRequirementFlags::Kind::ModifyCoroutine: + swift_ptrauth_init(slot, witness, reqt.Flags.getExtraDiscriminator()); + return; + + case ProtocolRequirementFlags::Kind::AssociatedConformanceAccessFunction: + initAssociatedConformanceProtocolWitness(slot, witness, reqt); + return; + + case ProtocolRequirementFlags::Kind::AssociatedTypeAccessFunction: + initAssociatedTypeProtocolWitness(reinterpret_cast( + const_cast(slot)), + reinterpret_cast( + witness), + reqt); + return; + } + swift_runtime_unreachable("bad witness kind"); +#else + *slot = witness; +#endif +} + +/// Copy an arbitrary protocol witness from another table. +static void copyProtocolWitness(void **dest, void * const *src, + const ProtocolRequirement &reqt) { +#if SWIFT_PTRAUTH + switch (reqt.Flags.getKind()) { + // Base protocols use no signing at all right now. + case ProtocolRequirementFlags::Kind::BaseProtocol: + *dest = *src; + return; + + // Method requirements use address-discriminated signing with the + // function-pointer key. + case ProtocolRequirementFlags::Kind::Method: + case ProtocolRequirementFlags::Kind::Init: + case ProtocolRequirementFlags::Kind::Getter: + case ProtocolRequirementFlags::Kind::Setter: + case ProtocolRequirementFlags::Kind::ReadCoroutine: + case ProtocolRequirementFlags::Kind::ModifyCoroutine: + swift_ptrauth_copy(dest, src, reqt.Flags.getExtraDiscriminator()); + return; + + // FIXME: these should both use ptrauth_key_process_independent_data now. + case ProtocolRequirementFlags::Kind::AssociatedConformanceAccessFunction: + case ProtocolRequirementFlags::Kind::AssociatedTypeAccessFunction: + swift_ptrauth_copy(dest, src, reqt.Flags.getExtraDiscriminator()); + return; + } + swift_runtime_unreachable("bad witness kind"); +#else + *dest = *src; +#endif +} + /// Initialize witness table entries from order independent resilient /// witnesses stored in the generic witness table structure itself. static void initializeResilientWitnessTable( @@ -4240,7 +4438,10 @@ static void initializeResilientWitnessTable( unsigned witnessIndex = (reqDescriptor - requirements.data()) + WitnessTableFirstRequirementOffset; - table[witnessIndex] = witness.Witness.get(); + auto &reqt = requirements[reqDescriptor - requirements.begin()]; + // This is an unsigned pointer formed from a relative address. + void *impl = witness.Witness.get(); + initProtocolWitness(&table[witnessIndex], impl, reqt); } // Loop over the requirements, filling in default implementations where @@ -4252,19 +4453,21 @@ static void initializeResilientWitnessTable( // If we already have a witness, there's nothing to do. auto &reqt = requirements[i]; if (!table[witnessIndex]) { + // This is an unsigned pointer formed from a relative address. void *impl = reqt.DefaultImplementation.get(); - table[witnessIndex] = impl; + initProtocolWitness(&table[witnessIndex], impl, reqt); } // Realize base protocol witnesses. if (reqt.Flags.getKind() == ProtocolRequirementFlags::Kind::BaseProtocol && table[witnessIndex]) { - // Realize the base protocol witness table. + // Realize the base protocol witness table. We call the slow function + // because the fast function doesn't allow base protocol requirements. auto baseReq = protocol->getRequirementBaseDescriptor(); - (void)swift_getAssociatedConformanceWitness((WitnessTable *)table, - conformingType, - conformingType, - baseReq, &reqt); + (void)swift_getAssociatedConformanceWitnessSlow((WitnessTable *)table, + conformingType, + conformingType, + baseReq, &reqt); } } } @@ -4302,9 +4505,16 @@ WitnessTableCacheEntry::allocate( if (auto pattern = reinterpret_cast( &*conformance->getWitnessTablePattern())) { + auto requirements = protocol->getRequirements(); + // Fill in the provided part of the requirements from the pattern. for (size_t i = 0, e = numPatternWitnesses; i < e; ++i) { - table[i] = pattern[i]; + size_t requirementIndex = i - WitnessTableFirstRequirementOffset; + if (i < WitnessTableFirstRequirementOffset) + table[i] = pattern[i]; + else + copyProtocolWitness(&table[i], &pattern[i], + requirements[requirementIndex]); } } else { // Put the conformance descriptor in place. Instantiation will fill in the @@ -4425,9 +4635,19 @@ swift_getAssociatedTypeWitnessSlowImpl( } #endif - // If the low bit of the witness is clear, it's already a metadata pointer. + // Retrieve the witness. unsigned witnessIndex = assocType - reqBase; - auto witness = ((const void* const *)wtable)[witnessIndex]; + auto *witnessAddr = &((const Metadata **)wtable)[witnessIndex]; + auto witness = *witnessAddr; + +#if SWIFT_PTRAUTH + uint16_t extraDiscriminator = assocType->Flags.getExtraDiscriminator(); + witness = ptrauth_auth_data(witness, swift_ptrauth_key_associated_type, + ptrauth_blend_discriminator(witnessAddr, + extraDiscriminator)); +#endif + + // If the low bit of the witness is clear, it's already a metadata pointer. if (LLVM_LIKELY((uintptr_t(witness) & ProtocolRequirementFlags::AssociatedTypeMangledNameBit) == 0)) { // Cached metadata pointers are always complete. @@ -4519,7 +4739,10 @@ swift_getAssociatedTypeWitnessSlowImpl( // If the metadata was completed, record it in the witness table. if (response.State == MetadataState::Complete) { - reinterpret_cast(wtable)[witnessIndex] = assocTypeMetadata; + // We pass type metadata around as unsigned pointers, but we sign them + // in witness tables, which doesn't provide all that much extra security. + initAssociatedTypeProtocolWitness(witnessAddr, assocTypeMetadata, + *assocType); } return response; @@ -4531,9 +4754,21 @@ swift::swift_getAssociatedTypeWitness(MetadataRequest request, const Metadata *conformingType, const ProtocolRequirement *reqBase, const ProtocolRequirement *assocType) { + assert(assocType->Flags.getKind() == + ProtocolRequirementFlags::Kind::AssociatedTypeAccessFunction); + // If the low bit of the witness is clear, it's already a metadata pointer. unsigned witnessIndex = assocType - reqBase; - auto witness = ((const void* const *)wtable)[witnessIndex]; + auto *witnessAddr = &((const void* *)wtable)[witnessIndex]; + auto witness = *witnessAddr; + +#if SWIFT_PTRAUTH + uint16_t extraDiscriminator = assocType->Flags.getExtraDiscriminator(); + witness = ptrauth_auth_data(witness, swift_ptrauth_key_associated_type, + ptrauth_blend_discriminator(witnessAddr, + extraDiscriminator)); +#endif + if (LLVM_LIKELY((uintptr_t(witness) & ProtocolRequirementFlags::AssociatedTypeMangledNameBit) == 0)) { // Cached metadata pointers are always complete. @@ -4569,7 +4804,22 @@ static const WitnessTable *swift_getAssociatedConformanceWitnessSlowImpl( // Retrieve the witness. unsigned witnessIndex = assocConformance - reqBase; - auto witness = ((const void* const *)wtable)[witnessIndex]; + auto *witnessAddr = &((void**)wtable)[witnessIndex]; + auto witness = *witnessAddr; + +#if SWIFT_PTRAUTH + // For associated protocols, the witness is signed with address + // discrimination. + // For base protocols, the witness isn't signed at all. + if (assocConformance->Flags.isSignedWithAddress()) { + uint16_t extraDiscriminator = + assocConformance->Flags.getExtraDiscriminator(); + witness = ptrauth_auth_data( + witness, swift_ptrauth_key_associated_conformance, + ptrauth_blend_discriminator(witnessAddr, extraDiscriminator)); + } +#endif + // Fast path: we've already resolved this to a witness table, so return it. if (LLVM_LIKELY((uintptr_t(witness) & ProtocolRequirementFlags::AssociatedTypeMangledNameBit) == 0)) { @@ -4601,13 +4851,21 @@ static const WitnessTable *swift_getAssociatedConformanceWitnessSlowImpl( // Call the witness function. auto witnessFn = (AssociatedWitnessTableAccessFunction *)ptr; - auto assocWitnessTable = witnessFn(assocType, conformingType, wtable); +#if SWIFT_PTRAUTH + witnessFn = ptrauth_sign_unauthenticated(witnessFn, + ptrauth_key_function_pointer, + 0); +#endif + auto assocWitnessTable = witnessFn(assocType, conformingType, wtable); assert((uintptr_t(assocWitnessTable) & ProtocolRequirementFlags::AssociatedTypeMangledNameBit) == 0); - // Update the cache. - reinterpret_cast(wtable)[witnessIndex] = assocWitnessTable; + // The access function returns an unsigned pointer for now. + + // We can't just use initAssociatedConformanceProtocolWitness because we + // also use this function for base protocols. + initProtocolWitness(witnessAddr, assocWitnessTable, *assocConformance); return assocWitnessTable; } @@ -4621,9 +4879,23 @@ const WitnessTable *swift::swift_getAssociatedConformanceWitness( const Metadata *assocType, const ProtocolRequirement *reqBase, const ProtocolRequirement *assocConformance) { + // We avoid using this function for initializing base protocol conformances + // so that we can have a better fast-path. + assert(assocConformance->Flags.getKind() == + ProtocolRequirementFlags::Kind::AssociatedConformanceAccessFunction); + // Retrieve the witness. unsigned witnessIndex = assocConformance - reqBase; - auto witness = ((const void* const *)wtable)[witnessIndex]; + auto *witnessAddr = &((const void* *)wtable)[witnessIndex]; + auto witness = *witnessAddr; + +#if SWIFT_PTRAUTH + uint16_t extraDiscriminator = assocConformance->Flags.getExtraDiscriminator(); + witness = ptrauth_auth_data(witness, swift_ptrauth_key_associated_conformance, + ptrauth_blend_discriminator(witnessAddr, + extraDiscriminator)); +#endif + // Fast path: we've already resolved this to a witness table, so return it. if (LLVM_LIKELY((uintptr_t(witness) & ProtocolRequirementFlags::AssociatedTypeMangledNameBit) == 0)) { @@ -4955,7 +5227,8 @@ checkTransitiveCompleteness(const Metadata *initialType) { // Check the metadata's current state with a non-blocking request. auto request = MetadataRequest(MetadataState::Complete, /*non-blocking*/ true); - auto state = swift_checkMetadataState(request, type).State; + auto state = + MetadataResponse(swift_checkMetadataState(request, type)).State; // If it's transitively complete, we're done. // This is the most likely result. diff --git a/stdlib/public/runtime/MetadataLookup.cpp b/stdlib/public/runtime/MetadataLookup.cpp index dedbebd8591d2..8c1efa232cbf4 100644 --- a/stdlib/public/runtime/MetadataLookup.cpp +++ b/stdlib/public/runtime/MetadataLookup.cpp @@ -72,16 +72,39 @@ class DemanglerForRuntimeTypeResolution : public Base { } }; +/// Resolve the relative reference in a mangled symbolic reference. +static uintptr_t resolveSymbolicReferenceOffset(SymbolicReferenceKind kind, + Directness isIndirect, + int32_t offset, + const void *base) { + auto ptr = detail::applyRelativeOffset(base, offset); + + // Indirect references may be authenticated in a way appropriate for the + // referent. + if (isIndirect == Directness::Indirect) { + switch (kind) { + case SymbolicReferenceKind::Context: { + ContextDescriptor *contextPtr = + *(const TargetSignedContextPointer *)ptr; + return (uintptr_t)contextPtr; + } + case SymbolicReferenceKind::AccessorFunctionReference: { + swift_runtime_unreachable("should not be indirectly referenced"); + } + } + swift_runtime_unreachable("unknown symbolic reference kind"); + } else { + return ptr; + } +} + NodePointer ResolveAsSymbolicReference::operator()(SymbolicReferenceKind kind, Directness isIndirect, int32_t offset, const void *base) { // Resolve the absolute pointer to the entity being referenced. - auto ptr = detail::applyRelativeOffset(base, offset); - if (isIndirect == Directness::Indirect) { - ptr = *(const uintptr_t *)ptr; - } + auto ptr = resolveSymbolicReferenceOffset(kind, isIndirect, offset, base); // Figure out this symbolic reference's grammatical role. Node::Kind nodeKind; @@ -118,6 +141,11 @@ ResolveAsSymbolicReference::operator()(SymbolicReferenceKind kind, // invoke the function to resolve the thing they're trying to access. nodeKind = Node::Kind::AccessorFunctionReference; isType = false; +#if SWIFT_PTRAUTH + // The pointer refers to an accessor function, which we need to sign. + ptr = (uintptr_t)ptrauth_sign_unauthenticated((void*)ptr, + ptrauth_key_function_pointer, 0); +#endif break; } } @@ -140,6 +168,11 @@ _buildDemanglingForSymbolicReference(SymbolicReferenceKind kind, return _buildDemanglingForContext( (const ContextDescriptor *)resolvedReference, {}, Dem); case SymbolicReferenceKind::AccessorFunctionReference: +#if SWIFT_PTRAUTH + // The pointer refers to an accessor function, which we need to sign. + resolvedReference = ptrauth_sign_unauthenticated(resolvedReference, + ptrauth_key_function_pointer, 0); +#endif return Dem.createNode(Node::Kind::AccessorFunctionReference, (uintptr_t)resolvedReference); } @@ -152,11 +185,8 @@ ResolveToDemanglingForContext::operator()(SymbolicReferenceKind kind, Directness isIndirect, int32_t offset, const void *base) { - auto ptr = detail::applyRelativeOffset(base, offset); - if (isIndirect == Directness::Indirect) { - ptr = *(const uintptr_t *)ptr; - } - + auto ptr = resolveSymbolicReferenceOffset(kind, isIndirect, offset, base); + return _buildDemanglingForSymbolicReference(kind, (const void *)ptr, Dem); } @@ -1371,10 +1401,11 @@ class DecodedMetadataBuilder { auto flags = TupleTypeFlags().withNumElements(elements.size()); if (!labels.empty()) flags = flags.withNonConstantLabels(true); - return swift_getTupleTypeMetadata(MetadataState::Abstract, - flags, elements.data(), - labels.empty() ? nullptr : labels.c_str(), - /*proposedWitnesses=*/nullptr).Value; + return MetadataResponse(swift_getTupleTypeMetadata( + MetadataState::Abstract, flags, elements.data(), + labels.empty() ? nullptr : labels.c_str(), + /*proposedWitnesses=*/nullptr)) + .Value; } BuiltType createDependentMemberType(StringRef name, BuiltType base) const { @@ -1459,7 +1490,7 @@ static TypeInfo swift_getTypeByMangledNodeImpl( // The accessor function is passed the pointer to the original argument // buffer. It's assumed to match the generic context. auto accessorFn = - (const Metadata *(*)(const void * const *))node->getIndex(); + (const Metadata *(*)(const void * const *))node->getIndex(); auto type = accessorFn(origArgumentVector); // We don't call checkMetadataState here since the result may not really // *be* type metadata. If the accessor returns a type, it is responsible @@ -2090,18 +2121,31 @@ void DynamicReplacementDescriptor::enableReplacement() const { if (!shouldChain() && chainRoot->next) { auto *previous = chainRoot->next; chainRoot->next = previous->next; - chainRoot->implementationFunction = previous->implementationFunction; + //chainRoot->implementationFunction = previous->implementationFunction; + swift_ptrauth_copy( + reinterpret_cast(&chainRoot->implementationFunction), + reinterpret_cast(&previous->implementationFunction), + replacedFunctionKey->getExtraDiscriminator()); } // First populate the current replacement's chain entry. auto *currentEntry = const_cast(chainEntry.get()); - currentEntry->implementationFunction = chainRoot->implementationFunction; + // currentEntry->implementationFunction = chainRoot->implementationFunction; + swift_ptrauth_copy( + reinterpret_cast(¤tEntry->implementationFunction), + reinterpret_cast(&chainRoot->implementationFunction), + replacedFunctionKey->getExtraDiscriminator()); + currentEntry->next = chainRoot->next; // Link the replacement entry. chainRoot->next = chainEntry.get(); - chainRoot->implementationFunction = replacementFunction.get(); + // chainRoot->implementationFunction = replacementFunction.get(); + swift_ptrauth_init( + reinterpret_cast(&chainRoot->implementationFunction), + reinterpret_cast(replacementFunction.get()), + replacedFunctionKey->getExtraDiscriminator()); } void DynamicReplacementDescriptor::disableReplacement() const { @@ -2121,7 +2165,11 @@ void DynamicReplacementDescriptor::disableReplacement() const { // Unlink this entry. auto *previous = const_cast(prev); previous->next = thisEntry->next; - previous->implementationFunction = thisEntry->implementationFunction; + // previous->implementationFunction = thisEntry->implementationFunction; + swift_ptrauth_copy( + reinterpret_cast(&previous->implementationFunction), + reinterpret_cast(&thisEntry->implementationFunction), + replacedFunctionKey->getExtraDiscriminator()); } /// An automatic dymamic replacement entry. @@ -2166,7 +2214,10 @@ class AutomaticDynamicReplacements /// A map from original to replaced opaque type descriptor of a some type. class DynamicReplacementSomeDescriptor { - RelativeIndirectablePointer + RelativeIndirectablePointer< + const OpaqueTypeDescriptor, false, int32_t, + TargetSignedPointer> originalOpaqueTypeDesc; RelativeDirectPointer replacementOpaqueTypeDesc; @@ -2263,11 +2314,15 @@ void swift::addImageDynamicReplacementBlockCallback( void swift::swift_enableDynamicReplacementScope( const DynamicReplacementScope *scope) { + scope = swift_auth_data_non_address( + scope, SpecialPointerAuthDiscriminators::DynamicReplacementScope); DynamicReplacementLock.get().withLock([=] { scope->enable(); }); } void swift::swift_disableDynamicReplacementScope( const DynamicReplacementScope *scope) { + scope = swift_auth_data_non_address( + scope, SpecialPointerAuthDiscriminators::DynamicReplacementScope); DynamicReplacementLock.get().withLock([=] { scope->disable(); }); } #define OVERRIDE_METADATALOOKUP COMPATIBILITY_OVERRIDE diff --git a/stdlib/toolchain/CompatibilityDynamicReplacements/DynamicReplaceable.cpp b/stdlib/toolchain/CompatibilityDynamicReplacements/DynamicReplaceable.cpp index b4d3a3e7ff780..e2dcc24b6e774 100644 --- a/stdlib/toolchain/CompatibilityDynamicReplacements/DynamicReplaceable.cpp +++ b/stdlib/toolchain/CompatibilityDynamicReplacements/DynamicReplaceable.cpp @@ -32,6 +32,10 @@ extern "C" char *swift_getFunctionReplacement50(char **ReplFnPtr, char *CurrFn) char *ReplFn = *ReplFnPtr; char *RawReplFn = ReplFn; +#if SWIFT_PTRAUTH + RawReplFn = ptrauth_strip(RawReplFn, ptrauth_key_function_pointer); +#endif + if (RawReplFn == CurrFn) return nullptr; diff --git a/stdlib/toolchain/legacy_layouts/iphoneos/layouts-arm64e.yaml b/stdlib/toolchain/legacy_layouts/iphoneos/layouts-arm64e.yaml new file mode 100644 index 0000000000000..a9f22fcda8e8b --- /dev/null +++ b/stdlib/toolchain/legacy_layouts/iphoneos/layouts-arm64e.yaml @@ -0,0 +1,452 @@ +--- +Name: ARKit +Decls: + - Name: So13ARPlaneAnchorC5ARKitE14ClassificationO + Size: 1 + Alignment: 1 + ExtraInhabitants: 248 + - Name: So13ARPlaneAnchorC5ARKitE14ClassificationO6StatusO + Size: 1 + Alignment: 1 + ExtraInhabitants: 253 + - Name: So8ARCameraC5ARKitE13TrackingStateO6ReasonO + Size: 1 + Alignment: 1 + ExtraInhabitants: 252 +... +--- +Name: AVFoundation +Decls: + - Name: So35AVCaptureSynchronizedDataCollectionC12AVFoundationE8IteratorV + Size: 217 + Alignment: 8 + ExtraInhabitants: 2147483647 +... +--- +Name: CloudKit +Decls: + - Name: 8CloudKit24CKRecordKeyValueIteratorV + Size: 24 + Alignment: 8 + ExtraInhabitants: 2147483647 + - Name: So11CKContainerC8CloudKitE11ApplicationO + Size: 0 + Alignment: 1 + ExtraInhabitants: 0 + - Name: So7CKShareC8CloudKitE14SystemFieldKeyO + Size: 0 + Alignment: 1 + ExtraInhabitants: 0 + - Name: So8CKRecordC8CloudKitE10SystemTypeO + Size: 0 + Alignment: 1 + ExtraInhabitants: 0 + - Name: So8CKRecordC8CloudKitE14SystemFieldKeyO + Size: 0 + Alignment: 1 + ExtraInhabitants: 0 +... +--- +Name: CoreAudio +Decls: + - Name: 9CoreAudio013UnsafeMutableB17BufferListPointerV + Size: 8 + Alignment: 8 + ExtraInhabitants: 1 +... +--- +Name: CoreGraphics +Decls: + - Name: 12CoreGraphics14CGPathFillRuleO + Size: 1 + Alignment: 1 + ExtraInhabitants: 254 +... +--- +Name: Dispatch +Decls: + - Name: 8Dispatch0A12DataIteratorV + Size: 32 + Alignment: 8 + ExtraInhabitants: 2147483647 + - Name: 8Dispatch0A12TimeIntervalO + Size: 9 + Alignment: 8 + ExtraInhabitants: 251 + - Name: 8Dispatch0A13WorkItemFlagsV + Size: 8 + Alignment: 8 + ExtraInhabitants: 0 + - Name: 8Dispatch0A3QoSV + Size: 16 + Alignment: 8 + ExtraInhabitants: 250 + - Name: 8Dispatch0A3QoSV0B6SClassO + Size: 1 + Alignment: 1 + ExtraInhabitants: 250 + - Name: 8Dispatch0A4DataV + Size: 8 + Alignment: 8 + ExtraInhabitants: 2147483647 + - Name: 8Dispatch0A4DataV11DeallocatorO + Size: 16 + Alignment: 8 + ExtraInhabitants: 2147483645 + - Name: 8Dispatch0A4TimeV + Size: 8 + Alignment: 8 + ExtraInhabitants: 0 + - Name: 8Dispatch0A8WallTimeV + Size: 8 + Alignment: 8 + ExtraInhabitants: 0 + - Name: 8Dispatch0A9PredicateO + Size: 9 + Alignment: 8 + ExtraInhabitants: 253 + - Name: So14OS_dispatch_ioC8DispatchE10CloseFlagsV + Size: 8 + Alignment: 8 + ExtraInhabitants: 0 + - Name: So14OS_dispatch_ioC8DispatchE10StreamTypeO + Size: 1 + Alignment: 1 + ExtraInhabitants: 254 + - Name: So14OS_dispatch_ioC8DispatchE13IntervalFlagsV + Size: 8 + Alignment: 8 + ExtraInhabitants: 0 + - Name: So17OS_dispatch_queueC8DispatchE10AttributesV + Size: 8 + Alignment: 8 + ExtraInhabitants: 0 + - Name: So17OS_dispatch_queueC8DispatchE19GlobalQueuePriorityO + Size: 1 + Alignment: 1 + ExtraInhabitants: 252 + - Name: So17OS_dispatch_queueC8DispatchE20AutoreleaseFrequencyO + Size: 1 + Alignment: 1 + ExtraInhabitants: 253 + - Name: So18OS_dispatch_sourceC8DispatchE10TimerFlagsV + Size: 8 + Alignment: 8 + ExtraInhabitants: 0 + - Name: So18OS_dispatch_sourceC8DispatchE12ProcessEventV + Size: 8 + Alignment: 8 + ExtraInhabitants: 0 + - Name: So18OS_dispatch_sourceC8DispatchE13MachSendEventV + Size: 8 + Alignment: 8 + ExtraInhabitants: 0 + - Name: So18OS_dispatch_sourceC8DispatchE15FileSystemEventV + Size: 8 + Alignment: 8 + ExtraInhabitants: 0 + - Name: So18OS_dispatch_sourceC8DispatchE19MemoryPressureEventV + Size: 8 + Alignment: 8 + ExtraInhabitants: 0 +... +--- +Name: Foundation +Decls: + - Name: 10Foundation10CocoaErrorV + Size: 8 + Alignment: 8 + ExtraInhabitants: 2147483647 + - Name: 10Foundation10CocoaErrorV4CodeV + Size: 8 + Alignment: 8 + ExtraInhabitants: 0 + - Name: 10Foundation10POSIXErrorV + Size: 8 + Alignment: 8 + ExtraInhabitants: 2147483647 + - Name: 10Foundation10URLRequestV + Size: 8 + Alignment: 8 + ExtraInhabitants: 2147483647 + - Name: 10Foundation11JSONDecoderC19KeyDecodingStrategyO + Size: 16 + Alignment: 8 + ExtraInhabitants: 2147483645 + - Name: 10Foundation11JSONDecoderC20DataDecodingStrategyO + Size: 16 + Alignment: 8 + ExtraInhabitants: 2147483645 + - Name: 10Foundation11JSONDecoderC20DateDecodingStrategyO + Size: 17 + Alignment: 8 + ExtraInhabitants: 253 + - Name: 10Foundation11JSONDecoderC34NonConformingFloatDecodingStrategyO + Size: 48 + Alignment: 8 + ExtraInhabitants: 2147483646 + - Name: 10Foundation11JSONEncoderC16OutputFormattingV + Size: 8 + Alignment: 8 + ExtraInhabitants: 0 + - Name: 10Foundation11JSONEncoderC19KeyEncodingStrategyO + Size: 16 + Alignment: 8 + ExtraInhabitants: 2147483645 + - Name: 10Foundation11JSONEncoderC20DataEncodingStrategyO + Size: 16 + Alignment: 8 + ExtraInhabitants: 2147483645 + - Name: 10Foundation11JSONEncoderC20DateEncodingStrategyO + Size: 17 + Alignment: 8 + ExtraInhabitants: 253 + - Name: 10Foundation11JSONEncoderC34NonConformingFloatEncodingStrategyO + Size: 48 + Alignment: 8 + ExtraInhabitants: 2147483646 + - Name: 10Foundation11MeasurementV + Size: 16 + Alignment: 8 + ExtraInhabitants: 2147483647 + - Name: 10Foundation12CharacterSetV + Size: 8 + Alignment: 8 + ExtraInhabitants: 2147483647 + - Name: 10Foundation12DateIntervalV + Size: 16 + Alignment: 8 + ExtraInhabitants: 0 + - Name: 10Foundation12NotificationV + Size: 48 + Alignment: 8 + ExtraInhabitants: 2147483647 + - Name: 10Foundation12URLQueryItemV + Size: 8 + Alignment: 8 + ExtraInhabitants: 2147483647 + - Name: 10Foundation13URLComponentsV + Size: 8 + Alignment: 8 + ExtraInhabitants: 2147483647 + - Name: 10Foundation14DateComponentsV + Size: 8 + Alignment: 8 + ExtraInhabitants: 2147483647 + - Name: 10Foundation16ErrorUserInfoKeyV + Size: 16 + Alignment: 8 + ExtraInhabitants: 2147483647 + - Name: 10Foundation17URLResourceValuesV + Size: 16 + Alignment: 8 + ExtraInhabitants: 2147483647 + - Name: 10Foundation18NSIndexSetIteratorV + Size: 25 + Alignment: 8 + ExtraInhabitants: 2147483647 + - Name: 10Foundation20PersonNameComponentsV + Size: 8 + Alignment: 8 + ExtraInhabitants: 2147483647 + - Name: 10Foundation25NSFastEnumerationIteratorV + Size: 217 + Alignment: 8 + ExtraInhabitants: 2147483647 + - Name: 10Foundation3URLV + Size: 8 + Alignment: 8 + ExtraInhabitants: 2147483647 + - Name: 10Foundation4DataV11DeallocatorO + Size: 16 + Alignment: 8 + ExtraInhabitants: 2147483643 + - Name: 10Foundation4DataV8IteratorV + Size: 64 + Alignment: 8 + ExtraInhabitants: 12 + - Name: 10Foundation4DateV + Size: 8 + Alignment: 8 + ExtraInhabitants: 0 + - Name: 10Foundation4UUIDV + Size: 16 + Alignment: 1 + ExtraInhabitants: 0 + - Name: 10Foundation6LocaleV + Size: 9 + Alignment: 8 + ExtraInhabitants: 2147483647 + - Name: 10Foundation8CalendarV + Size: 16 + Alignment: 8 + ExtraInhabitants: 2147483647 + - Name: 10Foundation8CalendarV10IdentifierO + Size: 1 + Alignment: 1 + ExtraInhabitants: 240 + - Name: 10Foundation8CalendarV14MatchingPolicyO + Size: 1 + Alignment: 1 + ExtraInhabitants: 252 + - Name: 10Foundation8CalendarV15SearchDirectionO + Size: 1 + Alignment: 1 + ExtraInhabitants: 254 + - Name: 10Foundation8CalendarV18RepeatedTimePolicyO + Size: 1 + Alignment: 1 + ExtraInhabitants: 254 + - Name: 10Foundation8CalendarV9ComponentO + Size: 1 + Alignment: 1 + ExtraInhabitants: 240 + - Name: 10Foundation8IndexSetV + Size: 8 + Alignment: 8 + ExtraInhabitants: 2147483647 + - Name: 10Foundation8IndexSetV0B0V + Size: 40 + Alignment: 8 + ExtraInhabitants: 0 + - Name: 10Foundation8IndexSetV9RangeViewV + Size: 24 + Alignment: 8 + ExtraInhabitants: 2147483647 + - Name: 10Foundation8TimeZoneV + Size: 9 + Alignment: 8 + ExtraInhabitants: 2147483647 + - Name: 10Foundation8URLErrorV + Size: 8 + Alignment: 8 + ExtraInhabitants: 2147483647 + - Name: 10Foundation8URLErrorV4CodeV + Size: 8 + Alignment: 8 + ExtraInhabitants: 0 + - Name: 10Foundation9IndexPathV + Size: 17 + Alignment: 8 + ExtraInhabitants: 252 + - Name: 10Foundation9MachErrorV + Size: 8 + Alignment: 8 + ExtraInhabitants: 2147483647 + - Name: 8Dispatch0A4DataV10FoundationE6RegionV + Size: 32 + Alignment: 8 + ExtraInhabitants: 2147483647 + - Name: SS10FoundationE8EncodingV + Size: 8 + Alignment: 8 + ExtraInhabitants: 0 +... +--- +Name: Intents +Decls: + - Name: 7Intents10INShortcutO + Size: 9 + Alignment: 8 + ExtraInhabitants: 254 +... +--- +Name: Network +Decls: + - Name: 7Network10NWEndpointO + Size: 89 + Alignment: 8 + ExtraInhabitants: 253 + - Name: 7Network10NWEndpointO4HostO + Size: 57 + Alignment: 8 + ExtraInhabitants: 253 + - Name: 7Network10NWEndpointO4PortV + Size: 2 + Alignment: 2 + ExtraInhabitants: 0 + - Name: 7Network10NWListenerC25ServiceRegistrationChangeO + Size: 90 + Alignment: 8 + ExtraInhabitants: 254 + - Name: 7Network10NWListenerC5StateO + Size: 5 + Alignment: 4 + ExtraInhabitants: 61 + - Name: 7Network10NWListenerC7ServiceV + Size: 64 + Alignment: 8 + ExtraInhabitants: 2147483647 + - Name: 7Network11IPv4AddressV + Size: 48 + Alignment: 8 + ExtraInhabitants: 2147483646 + - Name: 7Network11IPv6AddressV + Size: 56 + Alignment: 8 + ExtraInhabitants: 2147483646 + - Name: 7Network11IPv6AddressV5ScopeO + Size: 1 + Alignment: 1 + ExtraInhabitants: 251 + - Name: 7Network11NWInterfaceV + Size: 40 + Alignment: 8 + ExtraInhabitants: 2147483647 + - Name: 7Network11NWInterfaceV13InterfaceTypeO + Size: 1 + Alignment: 1 + ExtraInhabitants: 251 + - Name: 7Network12NWConnectionC14SendCompletionO + Size: 16 + Alignment: 8 + ExtraInhabitants: 2147483646 + - Name: 7Network12NWConnectionC5StateO + Size: 5 + Alignment: 4 + ExtraInhabitants: 61 + - Name: 7Network12NWParametersC12ServiceClassO + Size: 1 + Alignment: 1 + ExtraInhabitants: 250 + - Name: 7Network12NWParametersC18ExpiredDNSBehaviorO + Size: 1 + Alignment: 1 + ExtraInhabitants: 253 + - Name: 7Network12NWParametersC20MultipathServiceTypeO + Size: 1 + Alignment: 1 + ExtraInhabitants: 252 + - Name: 7Network12NWProtocolIPC3ECNO + Size: 1 + Alignment: 1 + ExtraInhabitants: 252 + - Name: 7Network12NWProtocolIPC7OptionsC7VersionO + Size: 1 + Alignment: 1 + ExtraInhabitants: 253 + - Name: 7Network6NWPathV + Size: 224 + Alignment: 8 + ExtraInhabitants: 2147483647 + - Name: 7Network6NWPathV6StatusO + Size: 1 + Alignment: 1 + ExtraInhabitants: 253 + - Name: 7Network7NWErrorO + Size: 5 + Alignment: 4 + ExtraInhabitants: 253 +... +--- +Name: os +Decls: + - Name: 2os12OSSignpostIDV + Size: 8 + Alignment: 8 + ExtraInhabitants: 0 + - Name: So9OS_os_logC0B0E8CategoryV + Size: 16 + Alignment: 8 + ExtraInhabitants: 2147483647 +... diff --git a/stdlib/tools/swift-reflection-test/swift-reflection-test.c b/stdlib/tools/swift-reflection-test/swift-reflection-test.c index d6a202b86e7ac..6b86f492ccdc3 100644 --- a/stdlib/tools/swift-reflection-test/swift-reflection-test.c +++ b/stdlib/tools/swift-reflection-test/swift-reflection-test.c @@ -38,6 +38,10 @@ #include #endif +#if __has_feature(ptrauth_calls) +#include +#endif + #if defined(__clang__) || defined(__GNUC__) #define NORETURN __attribute__((noreturn)) #elif defined(_MSC_VER) @@ -160,6 +164,15 @@ static int PipeMemoryReader_queryDataLayout(void *Context, *result = sizeof(size_t); return 1; } + case DLQ_GetPtrAuthMask: { + uintptr_t *result = (uintptr_t *)outBuffer; +#if __has_feature(ptrauth_calls) + *result = (uintptr_t)ptrauth_strip((void*)0x0007ffffffffffff, 0); +#else + *result = (uintptr_t)~0ull; +#endif + return 1; + } case DLQ_GetObjCReservedLowBits: { uint8_t *result = (uint8_t *)outBuffer; if (applePlatform && !iosDerivedPlatform && (sizeof(void *) == 8)) { diff --git a/test/IRGen/Inputs/ptrauth-foreign.h b/test/IRGen/Inputs/ptrauth-foreign.h new file mode 100644 index 0000000000000..0b51e8c31214b --- /dev/null +++ b/test/IRGen/Inputs/ptrauth-foreign.h @@ -0,0 +1,13 @@ +struct IntPair { + int x; + int y; +}; + +__attribute__((objc_root_class)) +@interface Root +@end + +@interface ObjCWidget : Root +@end + +typedef struct __attribute__((objc_bridge(ObjCWidget))) __widget *WidgetRef; \ No newline at end of file diff --git a/test/IRGen/abitypes.swift b/test/IRGen/abitypes.swift index be7ae04892a48..41487f1f31d4a 100644 --- a/test/IRGen/abitypes.swift +++ b/test/IRGen/abitypes.swift @@ -14,6 +14,7 @@ import Foundation // armv7s-ios: [[ARMV7S_MYRECT:%.*]] = type { float, float, float, float } // arm64-ios: [[ARM64_MYRECT:%.*]] = type { float, float, float, float } +// arm64e-ios: [[ARM64E_MYRECT:%.*]] = type { float, float, float, float } // arm64-tvos: [[ARM64_MYRECT:%.*]] = type { float, float, float, float } // armv7k-watchos: [[ARMV7K_MYRECT:%.*]] = type { float, float, float, float } @@ -275,6 +276,11 @@ class Foo { // arm64-ios-fixme: [[R2:%[0-9]+]] = call i1 @"$s8abitypes3FooC6negate{{[_0-9a-zA-Z]*}}F" // arm64-ios-fixme: ret i1 [[R2]] // + // arm64e-ios-fixme: define hidden i1 @"$s8abitypes3FooC6negate{{[_0-9a-zA-Z]*}}F"(i1, %T8abitypes3FooC*) {{.*}} { + // arm64e-ios-fixme: define internal zeroext i1 @"$s8abitypes3FooC6negate{{[_0-9a-zA-Z]*}}FTo" + // arm64e-ios-fixme: [[R2:%[0-9]+]] = call i1 @"$s8abitypes3FooC6negate{{[_0-9a-zA-Z]*}}F" + // arm64e-ios-fixme: ret i1 [[R2]] + // // i386-ios-fixme: define hidden i1 @"$s8abitypes3FooC6negate{{[_0-9a-zA-Z]*}}F"(i1, %T8abitypes3FooC*) {{.*}} { // i386-ios-fixme: define internal signext i8 @"$s8abitypes3FooC6negate{{[_0-9a-zA-Z]*}}FTo"(i8*, i8*, i8 signext) {{[#0-9]*}} { // i386-ios-fixme: [[R1:%[0-9]+]] = call i1 @"$s10ObjectiveC22_convertObjCBoolToBool{{[_0-9a-zA-Z]*}}F" @@ -364,6 +370,11 @@ class Foo { // arm64-ios: [[TOOBJCBOOL:%[0-9]+]] = call swiftcc i1 @"$s10ObjectiveC22_convertBoolToObjCBool{{[_0-9a-zA-Z]*}}F"(i1 [[NEG]]) // arm64-ios: ret i1 [[TOOBJCBOOL]] // + // arm64e-ios: define hidden zeroext i1 @"$s8abitypes3FooC7negate2{{[_0-9a-zA-Z]*}}FTo"(i8* %0, i8* %1, i1 zeroext %2) + // arm64e-ios: [[NEG:%[0-9]+]] = call swiftcc i1 @"$s8abitypes3FooC7negate2{{[_0-9a-zA-Z]*}}F"(i1 + // arm64e-ios: [[TOOBJCBOOL:%[0-9]+]] = call swiftcc i1 @"$s10ObjectiveC22_convertBoolToObjCBool{{[_0-9a-zA-Z]*}}F"(i1 [[NEG]]) + // arm64e-ios: ret i1 [[TOOBJCBOOL]] + // // i386-ios: define hidden swiftcc i1 @"$s8abitypes3FooC7negate2{{[_0-9a-zA-Z]*}}F"(i1 %0, %T8abitypes3FooC* swiftself %1) {{.*}} { // i386-ios: [[TOOBJCBOOL:%[0-9]+]] = call swiftcc i8 @"$s10ObjectiveC22_convertBoolToObjCBool{{[_0-9a-zA-Z]*}}F"(i1 %0) // i386-ios: [[SEL:%[0-9]+]] = load i8*, i8** @"\01L_selector(negate:)", align 4 @@ -516,6 +527,9 @@ class Foo { // arm64-ios: define hidden swiftcc { i64, i64, i64, i64 } @"$s8abitypes3FooC14callJustReturn{{[_0-9a-zA-Z]*}}F"(%TSo13StructReturnsC* %0, i64 %1, i64 %2, i64 %3, i64 %4, %T8abitypes3FooC* swiftself %5) {{.*}} { // arm64-ios: define hidden void @"$s8abitypes3FooC14callJustReturn{{[_0-9a-zA-Z]*}}FTo"(%TSo9BigStructV* noalias nocapture sret %0, i8* %1, i8* %2, [[OPAQUE:.*]]* %3, %TSo9BigStructV* %4) {{[#0-9]*}} { // + // arm64e-ios: define hidden swiftcc { i64, i64, i64, i64 } @"$s8abitypes3FooC14callJustReturn{{[_0-9a-zA-Z]*}}F"(%TSo13StructReturnsC* %0, i64 %1, i64 %2, i64 %3, i64 %4, %T8abitypes3FooC* swiftself %5) {{.*}} { + // arm64e-ios: define hidden void @"$s8abitypes3FooC14callJustReturn{{[_0-9a-zA-Z]*}}FTo"(%TSo9BigStructV* noalias nocapture sret %0, i8* %1, i8* %2, [[OPAQUE:.*]]* %3, %TSo9BigStructV* %4) {{.*}} { + // // arm64-tvos: define hidden swiftcc { i64, i64, i64, i64 } @"$s8abitypes3FooC14callJustReturn{{[_0-9a-zA-Z]*}}F"(%TSo13StructReturnsC* %0, i64 %1, i64 %2, i64 %3, i64 %4, %T8abitypes3FooC* swiftself %5) {{.*}} { // arm64-tvos: define hidden void @"$s8abitypes3FooC14callJustReturn{{[_0-9a-zA-Z]*}}FTo"(%TSo9BigStructV* noalias nocapture sret %0, i8* %1, i8* %2, [[OPAQUE:.*]]* %3, %TSo9BigStructV* %4) {{[#0-9]*}} { @objc dynamic func callJustReturn(_ r: StructReturns, with v: BigStruct) -> BigStruct { @@ -561,6 +575,16 @@ public func testInlineAgg(_ rect: MyRect) -> Float { // arm64-ios: store i1 false, i1* [[PTR2]], align 8 // arm64-ios: [[ARG:%.*]] = load i64, i64* [[COERCED]] // arm64-ios: call void bitcast (void ()* @objc_msgSend to void (i8*, i8*, i64)*)(i8* {{.*}}, i8* {{.*}}, i64 [[ARG]]) +// +// arm64e-ios: define swiftcc void @"$s8abitypes14testBOOLStructyyF"() +// arm64e-ios: [[COERCED:%.*]] = alloca i64 +// arm64e-ios: [[STRUCTPTR:%.*]] = bitcast i64* [[COERCED]] to %TSo14FiveByteStructV +// arm64e-ios: [[PTR0:%.*]] = getelementptr inbounds %TSo14FiveByteStructV, %TSo14FiveByteStructV* [[STRUCTPTR]], {{i.*}} 0, {{i.*}} 0 +// arm64e-ios: [[PTR1:%.*]] = getelementptr inbounds %T10ObjectiveC8ObjCBoolV, %T10ObjectiveC8ObjCBoolV* [[PTR0]], {{i.*}} 0, {{i.*}} 0 +// arm64e-ios: [[PTR2:%.*]] = getelementptr inbounds %TSb, %TSb* [[PTR1]], {{i.*}} 0, {{i.*}} 0 +// arm64e-ios: store i1 false, i1* [[PTR2]], align 8 +// arm64e-ios: [[ARG:%.*]] = load i64, i64* [[COERCED]] +// arm64e-ios: call void bitcast (void ()* @objc_msgSend to void (i8*, i8*, i64)*)(i8* {{.*}}, i8* {{.*}}, i64 [[ARG]]) public func testBOOLStruct() { let s = FiveByteStruct() MyClass.mymethod(s) diff --git a/test/IRGen/associated_type_witness.swift b/test/IRGen/associated_type_witness.swift index 298756bdb66db..0af07e62363b9 100644 --- a/test/IRGen/associated_type_witness.swift +++ b/test/IRGen/associated_type_witness.swift @@ -41,7 +41,7 @@ protocol HasThreeAssocTypes { // GLOBAL-SAME: @"$s23associated_type_witness13WithUniversalVAA8AssockedAAMc" // GLOBAL-SAME: @"associated conformance 23associated_type_witness13WithUniversalVAA8AssockedAA5AssocAaDP_AA1P", // GLOBAL-SAME: @"associated conformance 23associated_type_witness13WithUniversalVAA8AssockedAA5AssocAaDP_AA1Q" -// GLOBAL-SAME: i64 add (i64 ptrtoint (<{ {{.*}} }>* @"symbolic{{.*}}23associated_type_witness9UniversalV" to i64), i64 1) to i8*) +// GLOBAL-SAME: @"symbolic{{.*}}23associated_type_witness9UniversalV" // GLOBAL-SAME: ] struct WithUniversal : Assocked { typealias Assoc = Universal diff --git a/test/IRGen/autorelease.sil b/test/IRGen/autorelease.sil index 223cc89e49417..09fbf729c6477 100644 --- a/test/IRGen/autorelease.sil +++ b/test/IRGen/autorelease.sil @@ -46,6 +46,14 @@ bb0(%0 : @owned $C?): // arm64-NEXT: [[T3:%.*]] = ptrtoint i8* [[T2]] to i64 // arm64-NEXT: ret i64 [[T3]] +// arm64e: define{{( dllexport| protected)?}} swiftcc i64 @bar(i64 %0) +// arm64e: [[T0:%.*]] = call swiftcc i64 @foo(i64 %0) +// arm64e-NEXT: call void asm sideeffect "mov +// arm64e-NEXT: [[T1:%.*]] = inttoptr i64 [[T0]] to i8* +// arm64e-NEXT: [[T2:%.*]] = call i8* @llvm.objc.retainAutoreleasedReturnValue(i8* [[T1]]) +// arm64e-NEXT: [[T3:%.*]] = ptrtoint i8* [[T2]] to i64 +// arm64e-NEXT: ret i64 [[T3]] + // aarch64: define{{( dllexport| protected)?}} swiftcc i64 @bar(i64 %0) // aarch64: [[T0:%.*]] = call swiftcc i64 @foo(i64 %0) // aarch64-NEXT: call void asm sideeffect "mov diff --git a/test/IRGen/c_functions.swift b/test/IRGen/c_functions.swift index 5f87bd05f9643..3d42cfc1c3657 100644 --- a/test/IRGen/c_functions.swift +++ b/test/IRGen/c_functions.swift @@ -28,6 +28,7 @@ func test_indirect_by_val_alignment() { // aarch64: define hidden swiftcc void @"$s11c_functions30test_indirect_by_val_alignmentyyF"() // arm64: define hidden swiftcc void @"$s11c_functions30test_indirect_by_val_alignmentyyF"() +// arm64e: define hidden swiftcc void @"$s11c_functions30test_indirect_by_val_alignmentyyF"() // armv7k: define hidden swiftcc void @"$s11c_functions30test_indirect_by_val_alignmentyyF"() // armv7s: define hidden swiftcc void @"$s11c_functions30test_indirect_by_val_alignmentyyF"() // armv7: define hidden swiftcc void @"$s11c_functions30test_indirect_by_val_alignmentyyF"() diff --git a/test/IRGen/c_layout.sil b/test/IRGen/c_layout.sil index 9ada704fb897c..8cdbc74113441 100644 --- a/test/IRGen/c_layout.sil +++ b/test/IRGen/c_layout.sil @@ -249,6 +249,22 @@ bb0: // CHECK-arm64-LABEL: declare{{( dllimport)?}} i32 @ints(i32) // CHECK-arm64-LABEL: declare{{( dllimport)?}} i32 @unsigneds(i32) +// CHECK-arm64e-LABEL: define{{( dllexport)?}}{{( protected)?}} swiftcc void @testIntegerExtension +// CHECK-arm64e: call signext i8 @chareth(i8 signext +// CHECK-arm64e: call signext i8 @signedChareth(i8 signext +// CHECK-arm64e: call zeroext i8 @unsignedChareth(i8 zeroext +// CHECK-arm64e: call signext i16 @eatMyShorts(i16 signext +// CHECK-arm64e: call zeroext i16 @eatMyUnsignedShorts(i16 zeroext +// CHECK-arm64e: call i32 @ints(i32 %5) +// CHECK-arm64e: call i32 @unsigneds(i32 %6) +// CHECK-arm64e-LABEL: declare{{( dllimport)?}} signext i8 @chareth(i8 signext) +// CHECK-arm64e-LABEL: declare{{( dllimport)?}} signext i8 @signedChareth(i8 signext) +// CHECK-arm64e-LABEL: declare{{( dllimport)?}} zeroext i8 @unsignedChareth(i8 zeroext) +// CHECK-arm64e-LABEL: declare{{( dllimport)?}} signext i16 @eatMyShorts(i16 signext) +// CHECK-arm64e-LABEL: declare{{( dllimport)?}} zeroext i16 @eatMyUnsignedShorts(i16 zeroext) +// CHECK-arm64e-LABEL: declare{{( dllimport)?}} i32 @ints(i32) +// CHECK-arm64e-LABEL: declare{{( dllimport)?}} i32 @unsigneds(i32) + // CHECK-aarch64-LABEL: define{{( dllexport)?}}{{( protected)?}} swiftcc void @testIntegerExtension // CHECK-aarch64: call i8 @chareth(i8 %0) // CHECK-aarch64: call i8 @signedChareth(i8 %1) diff --git a/test/IRGen/class_metadata.swift b/test/IRGen/class_metadata.swift index e130c37d86921..ef631cc6a7897 100644 --- a/test/IRGen/class_metadata.swift +++ b/test/IRGen/class_metadata.swift @@ -1,6 +1,6 @@ // RUN: %empty-directory(%t) // RUN: %{python} %utils/chex.py < %s > %t/class_metadata.swift -// RUN: %target-swift-frontend -emit-ir %s | %FileCheck %t/class_metadata.swift -check-prefix=CHECK -check-prefix=CHECK-%target-ptrsize -check-prefix CHECK-%target-import-type +// RUN: %target-swift-frontend -emit-ir %s | %FileCheck %t/class_metadata.swift -check-prefix=CHECK -check-prefix=CHECK-%target-ptrsize -check-prefix CHECK-%target-import-type -check-prefix=CHECK-%target-cpu class A {} @@ -32,9 +32,13 @@ class A {} // CHECK-64-SAME: i32 10, // V-table length. // CHECK-SAME: i32 1, -// CHECK-SMAE: %swift.method_descriptor { +// CHECK-SAME: %swift.method_descriptor { // V-table entry #1: flags. -// CHECK-SAME: i32 1 +// CHECK-i386-SAME: i32 1, +// CHECK-x86_64-SAME: i32 1, +// CHECK-armv7k-SAME: i32 1, +// CHECK-arm64-SAME: i32 1, +// CHECK-arm64e-SAME: i32 1882783745 // V-table entry #1: invocation function. // CHECK-SAME: @"$s14class_metadata1ACACycfC" // CHECK-SAME: }>, section diff --git a/test/IRGen/class_resilience.swift b/test/IRGen/class_resilience.swift index 662a785409c84..cd33c5493db1d 100644 --- a/test/IRGen/class_resilience.swift +++ b/test/IRGen/class_resilience.swift @@ -3,7 +3,7 @@ // RUN: %target-swift-frontend -emit-module -enable-library-evolution -emit-module-path=%t/resilient_struct.swiftmodule -module-name=resilient_struct %S/../Inputs/resilient_struct.swift // RUN: %target-swift-frontend -emit-module -enable-library-evolution -emit-module-path=%t/resilient_enum.swiftmodule -module-name=resilient_enum -I %t %S/../Inputs/resilient_enum.swift // RUN: %target-swift-frontend -emit-module -enable-library-evolution -emit-module-path=%t/resilient_class.swiftmodule -module-name=resilient_class -I %t %S/../Inputs/resilient_class.swift -// RUN: %target-swift-frontend -I %t -emit-ir -enable-library-evolution %t/class_resilience.swift | %FileCheck %t/class_resilience.swift --check-prefix=CHECK --check-prefix=CHECK-%target-ptrsize --check-prefix=CHECK-%target-runtime -DINT=i%target-ptrsize +// RUN: %target-swift-frontend -I %t -emit-ir -enable-library-evolution %t/class_resilience.swift | %FileCheck %t/class_resilience.swift --check-prefix=CHECK --check-prefix=CHECK-%target-ptrsize --check-prefix=CHECK-%target-runtime -check-prefix=CHECK-%target-cpu --check-prefix=CHECK-DEP-TARGET-GTE-13_0-%target-mandates-deployment-target-gte-13.0 -DINT=i%target-ptrsize // RUN: %target-swift-frontend -I %t -emit-ir -enable-library-evolution -O %t/class_resilience.swift // CHECK: @"$s16class_resilience26ClassWithResilientPropertyC1s16resilient_struct4SizeVvpWvd" = hidden global [[INT]] 0 @@ -414,7 +414,8 @@ public class ClassWithResilientThenEmpty { // CHECK: dependency-satisfied: // -- ClassLayoutFlags = 0x100 (HasStaticVTable) -// CHECK: [[T0:%.*]] = call swiftcc %swift.metadata_response @swift_initClassMetadata2(%swift.type* %0, [[INT]] 256, [[INT]] 3, i8*** [[FIELDS_PTR]], [[INT]]* [[FIELDS_DEST]]) +// CHECK-DEP-TARGET-GTE-13_0-TRUE: [[T0:%.*]] = call swiftcc %swift.metadata_response @swift_updateClassMetadata2(%swift.type* %0, [[INT]] 256, [[INT]] 3, i8*** [[FIELDS_PTR]], [[INT]]* [[FIELDS_DEST]]) +// CHECK-DEP-TARGET-GTE-13_0-FALSE:[[T0:%.*]] = call swiftcc %swift.metadata_response @swift_initClassMetadata2(%swift.type* %0, [[INT]] 256, [[INT]] 3, i8*** [[FIELDS_PTR]], [[INT]]* [[FIELDS_DEST]]) // CHECK-NEXT: [[INITDEP_METADATA:%.*]] = extractvalue %swift.metadata_response [[T0]], 0 // CHECK-NEXT: [[INITDEP_STATUS:%.*]] = extractvalue %swift.metadata_response [[T0]], 1 // CHECK-NEXT: [[INITDEP_PRESENT:%.*]] = icmp eq %swift.type* [[INITDEP_METADATA]], null @@ -490,7 +491,8 @@ public class ClassWithResilientThenEmpty { // CHECK: dependency-satisfied: // -- ClassLayoutFlags = 0x100 (HasStaticVTable) -// CHECK: [[T0:%.*]] = call swiftcc %swift.metadata_response @swift_initClassMetadata2(%swift.type* %0, [[INT]] 256, [[INT]] 2, i8*** [[FIELDS_PTR]], [[INT]]* [[FIELDS_DEST]]) +// CHECK-DEP-TARGET-GTE-13_0-TRUE: [[T0:%.*]] = call swiftcc %swift.metadata_response @swift_updateClassMetadata2(%swift.type* %0, [[INT]] 256, [[INT]] 2, i8*** [[FIELDS_PTR]], [[INT]]* [[FIELDS_DEST]]) +// CHECK-DEP-TARGET-GTE-13_0-FALSE: [[T0:%.*]] = call swiftcc %swift.metadata_response @swift_initClassMetadata2(%swift.type* %0, [[INT]] 256, [[INT]] 2, i8*** [[FIELDS_PTR]], [[INT]]* [[FIELDS_DEST]]) // CHECK-NEXT: [[INITDEP_METADATA:%.*]] = extractvalue %swift.metadata_response [[T0]], 0 // CHECK-NEXT: [[INITDEP_STATUS:%.*]] = extractvalue %swift.metadata_response [[T0]], 1 // CHECK-NEXT: [[INITDEP_PRESENT:%.*]] = icmp eq %swift.type* [[INITDEP_METADATA]], null @@ -542,6 +544,21 @@ public class ClassWithResilientThenEmpty { // CHECK-NEXT: ret i8* [[RESULT]] // CHECK-NEXT: } +// ResilientChild.field getter dispatch thunk + +// CHECK-LABEL: define{{( dllexport)?}}{{( protected)?}} swiftcc i32 @"$s16class_resilience14ResilientChildC5fields5Int32VvgTj"(%T16class_resilience14ResilientChildC* swiftself %0) +// CHECK: [[ISA_ADDR:%.*]] = getelementptr inbounds %T16class_resilience14ResilientChildC, %T16class_resilience14ResilientChildC* %0, i32 0, i32 0, i32 0 +// CHECK-NEXT: [[ISA:%.*]] = load %swift.type*, %swift.type** [[ISA_ADDR]] +// CHECK-NEXT: [[BASE_ADDR:%.*]] = load [[INT]], [[INT]]* getelementptr inbounds ([[BOUNDS]], [[BOUNDS]]* @"$s16class_resilience14ResilientChildCMo", i32 0, i32 0) +// CHECK-NEXT: [[BASE:%.*]] = add [[INT]] [[BASE_ADDR]], {{4|8}} +// CHECK-NEXT: [[METADATA_BYTES:%.*]] = bitcast %swift.type* [[ISA]] to i8* +// CHECK-NEXT: [[VTABLE_OFFSET_TMP:%.*]] = getelementptr inbounds i8, i8* [[METADATA_BYTES]], [[INT]] [[BASE]] +// CHECK-NEXT: [[VTABLE_OFFSET_ADDR:%.*]] = bitcast i8* [[VTABLE_OFFSET_TMP]] to i32 (%T16class_resilience14ResilientChildC*)** +// CHECK-NEXT: [[METHOD:%.*]] = load i32 (%T16class_resilience14ResilientChildC*)*, i32 (%T16class_resilience14ResilientChildC*)** [[VTABLE_OFFSET_ADDR]] +// CHECK-arm64e-NEXT: ptrtoint i32 (%T16class_resilience14ResilientChildC*)** [[VTABLE_OFFSET_ADDR]] to i64 +// CHECK-arm64e-NEXT: call i64 @llvm.ptrauth.blend.i64 +// CHECK-NEXT: [[RESULT:%.*]] = call swiftcc i32 [[METHOD]](%T16class_resilience14ResilientChildC* swiftself %0) +// CHECK-NEXT: ret i32 [[RESULT]] // ResilientChild.field setter dispatch thunk @@ -554,6 +571,8 @@ public class ClassWithResilientThenEmpty { // CHECK-NEXT: [[VTABLE_OFFSET_TMP:%.*]] = getelementptr inbounds i8, i8* [[METADATA_BYTES]], [[INT]] [[METADATA_OFFSET]] // CHECK-NEXT: [[VTABLE_OFFSET_ADDR:%.*]] = bitcast i8* [[VTABLE_OFFSET_TMP]] to void (i32, %T16class_resilience14ResilientChildC*)** // CHECK-NEXT: [[METHOD:%.*]] = load void (i32, %T16class_resilience14ResilientChildC*)*, void (i32, %T16class_resilience14ResilientChildC*)** [[VTABLE_OFFSET_ADDR]] +// CHECK-arm64e-NEXT: ptrtoint void (i32, %T16class_resilience14ResilientChildC*)** [[VTABLE_OFFSET_ADDR]] to i64 +// CHECK-arm64e-NEXT: call i64 @llvm.ptrauth.blend.i64 // CHECK-NEXT: call swiftcc void [[METHOD]](i32 %0, %T16class_resilience14ResilientChildC* swiftself %1) // CHECK-NEXT: ret void @@ -561,7 +580,7 @@ public class ClassWithResilientThenEmpty { // ResilientGenericChild metadata initialization function // CHECK-LABEL: define internal %swift.type* @"$s16class_resilience21ResilientGenericChildCMi"(%swift.type_descriptor* %0, i8** %1, i8* %2) -// CHECK: [[METADATA:%.*]] = call %swift.type* @swift_allocateGenericClassMetadata(%swift.type_descriptor* %0, i8** %1, i8* %2) +// CHECK: [[METADATA:%.*]] = call %swift.type* @swift_allocateGenericClassMetadata(%swift.type_descriptor* {{.*}}, i8** %1, i8* %2) // CHECK: ret %swift.type* [[METADATA]] // CHECK-LABEL: define internal swiftcc %swift.metadata_response @"$s16class_resilience21ResilientGenericChildCMr" diff --git a/test/IRGen/class_update_callback_without_fixed_layout.sil b/test/IRGen/class_update_callback_without_fixed_layout.sil index e6e8e71a45243..a905c46986b8b 100644 --- a/test/IRGen/class_update_callback_without_fixed_layout.sil +++ b/test/IRGen/class_update_callback_without_fixed_layout.sil @@ -5,6 +5,7 @@ // RUN: %target-swift-frontend -I %t -emit-ir -enable-library-evolution -O %s -target %target-pre-stable-abi-triple // REQUIRES: objc_interop +// UNSUPPORTED: CPU=arm64e // With the old deployment target, these classes use the 'singleton' metadata // initialization pattern. The class is not statically visible to Objective-C, @@ -59,7 +60,7 @@ sil_vtable SubclassOfClassWithResilientField {} // CHECK-NEW-SAME: i32 192, // -- the update callback -// CHECK-NEW-SAME: @"$s42class_update_callback_without_fixed_layout23ClassWithResilientFieldCMU" +// CHECK-NEW-SAME: @"$s42class_update_callback_without_fixed_layout23ClassWithResilientFieldCMU{{(\.ptrauth)?}}" // CHECK-SAME: }, section "__DATA, __objc_const" diff --git a/test/IRGen/dead_method.swift b/test/IRGen/dead_method.swift index fd52c73d85240..1c31093657717 100644 --- a/test/IRGen/dead_method.swift +++ b/test/IRGen/dead_method.swift @@ -19,35 +19,35 @@ public class Class { // -- vtable // CHECK-SAME: %swift.method_descriptor { -// CHECK-SAME: i32 1, +// CHECK-SAME: i32 {{(1|-835911679)}}, // CHECK-SAME: @"$s11dead_method5ClassCACycfC" // CHECK-SAME: } // CHECK-SAME: %swift.method_descriptor { -// CHECK-SAME: i32 16, +// CHECK-SAME: i32 {{(16|-1609105392)}}, // CHECK-SAME: @"$s11dead_method5ClassC4liveyyF" // CHECK-SAME: } -// CHECK-SAME: %swift.method_descriptor { i32 16, i32 0 } +// CHECK-SAME: %swift.method_descriptor { i32 {{(16|-1887436784)}}, i32 0 } // CHECK-SAME: }> // CHECK-LABEL: @"$s11dead_method5ClassCMf" = internal global <{{.*}}> <{ // -- destructor -// CHECK-SAME: void (%T11dead_method5ClassC*)* @"$s11dead_method5ClassCfD", +// CHECK-SAME: void (%T11dead_method5ClassC*)* {{.*}}@"$s11dead_method5ClassCfD{{(.ptrauth)?}}" // -- value witness table // CHECK-SAME: i8** {{@"\$sBoWV"|null}}, // -- nominal type descriptor -// CHECK-SAME: @"$s11dead_method5ClassCMn", +// CHECK-SAME: @"$s11dead_method5ClassCMn{{(.ptrauth)?}}" // -- ivar destroyer // CHECK-SAME: i8* null, // -- vtable -// CHECK-SAME: %T11dead_method5ClassC* (%swift.type*)* @"$s11dead_method5ClassCACycfC", -// CHECK-SAME: void (%T11dead_method5ClassC*)* @"$s11dead_method5ClassC4liveyyF", -// CHECK-SAME: i8* bitcast (void ()* @swift_deletedMethodError to i8*) +// CHECK-SAME: %T11dead_method5ClassC* (%swift.type*)* {{.*}}@"$s11dead_method5ClassCACycfC{{(.ptrauth)?}}" +// CHECK-SAME: void (%T11dead_method5ClassC*)* {{.*}}@"$s11dead_method5ClassC4liveyyF{{(.ptrauth)?}}" +// CHECK-SAME: i8* bitcast {{.*}}@swift_deletedMethodError{{(.ptrauth)?}} to i8*) // CHECK-SAME: }> diff --git a/test/IRGen/dynamic_replaceable.sil b/test/IRGen/dynamic_replaceable.sil index 3f4cbe8fe45c2..15cb46788d38f 100644 --- a/test/IRGen/dynamic_replaceable.sil +++ b/test/IRGen/dynamic_replaceable.sil @@ -3,6 +3,9 @@ // REQUIRES: objc_interop +// The arm64e test is in ptrauth-dynamic_replaceable.sil. +// UNSUPPORTED: CPU=arm64e + // CHECK: @test_dynamically_replaceableTX = global %swift.dyn_repl_link_entry { i8* bitcast (void ()* @test_dynamically_replaceable to i8*), %swift.dyn_repl_link_entry* null } // CHECK: @test_dynamically_replaceableTx = constant %swift.dyn_repl_key { i32{{.*}}%swift.dyn_repl_link_entry* @test_dynamically_replaceableTX{{.*}}, i32 0 }, section "__TEXT,__const" // CHECK: @test_replacementTX = global %swift.dyn_repl_link_entry zeroinitializer @@ -24,7 +27,7 @@ // CHECK-LABEL: define swiftcc void @test_dynamically_replaceable() // CHECK-NEXT: entry: -// COMPAT-NEXT: [[FUN_PTR:%.*]] = call i8* @swift_getFunctionReplacement50(i8** getelementptr inbounds (%swift.dyn_repl_link_entry, %swift.dyn_repl_link_entry* @test_dynamically_replaceableTX, i32 0, i32 0), i8* bitcast (void ()* @test_dynamically_replaceable to i8*)) +// COMPAT-NEXT: [[FUN_PTR:%.*]] = call i8* @swift_getFunctionReplacement{{.*}}(i8** getelementptr inbounds (%swift.dyn_repl_link_entry, %swift.dyn_repl_link_entry* @test_dynamically_replaceableTX, i32 0, i32 0), i8* bitcast (void ()* @test_dynamically_replaceable to i8*)) // NONCOMPAT-NEXT: [[FUN_PTR:%.*]] = call i8* @swift_getFunctionReplacement(i8** getelementptr inbounds (%swift.dyn_repl_link_entry, %swift.dyn_repl_link_entry* @test_dynamically_replaceableTX, i32 0, i32 0), i8* bitcast (void ()* @test_dynamically_replaceable to i8*)) // CHECK-NEXT: [[CMP:%.*]] = icmp eq i8* [[FUN_PTR]], null // CHECK-NEXT: br i1 [[CMP]], label %[[ORIGBB:[a-z_]*]], label %[[FWBB:[a-z_]*]] @@ -51,7 +54,7 @@ bb0: // The thunk that implement the prev_dynamic_function_ref lookup. // CHECK-LABEL: define swiftcc void @test_replacementTI() // CHECK: entry: -// COMPAT: [[FUN_PTR:%.*]] = call i8* @swift_getOrigOfReplaceable50(i8** getelementptr inbounds (%swift.dyn_repl_link_entry, %swift.dyn_repl_link_entry* @test_replacementTX, i32 0, i32 0)) +// COMPAT: [[FUN_PTR:%.*]] = call i8* @swift_getOrigOfReplaceable{{.*}}(i8** getelementptr inbounds (%swift.dyn_repl_link_entry, %swift.dyn_repl_link_entry* @test_replacementTX, i32 0, i32 0)) // NONCOMPAT: [[FUN_PTR:%.*]] = call i8* @swift_getOrigOfReplaceable(i8** getelementptr inbounds (%swift.dyn_repl_link_entry, %swift.dyn_repl_link_entry* @test_replacementTX, i32 0, i32 0)) // CHECK: [[TYPED_PTR:%.*]] = bitcast i8* [[FUN_PTR]] to void ()* // CHECK: call swiftcc void [[TYPED_PTR]]() diff --git a/test/IRGen/dynamic_replaceable_opaque_return.swift b/test/IRGen/dynamic_replaceable_opaque_return.swift index f4b9dec457e61..5c1c74ffc5e58 100644 --- a/test/IRGen/dynamic_replaceable_opaque_return.swift +++ b/test/IRGen/dynamic_replaceable_opaque_return.swift @@ -1,5 +1,7 @@ // RUN: %target-swift-frontend -disable-availability-checking -module-name A -swift-version 5 -primary-file %s -emit-ir | %FileCheck %s +// The arm64e test is in ptrauth-dynamic_replaceable.sil. +// UNSUPPORTED: CPU=arm64e // REQUIRES: objc_interop // No 32bit for now. diff --git a/test/IRGen/eager-class-initialization.swift b/test/IRGen/eager-class-initialization.swift index 40a3cf18692aa..c3d0bf4bc705d 100644 --- a/test/IRGen/eager-class-initialization.swift +++ b/test/IRGen/eager-class-initialization.swift @@ -3,6 +3,7 @@ // RUN: %target-swift-frontend(mock-sdk: %clang-importer-sdk) %s -emit-ir -target %target-pre-stable-abi-triple | %FileCheck %s -DINT=i%target-ptrsize --check-prefix=CHECK --check-prefix=CHECK-OLD // REQUIRES: objc_interop +// UNSUPPORTED: CPU=arm64e // See also eager-class-initialization-stable-abi.swift, for the stable ABI // deployment target test. diff --git a/test/IRGen/enum_resilience.swift b/test/IRGen/enum_resilience.swift index 8edbc36b20a14..c8484b2582cad 100644 --- a/test/IRGen/enum_resilience.swift +++ b/test/IRGen/enum_resilience.swift @@ -6,7 +6,7 @@ // RUN: %target-swift-frontend -disable-type-layout -emit-ir -enable-library-evolution -module-name=resilient_enum -I %t %S/../Inputs/resilient_enum.swift | %FileCheck %t/enum_resilience.swift --check-prefix=ENUM_RES // RUN: %target-swift-frontend -disable-type-layout -emit-ir -module-name=resilient_enum -I %t %S/../Inputs/resilient_enum.swift | %FileCheck %t/enum_resilience.swift --check-prefix=ENUM_NOT_RES // RUN: %target-swift-frontend -emit-module -enable-library-evolution -emit-module-path=%t/resilient_enum.swiftmodule -module-name=resilient_enum -I %t %S/../Inputs/resilient_enum.swift -// RUN: %target-swift-frontend -disable-type-layout -module-name enum_resilience -I %t -emit-ir -enable-library-evolution %s | %FileCheck %t/enum_resilience.swift --check-prefix=CHECK --check-prefix=CHECK-%target-ptrsize -DINT=i%target-ptrsize +// RUN: %target-swift-frontend -disable-type-layout -module-name enum_resilience -I %t -emit-ir -enable-library-evolution %s | %FileCheck %t/enum_resilience.swift -DINT=i%target-ptrsize --check-prefix=CHECK --check-prefix=CHECK-%target-ptrsize --check-prefix=CHECK-%target-cpu // RUN: %target-swift-frontend -module-name enum_resilience -I %t -emit-ir -enable-library-evolution -O %s import resilient_enum @@ -100,6 +100,8 @@ public func functionWithResilientEnum(_ m: Medium) -> Medium { // CHECK-NEXT: [[WITNESS_ADDR:%.*]] = getelementptr inbounds i8*, i8** [[VWT]], i32 2 // CHECK-NEXT: [[WITNESS:%.*]] = load i8*, i8** [[WITNESS_ADDR]] // CHECK-NEXT: [[WITNESS_FN:%initializeWithCopy]] = bitcast i8* [[WITNESS]] +// CHECK-arm64e-NEXT: ptrtoint i8** [[WITNESS_ADDR]] to i64 +// CHECK-arm64e-NEXT: call i64 @llvm.ptrauth.blend.i64 // CHECK-NEXT: call %swift.opaque* [[WITNESS_FN]](%swift.opaque* noalias %0, %swift.opaque* noalias %1, %swift.type* [[METADATA]]) // CHECK-NEXT: ret void @@ -118,6 +120,8 @@ public func functionWithIndirectResilientEnum(_ ia: IndirectApproach) -> Indirec // CHECK-NEXT: [[WITNESS_ADDR:%.*]] = getelementptr inbounds i8*, i8** [[VWT]], i32 2 // CHECK-NEXT: [[WITNESS:%.*]] = load i8*, i8** [[WITNESS_ADDR]] // CHECK-NEXT: [[WITNESS_FN:%initializeWithCopy]] = bitcast i8* [[WITNESS]] +// CHECK-arm64e-NEXT: ptrtoint i8** [[WITNESS_ADDR]] to i64 +// CHECK-arm64e-NEXT: call i64 @llvm.ptrauth.blend.i64 // CHECK-NEXT: call %swift.opaque* [[WITNESS_FN]](%swift.opaque* noalias %0, %swift.opaque* noalias %1, %swift.type* [[METADATA]]) // CHECK-NEXT: ret void @@ -138,6 +142,8 @@ public func constructResilientEnumNoPayload() -> Medium { // CHECK-64-NEXT: [[WITNESS_ADDR:%.*]] = getelementptr inbounds i8*, i8** [[VWT]], i32 13 // CHECK-NEXT: [[WITNESS:%.*]] = load i8*, i8** [[WITNESS_ADDR]] // CHECK-NEXT: [[WITNESS_FN:%.*]] = bitcast i8* [[WITNESS]] +// CHECK-arm64e-NEXT: ptrtoint i8** [[WITNESS_ADDR]] to i64 +// CHECK-arm64e-NEXT: call i64 @llvm.ptrauth.blend.i64 // CHECK-NEXT: call void [[WITNESS_FN]](%swift.opaque* noalias %0, i32 [[TAG]], %swift.type* [[METADATA]]) // CHECK-NEXT: ret void @@ -162,11 +168,15 @@ public func constructResilientEnumPayload(_ s: Size) -> Medium { // CHECK-NEXT: [[WITNESS_ADDR:%.*]] = getelementptr inbounds i8*, i8** [[VWT]], i32 2 // CHECK-NEXT: [[WITNESS:%.*]] = load i8*, i8** [[WITNESS_ADDR]] // CHECK-NEXT: [[WITNESS_FN:%initializeWithCopy]] = bitcast i8* [[WITNESS]] to %swift.opaque* (%swift.opaque*, %swift.opaque*, %swift.type*)* +// CHECK-arm64e-NEXT: ptrtoint i8** [[WITNESS_ADDR]] to i64 +// CHECK-arm64e-NEXT: call i64 @llvm.ptrauth.blend.i64 // CHECK-NEXT: call %swift.opaque* [[WITNESS_FN]](%swift.opaque* noalias [[ENUM_STORAGE]], %swift.opaque* noalias %1, %swift.type* [[METADATA]]) // CHECK-NEXT: [[WITNESS_ADDR:%.*]] = getelementptr inbounds i8*, i8** [[VWT]], i32 4 // CHECK-NEXT: [[WITNESS:%.*]] = load i8*, i8** [[WITNESS_ADDR]] // CHECK-NEXT: [[WITNESS_FN:%initializeWithTake]] = bitcast i8* [[WITNESS]] to %swift.opaque* (%swift.opaque*, %swift.opaque*, %swift.type*)* +// CHECK-arm64e-NEXT: ptrtoint i8** [[WITNESS_ADDR]] to i64 +// CHECK-arm64e-NEXT: call i64 @llvm.ptrauth.blend.i64 // CHECK-NEXT: call %swift.opaque* [[WITNESS_FN]](%swift.opaque* noalias %0, %swift.opaque* noalias [[ENUM_STORAGE]], %swift.type* [[METADATA]]) // CHECK-NEXT: [[TAG:%.*]] = load i32, i32* @"$s14resilient_enum6MediumO8PostcardyAC0A7_struct4SizeVcACmFWC" @@ -181,6 +191,8 @@ public func constructResilientEnumPayload(_ s: Size) -> Medium { // CHECK-64-NEXT: [[WITNESS_ADDR:%.*]] = getelementptr inbounds i8*, i8** [[VWT2]], i32 13 // CHECK-NEXT: [[WITNESS:%.*]] = load i8*, i8** [[WITNESS_ADDR]] // CHECK-NEXT: [[WITNESS_FN:%destructiveInjectEnumTag]] = bitcast i8* [[WITNESS]] +// CHECK-arm64e-NEXT: ptrtoint i8** [[WITNESS_ADDR]] to i64 +// CHECK-arm64e-NEXT: call i64 @llvm.ptrauth.blend.i64 // CHECK-NEXT: call void [[WITNESS_FN]](%swift.opaque* noalias %0, i32 [[TAG]], %swift.type* [[METADATA2]]) // CHECK-NEXT: [[STORAGE_ALLOCA:%.*]] = bitcast %swift.opaque* [[ENUM_STORAGE]] to i8* // CHECK-NEXT: call void @llvm.lifetime.end.p0i8({{(i32|i64)}} -1, i8* [[STORAGE_ALLOCA]]) diff --git a/test/IRGen/errors.sil b/test/IRGen/errors.sil index 05c64e2d8e5fd..f8fba2b88c3a5 100644 --- a/test/IRGen/errors.sil +++ b/test/IRGen/errors.sil @@ -21,6 +21,7 @@ entry: // CHECK-LABEL-armv7s: define{{( dllexport)?}}{{( protected)?}} swiftcc void @does_throw(%swift.refcounted* swiftself %0, %swift.error** swifterror %1) {{.*}} { // CHECK-LABEL-armv7k: define{{( dllexport)?}}{{( protected)?}} swiftcc void @does_throw(%swift.refcounted* swiftself %0, %swift.error** swifterror %1) {{.*}} { // CHECK-LABEL-arm64: define{{( dllexport)?}}{{( protected)?}} swiftcc void @does_throw(%swift.refcounted* swiftself %0, %swift.error** swifterror %1) {{.*}} { +// CHECK-LABEL-arm64e: define{{( dllexport)?}}{{( protected)?}} swiftcc void @does_throw(%swift.refcounted* swiftself %0, %swift.error** swifterror %1) {{.*}} { // CHECK-LABEL-aarch64: define{{( dllexport)?}}{{( protected)?}} swiftcc void @does_throw(%swift.refcounted* swiftself %0, %swift.error** swifterror %1) {{.*}} { sil @does_throw : $@convention(thin) () -> @error Error { // CHECK: [[T0:%.*]] = call swiftcc %swift.error* @create_error() @@ -42,6 +43,7 @@ sil @does_throw : $@convention(thin) () -> @error Error { // CHECK-LABEL-armv7s: define{{( dllexport)?}}{{( protected)?}} swiftcc void @doesnt_throw(%swift.refcounted* swiftself %0, %swift.error** swifterror %1) {{.*}} { // CHECK-LABEL-armv7k: define{{( dllexport)?}}{{( protected)?}} swiftcc void @doesnt_throw(%swift.refcounted* swiftself %0, %swift.error** swifterror %1) {{.*}} { // CHECK-LABEL-arm64: define{{( dllexport)?}}{{( protected)?}} swiftcc void @doesnt_throw(%swift.refcounted* swiftself %0, %swift.error** swifterror %1) {{.*}} { +// CHECK-LABEL-arm64e: define{{( dllexport)?}}{{( protected)?}} swiftcc void @doesnt_throw(%swift.refcounted* swiftself %0, %swift.error** swifterror %1) {{.*}} { // CHECK-LABEL-aarch64: define{{( dllexport)?}}{{( protected)?}} swiftcc void @doesnt_throw(%swift.refcounted* swiftself %0, %swift.error** swifterror %1) {{.*}} { sil @doesnt_throw : $@convention(thin) () -> @error Error { // We don't have to do anything here because the caller always @@ -64,6 +66,7 @@ entry(%0 : $AnyObject): // CHECK-armv7s: [[ERRORSLOT:%.*]] = alloca [[SWIFTERROR:.*]] %swift.error*, align // CHECK-armv7k: [[ERRORSLOT:%.*]] = alloca [[SWIFTERROR:.*]] %swift.error*, align // CHECK-arm64: [[ERRORSLOT:%.*]] = alloca [[SWIFTERROR:.*]] %swift.error*, align + // CHECK-arm64e: [[ERRORSLOT:%.*]] = alloca [[SWIFTERROR:.*]] %swift.error*, align // CHECK-aarch64: [[ERRORSLOT:%.*]] = alloca [[SWIFTERROR:.*]] %swift.error*, align // CHECK-powerpc64le: [[ERRORSLOT:%.*]] = alloca [[SWIFTERROR:.*]] %swift.error*, align // CHECK-NEXT: store %swift.error* null, %swift.error** [[ERRORSLOT]], align @@ -116,7 +119,8 @@ bb0(%0 : $Error): // rdar://21084084 - Partial application of throwing functions. // CHECK-LABEL: define{{( dllexport)?}}{{( protected)?}} swiftcc { i8*, %swift.refcounted* } @partial_apply_single(%T6errors1AC* %0) -// CHECK: insertvalue { i8*, %swift.refcounted* } { i8* bitcast (void (%swift.refcounted*, %swift.error**)* @"$s27partial_apply_single_helperTA" to i8*), %swift.refcounted* undef }, +// CHECK: insertvalue { i8*, %swift.refcounted* } { i8* bitcast ({{.*}}* @"$s27partial_apply_single_helperTA{{(\.ptrauth)?}}" to i8*), %swift.refcounted* undef }, + // CHECK: define internal swiftcc void @"$s27partial_apply_single_helperTA"(%swift.refcounted* swiftself %0, %swift.error** noalias nocapture{{( )?}}[[SWIFTERROR]]{{( )?}}dereferenceable({{.}}) %1) // CHECK: [[T0:%.*]] = bitcast %swift.refcounted* {{%.*}} to %T6errors1AC* // CHECK-NEXT: tail call swiftcc void @partial_apply_single_helper(%T6errors1AC* [[T0]], %swift.refcounted* swiftself undef, %swift.error** noalias nocapture{{( )?}}[[SWIFTERROR]]{{( )?}}dereferenceable({{.}}){{( )?}}{{%.*}}) diff --git a/test/IRGen/foreign_types.sil b/test/IRGen/foreign_types.sil index be1380db1c630..921f28825d597 100644 --- a/test/IRGen/foreign_types.sil +++ b/test/IRGen/foreign_types.sil @@ -18,7 +18,7 @@ import c_layout // CHECK-LABEL: @"$sSo14HasNestedUnionV18__Unnamed_struct_sVMf" = linkonce_odr hidden constant // CHECK-SAME: @"$sSo14HasNestedUnionV18__Unnamed_struct_sVWV" // CHECK-SAME: [[INT]] 512, -// CHECK-SAME: @"$sSo14HasNestedUnionV18__Unnamed_struct_sVMn" +// CHECK-SAME: @"$sSo14HasNestedUnionV18__Unnamed_struct_sVMn{{(\.ptrauth)?}}" // CHECK-SAME: i32 0, // CHECK-SAME: i32 4 } diff --git a/test/IRGen/foreign_types_future.sil b/test/IRGen/foreign_types_future.sil index 8e8e8c3a59671..d66891e01fde0 100644 --- a/test/IRGen/foreign_types_future.sil +++ b/test/IRGen/foreign_types_future.sil @@ -23,7 +23,7 @@ import c_layout // CHECK-LABEL: @"$sSo14HasNestedUnionV18__Unnamed_struct_sVMf" = linkonce_odr hidden constant // CHECK-SAME: @"$sSo14HasNestedUnionV18__Unnamed_struct_sVWV" // CHECK-SAME: [[INT]] 512, -// CHECK-SAME: @"$sSo14HasNestedUnionV18__Unnamed_struct_sVMn" +// CHECK-SAME: @"$sSo14HasNestedUnionV18__Unnamed_struct_sVMn // CHECK-SAME: i32 0, // CHECK-SAME: i32 4, // CHECK-SAME: i64 0 } diff --git a/test/IRGen/generic_vtable.swift b/test/IRGen/generic_vtable.swift index 96ed3dcd70698..1aaba1131ea8d 100644 --- a/test/IRGen/generic_vtable.swift +++ b/test/IRGen/generic_vtable.swift @@ -40,15 +40,15 @@ public class Concrete : Derived { // CHECK-LABEL: @"$s14generic_vtable4BaseCMf" = internal global // -- destructor -// CHECK-SAME: void (%T14generic_vtable4BaseC*)* @"$s14generic_vtable4BaseCfD" +// CHECK-SAME: @"$s14generic_vtable4BaseCfD{{(.ptrauth)?}}" // -- value witness table // CHECK-SAME: i8** {{@"\$sBoWV"|null}} // -- vtable entry for 'm1()' -// CHECK-SAME: void (%T14generic_vtable4BaseC*)* @"$s14generic_vtable4BaseC2m1yyF" +// CHECK-SAME: void (%T14generic_vtable4BaseC*)* {{@"\$s14generic_vtable4BaseC2m1yyF"|.* @"\$s14generic_vtable4BaseC2m1yyF.ptrauth"}} // -- vtable entry for 'm2()' -// CHECK-SAME: void (%T14generic_vtable4BaseC*)* @"$s14generic_vtable4BaseC2m2yyF" +// CHECK-SAME: void (%T14generic_vtable4BaseC*)* {{@"\$s14generic_vtable4BaseC2m2yyF"|.* @"\$s14generic_vtable4BaseC2m2yyF.ptrauth"}} // -- vtable entry for 'init()' -// CHECK-SAME: %T14generic_vtable4BaseC* (%swift.type*)* @"$s14generic_vtable4BaseCACycfC" +// CHECK-SAME: %T14generic_vtable4BaseC* (%swift.type*)* {{@"\$s14generic_vtable4BaseCACycfC"|.* @"\$s14generic_vtable4BaseCACycfC.ptrauth"}} // -- // CHECK-SAME: , align @@ -119,21 +119,21 @@ public class Concrete : Derived { // CHECK-LABEL: @"$s14generic_vtable8ConcreteCMf" = internal global <{{.*}}> <{ // -- destructor -// CHECK-SAME: void (%T14generic_vtable8ConcreteC*)* @"$s14generic_vtable8ConcreteCfD", +// CHECK-SAME: @"$s14generic_vtable8ConcreteCfD{{(.ptrauth)?}}" // -- value witness table is filled in at runtime // CHECK-SAME: i8** null, // -- nominal type descriptor -// CHECK-SAME: @"$s14generic_vtable8ConcreteCMn", +// CHECK-SAME: @"$s14generic_vtable8ConcreteCMn{{(.ptrauth)?}}" // -- vtable entry for 'm1()' -// CHECK-SAME: void (%T14generic_vtable4BaseC*)* @"$s14generic_vtable4BaseC2m1yyF" +// CHECK-SAME: void (%T14generic_vtable4BaseC*)* {{@"\$s14generic_vtable4BaseC2m1yyF"|.* @"\$s14generic_vtable4BaseC2m1yyF.ptrauth.1"}} // -- vtable entry for 'm2()' -// CHECK-SAME: void (%T14generic_vtable7DerivedC*)* @"$s14generic_vtable7DerivedC2m2yyF" +// CHECK-SAME: void (%T14generic_vtable7DerivedC*)* {{@"\$s14generic_vtable7DerivedC2m2yyF"|.* @"\$s14generic_vtable7DerivedC2m2yyF.ptrauth"}} // -- vtable entry for 'init()' -// CHECK-SAME: %T14generic_vtable8ConcreteC* (%swift.type*)* @"$s14generic_vtable8ConcreteCACycfC" +// CHECK-SAME: %T14generic_vtable8ConcreteC* (%swift.type*)* {{@"\$s14generic_vtable8ConcreteCACycfC"|.* @"\$s14generic_vtable8ConcreteCACycfC.ptrauth"}} // -- vtable entry for 'm3()' -// CHECK-SAME: void (%T14generic_vtable8ConcreteC*)* @"$s14generic_vtable8ConcreteC2m3yyF" +// CHECK-SAME: void (%T14generic_vtable8ConcreteC*)* {{@"\$s14generic_vtable8ConcreteC2m3yyF"|.* @"\$s14generic_vtable8ConcreteC2m3yyF.ptrauth"}} // -- vtable entry for 'm4()' -// CHECK-SAME: void (%T14generic_vtable8ConcreteC*)* @"$s14generic_vtable8ConcreteC2m4yyF" +// CHECK-SAME: void (%T14generic_vtable8ConcreteC*)* {{@"\$s14generic_vtable8ConcreteC2m4yyF"|.* @"\$s14generic_vtable8ConcreteC2m4yyF.ptrauth"}} // -- // CHECK-SAME: }>, align @@ -157,7 +157,7 @@ public class Concrete : Derived { // - 2 immediate members: // - type metadata for generic parameter T, // - and vtable entry for 'm3()' -// CHECK: [[METADATA:%.*]] = call %swift.type* @swift_allocateGenericClassMetadata(%swift.type_descriptor* %0, i8** %1, i8* %2) +// CHECK: [[METADATA:%.*]] = call %swift.type* @swift_allocateGenericClassMetadata(%swift.type_descriptor* {{.*}}, i8** %1, i8* %2) // CHECK: ret %swift.type* [[METADATA]] // CHECK-LABEL: define internal swiftcc %swift.metadata_response @"$s14generic_vtable7DerivedCMr" diff --git a/test/IRGen/indirect_argument.sil b/test/IRGen/indirect_argument.sil index ea8ce00d0a4e8..ed24a2dc1676c 100644 --- a/test/IRGen/indirect_argument.sil +++ b/test/IRGen/indirect_argument.sil @@ -66,7 +66,7 @@ entry(%o : $*Huge, %x : $Huge): // CHECK-NOT: alloca // CHECK: [[CLOSURE:%.*]] = call noalias %swift.refcounted* @swift_allocObject // CHECK: bitcast %swift.refcounted* [[CLOSURE]] to <{ %swift.refcounted, %T17indirect_argument4HugeV }>* -// CHECK: call swiftcc void @"$s24huge_partial_applicationTA"(%T17indirect_argument4HugeV* noalias nocapture dereferenceable({{.*}}) %0, %swift.refcounted* swiftself [[CLOSURE]]) +// CHECK: call swiftcc {{.*}} @"$s24huge_partial_applicationTA{{(\.ptrauth)?}}"{{.*}}(%T17indirect_argument4HugeV* noalias nocapture dereferenceable({{.*}}) %0, %swift.refcounted* swiftself [[CLOSURE]]) // CHECK: define internal swiftcc void @"$s24huge_partial_applicationTA"(%T17indirect_argument4HugeV* noalias nocapture dereferenceable({{.*}}) %0, %swift.refcounted* swiftself %1) // CHECK: [[TMP_ARG:%.*]] = alloca // CHECK-NOT: tail @@ -83,7 +83,7 @@ entry(%x : $Huge, %y : $Huge): // CHECK: [[TMP_RET:%.*]] = alloca // CHECK: [[CLOSURE:%.*]] = call noalias %swift.refcounted* @swift_allocObject // CHECK: bitcast %swift.refcounted* [[CLOSURE]] to <{ %swift.refcounted, %T17indirect_argument4HugeV }>* -// CHECK: call swiftcc void @"$s30huge_partial_application_stretTA"(%T17indirect_argument4HugeV* noalias nocapture sret [[TMP_RET]], %T17indirect_argument4HugeV* noalias nocapture dereferenceable({{.*}}) %1, %swift.refcounted* swiftself [[CLOSURE]]) +// CHECK: call swiftcc {{.*}} @"$s30huge_partial_application_stretTA{{(\.ptrauth)?}}"{{.*}}(%T17indirect_argument4HugeV* noalias nocapture sret [[TMP_RET]], %T17indirect_argument4HugeV* noalias nocapture dereferenceable({{.*}}) %1, %swift.refcounted* swiftself [[CLOSURE]]) // CHECK: define internal swiftcc void @"$s30huge_partial_application_stretTA"(%T17indirect_argument4HugeV* noalias nocapture sret %0, %T17indirect_argument4HugeV* noalias nocapture dereferenceable({{.*}}) %1, %swift.refcounted* swiftself %2) // CHECK: [[TMP_ARG:%.*]] = alloca // CHECK-NOT: tail diff --git a/test/IRGen/keypaths.sil b/test/IRGen/keypaths.sil index 50f8778141b42..ca41bf4ad8548 100644 --- a/test/IRGen/keypaths.sil +++ b/test/IRGen/keypaths.sil @@ -172,7 +172,7 @@ sil_vtable C2 {} // -- computed, get-only, identified by (indirected) function pointer, no args // CHECK-SAME: , // CHECK-SAME: @{{got.|__imp_}}k_id -// CHECK-SAME: void (%TSi*, %T8keypaths1SV*)* @k_get +// CHECK-SAME: void (%TSi*, %T8keypaths1SV*)* {{.*}}@k_get{{.*}} // -- %l: computed // CHECK: [[KP_L:@keypath(\..*)?]] = private global <{ {{.*}} }> <{ @@ -185,7 +185,7 @@ sil_vtable C2 {} // CHECK-SAME: , // CHECK-SAME: @"$s8keypaths1CCMn" // CHECK-SAME: void (%TSi*, %T8keypaths1CC**)* @l_get -// CHECK-SAME: void (%TSi*, %T8keypaths1CC**)* @l_set +// CHECK-SAME: void (%TSi*, %T8keypaths1CC**)* @l_set{{.*}} // -- %m: computed // CHECK: [[KP_M:@keypath(\..*)?]] = private global <{ {{.*}} }> <{ @@ -197,8 +197,8 @@ sil_vtable C2 {} // -- computed, settable, nonmutating, identified by property offset, no args // CHECK-SAME: , // CHECK-SAME: [[WORD]] -// CHECK-SAME: void (%swift.function*, %T8keypaths1SV*)* @m_get -// CHECK-SAME: void (%swift.function*, %T8keypaths1SV*)* @m_set +// CHECK-SAME: void (%swift.function*, %T8keypaths1SV*)* {{.*}}@m_get +// CHECK-SAME: void (%swift.function*, %T8keypaths1SV*)* {{.*}}@m_set{{.*}} // -- %m2: reabstracted // Note: the contents here aren't interesting. The test triggered infinite diff --git a/test/IRGen/lifetime.sil b/test/IRGen/lifetime.sil index 4e07ae0d912d8..e40bce795462e 100644 --- a/test/IRGen/lifetime.sil +++ b/test/IRGen/lifetime.sil @@ -1,4 +1,4 @@ -// RUN: %target-swift-frontend -gnone -emit-ir %s | %FileCheck %s -DINT=i%target-ptrsize +// RUN: %target-swift-frontend -gnone -emit-ir %s | %FileCheck --check-prefix=CHECK --check-prefix=CHECK-%target-cpu %s -DINT=i%target-ptrsize // CHECK: [[OPAQUE:%swift.opaque]] = type opaque // CHECK: [[TYPE:%swift.type]] = type @@ -32,11 +32,15 @@ bb0(%x : $*T): // CHECK-NEXT: [[T3:%.*]] = getelementptr inbounds i8*, i8** [[VWT]], i32 2 // CHECK-NEXT: [[T4:%.*]] = load i8*, i8** [[T3]], align // CHECK-NEXT: [[INIT_WITH_COPY_FN:%.*]] = bitcast i8* [[T4]] to [[OPAQUE]]* ([[OPAQUE]]*, [[OPAQUE]]*, [[TYPE]]*)* +// CHECK-arm64e-NEXT: ptrtoint i8** [[T3]] to i64 +// CHECK-arm64e-NEXT: call i64 @llvm.ptrauth.blend.i64 // CHECK-NEXT: [[Y:%.*]] = call [[OPAQUE]]* [[INIT_WITH_COPY_FN]]([[OPAQUE]]* noalias [[Y_TMP]], [[OPAQUE]]* noalias [[X:%.*]], [[TYPE]]* %T) // Destroy 'y'. // CHECK-NEXT: [[T3:%.*]] = getelementptr inbounds i8*, i8** [[VWT]], i32 1 // CHECK-NEXT: [[T4:%.*]] = load i8*, i8** [[T3]], align // CHECK-NEXT: [[DESTROY_FN:%.*]] = bitcast i8* [[T4]] to void ([[OPAQUE]]*, [[TYPE]]*)* +// CHECK-arm64e-NEXT: ptrtoint i8** [[T3]] to i64 +// CHECK-arm64e-NEXT: call i64 @llvm.ptrauth.blend.i64 // CHECK-NEXT: call void [[DESTROY_FN]]([[OPAQUE]]* noalias [[Y_TMP]], [[TYPE]]* %T) // Destroy 'x'. // CHECK-NEXT: call void [[DESTROY_FN]]([[OPAQUE]]* noalias [[X]], [[TYPE]]* %T) @@ -71,16 +75,22 @@ bb0(%x : $*T): // CHECK-NEXT: [[T3:%.*]] = getelementptr inbounds i8*, i8** [[VWT]], i32 2 // CHECK-NEXT: [[T4:%.*]] = load i8*, i8** [[T3]], align // CHECK-NEXT: [[INIT_WITH_COPY_FN:%.*]] = bitcast i8* [[T4]] to [[OPAQUE]]* ([[OPAQUE]]*, [[OPAQUE]]*, [[TYPE]]*)* +// CHECK-arm64e-NEXT: ptrtoint i8** [[T3]] to i64 +// CHECK-arm64e-NEXT: call i64 @llvm.ptrauth.blend.i64 // CHECK-NEXT: [[Y:%.*]] = call [[OPAQUE]]* [[INIT_WITH_COPY_FN]]([[OPAQUE]]* noalias [[Y_TMP]], [[OPAQUE]]* noalias [[X:%.*]], [[TYPE]]* %T) // Destroy 'y'. // CHECK-NEXT: [[T3:%.*]] = getelementptr inbounds i8*, i8** [[VWT]], i32 1 // CHECK-NEXT: [[T4:%.*]] = load i8*, i8** [[T3]], align // CHECK-NEXT: [[DESTROY_FN:%.*]] = bitcast i8* [[T4]] to void ([[OPAQUE]]*, [[TYPE]]*)* +// CHECK-arm64e-NEXT: ptrtoint i8** [[T3]] to i64 +// CHECK-arm64e-NEXT: call i64 @llvm.ptrauth.blend.i64 // CHECK-NEXT: call void [[DESTROY_FN]]([[OPAQUE]]* noalias [[Y_TMP]], [[TYPE]]* %T) // Copy 'x' into 'y' again, this time as a take. // CHECK-NEXT: [[T3:%.*]] = getelementptr inbounds i8*, i8** [[VWT]], i32 4 // CHECK-NEXT: [[T4:%.*]] = load i8*, i8** [[T3]], align // CHECK-NEXT: [[TAKE_FN:%.*]] = bitcast i8* [[T4]] to [[OPAQUE]]* ([[OPAQUE]]*, [[OPAQUE]]*, [[TYPE]]*)* +// CHECK-arm64e-NEXT: ptrtoint i8** [[T3]] to i64 +// CHECK-arm64e-NEXT: call i64 @llvm.ptrauth.blend.i64 // CHECK-NEXT: call [[OPAQUE]]* [[TAKE_FN]]([[OPAQUE]]* noalias [[Y_TMP]], [[OPAQUE]]* noalias [[X]], [[TYPE]]* %T) // Destroy 'y'. // CHECK-NEXT: call void [[DESTROY_FN]]([[OPAQUE]]* noalias [[Y_TMP]], [[TYPE]]* %T) diff --git a/test/IRGen/objc_int_encoding.sil b/test/IRGen/objc_int_encoding.sil index 538e4922d2d22..77d0ea80c3ffc 100644 --- a/test/IRGen/objc_int_encoding.sil +++ b/test/IRGen/objc_int_encoding.sil @@ -5,7 +5,7 @@ // CHECK-64: [[INT_UINT_METHOD_ENCODING:@.*]] = private unnamed_addr constant {{.*}} c"Q24@0:8q16\00" // CHECK-32: [[INT_UINT_METHOD_ENCODING:@.*]] = private unnamed_addr constant {{.*}} c"I12@0:4i8\00" -// CHECK: @_INSTANCE_METHODS__TtC17objc_int_encoding3Foo = private constant {{.*}} [[SELECTOR]], {{.*}} [[INT_UINT_METHOD_ENCODING]], {{.*}} @"$s17objc_int_encoding3FooC3foo1xSuSi_tFTo" +// CHECK: @_INSTANCE_METHODS__TtC17objc_int_encoding3Foo = private constant {{.*}} [[SELECTOR]], {{.*}} [[INT_UINT_METHOD_ENCODING]], {{.*}} @"$s17objc_int_encoding3FooC3foo1xSuSi_tFTo{{(\.ptrauth)?}}" sil_stage canonical diff --git a/test/IRGen/objc_simd.sil b/test/IRGen/objc_simd.sil index 1b243c2cd6e15..210094ed1f90b 100644 --- a/test/IRGen/objc_simd.sil +++ b/test/IRGen/objc_simd.sil @@ -17,6 +17,7 @@ func forceStuff(x: float4, y: float3) -> (Float, Float, Float, Float) { // i386-LABEL: define{{( dllexport)?}}{{( protected)?}} <2 x i64> @simd_c_args(<4 x float> %0) // aarch64-LABEL: define{{( dllexport)?}}{{( protected)?}} <4 x float> @simd_c_args(<4 x float> %0) // arm64-LABEL: define{{( dllexport)?}}{{( protected)?}} <4 x float> @simd_c_args(<4 x float> %0) +// arm64e-LABEL: define{{( dllexport)?}}{{( protected)?}} <4 x float> @simd_c_args(<4 x float> %0) // armv6-LABEL: define{{( dllexport)?}}{{( protected)?}} <4 x float> @simd_c_args(<4 x float> %0) // armv7-LABEL: define{{( dllexport)?}}{{( protected)?}} <4 x float> @simd_c_args(<4 x float> %0) // armv7s-LABEL: define{{( dllexport)?}}{{( protected)?}} <4 x float> @simd_c_args(<4 x float> %0) @@ -33,6 +34,7 @@ entry(%x : $float4): // i386-LABEL: define{{( dllexport)?}}{{( protected)?}} <2 x i64> @simd_c_args_float3(<3 x float> %0) // aarch64-LABEL: define{{( dllexport)?}}{{( protected)?}} <3 x float> @simd_c_args_float3(<4 x i32> %0) // arm64-LABEL: define{{( dllexport)?}}{{( protected)?}} <3 x float> @simd_c_args_float3(<4 x i32> %0) +// arm64e-LABEL: define{{( dllexport)?}}{{( protected)?}} <3 x float> @simd_c_args_float3(<4 x i32> %0) // armv6-LABEL: define{{( dllexport)?}}{{( protected)?}} <3 x float> @simd_c_args_float3(<4 x i32> %0) // armv7-ios-LABEL: define <3 x float> @simd_c_args_float3(<4 x i32> %0) // armv7-linux-LABEL: define protected <3 x float> @simd_c_args_float3(<4 x i32> %0) diff --git a/test/IRGen/objc_subclass.swift b/test/IRGen/objc_subclass.swift index 0f8063b6f1a18..bc317a21cc50b 100644 --- a/test/IRGen/objc_subclass.swift +++ b/test/IRGen/objc_subclass.swift @@ -68,47 +68,47 @@ // CHECK-32: [11 x { i8*, i8*, i8* }] [{ i8*, i8*, i8* } { // CHECK-32: i8* getelementptr inbounds ([2 x i8], [2 x i8]* @"\01L_selector_data(x)", i32 0, i32 0), // CHECK-32: i8* getelementptr inbounds ([7 x i8], [7 x i8]* [[METHOD_TYPE_ENCODING1]], i32 0, i32 0), -// CHECK-32: i8* bitcast (i32 (%0*, i8*)* @"$s13objc_subclass10SwiftGizmoC1xSivgTo" to i8*) +// CHECK-32: i8* bitcast {{.*}}* @"$s13objc_subclass10SwiftGizmoC1xSivgTo{{(\.ptrauth)?}}" to i8*) // CHECK-32: }, { i8*, i8*, i8* } { // CHECK-32: i8* getelementptr inbounds ([6 x i8], [6 x i8]* @"\01L_selector_data(setX:)", i32 0, i32 0), // CHECK-32: i8* getelementptr inbounds ([10 x i8], [10 x i8]* [[METHOD_TYPE_ENCODING2]], i32 0, i32 0), -// CHECK-32: i8* bitcast (void (%0*, i8*, i32)* @"$s13objc_subclass10SwiftGizmoC1xSivsTo" to i8*) +// CHECK-32: i8* bitcast {{.*}}* @"$s13objc_subclass10SwiftGizmoC1xSivsTo{{(\.ptrauth)?}}" to i8*) // CHECK-32: }, { i8*, i8*, i8* } { // CHECK-32: i8* getelementptr inbounds ([5 x i8], [5 x i8]* @"\01L_selector_data(getX)", i32 0, i32 0), // CHECK-32: i8* getelementptr inbounds ([7 x i8], [7 x i8]* [[METHOD_TYPE_ENCODING1]], i32 0, i32 0), -// CHECK-32: i8* bitcast (i32 (%0*, i8*)* @"$s13objc_subclass10SwiftGizmoC4getXSiyFTo" to i8*) +// CHECK-32: i8* bitcast {{.*}}* @"$s13objc_subclass10SwiftGizmoC4getXSiyFTo{{(\.ptrauth)?}}" to i8*) // CHECK-32: }, { i8*, i8*, i8* } { // CHECK-32: i8* getelementptr inbounds ([10 x i8], [10 x i8]* @"\01L_selector_data(duplicate)", i32 0, i32 0), // CHECK-32: i8* getelementptr inbounds ([7 x i8], [7 x i8]* [[GETTER_ENCODING]], i32 0, i32 0), -// CHECK-32: i8* bitcast (%1* (%0*, i8*)* @"$s13objc_subclass10SwiftGizmoC9duplicateSo0D0CyFTo" to i8*) +// CHECK-32: i8* bitcast ({{.*}}* @"$s13objc_subclass10SwiftGizmoC9duplicateSo0D0CyFTo{{(\.ptrauth)?}}" to i8*) // CHECK-32: }, { i8*, i8*, i8* } { // CHECK-32: i8* getelementptr inbounds ([5 x i8], [5 x i8]* @"\01L_selector_data(init)", i32 0, i32 0), // CHECK-32: i8* getelementptr inbounds ([7 x i8], [7 x i8]* [[GETTER_ENCODING]], i32 0, i32 0), -// CHECK-32: i8* bitcast (%0* (%0*, i8*)* @"$s13objc_subclass10SwiftGizmoCACycfcTo" to i8*) +// CHECK-32: i8* bitcast ({{.*}}* @"$s13objc_subclass10SwiftGizmoCACycfcTo{{(\.ptrauth)?}}" to i8*) // CHECK-32: }, { i8*, i8*, i8* } { // CHECK-32: i8* getelementptr inbounds ([20 x i8], [20 x i8]* @"\01L_selector_data(initWithInt:string:)", i32 0, i32 0), // CHECK-32: i8* getelementptr inbounds ([13 x i8], [13 x i8]* [[INIT_ENCODING]], i32 0, i32 0), -// CHECK-32: i8* bitcast (%0* (%0*, i8*, i32, %2*)* @"$s13objc_subclass10SwiftGizmoC3int6stringACSi_SStcfcTo" to i8*) +// CHECK-32: i8* bitcast ({{.*}}* @"$s13objc_subclass10SwiftGizmoC3int6stringACSi_SStcfcTo{{(\.ptrauth)?}}" to i8*) // CHECK-32: }, { i8*, i8*, i8* } { // CHECK-32: i8* getelementptr inbounds ([8 x i8], [8 x i8]* @"\01L_selector_data(dealloc)", i32 0, i32 0), // CHECK-32: i8* getelementptr inbounds ([7 x i8], [7 x i8]* [[DEALLOC_ENCODING]], i32 0, i32 0), -// CHECK-32: i8* bitcast (void (%0*, i8*)* @"$s13objc_subclass10SwiftGizmoCfDTo" to i8*) +// CHECK-32: i8* bitcast {{.*}}* @"$s13objc_subclass10SwiftGizmoCfDTo{{(\.ptrauth)?}}" to i8*) // CHECK-32: }, { i8*, i8*, i8* } { // CHECK-32: i8* getelementptr inbounds ([10 x i8], [10 x i8]* @"\01L_selector_data(isEnabled)", i32 0, i32 0), // CHECK-32: i8* getelementptr inbounds ([7 x i8], [7 x i8]* {{@[0-9]+}}, i32 0, i32 0), -// CHECK-32: i8* bitcast ({{(i8|i1)}} (%0*, i8*)* @"$s13objc_subclass10SwiftGizmoC7enabledSbvgTo" to i8*) +// CHECK-32: i8* bitcast ({{.*}}* @"$s13objc_subclass10SwiftGizmoC7enabledSbvgTo{{(\.ptrauth)?}}" to i8*) // CHECK-32: }, { i8*, i8*, i8* } { // CHECK-32: i8* getelementptr inbounds ([14 x i8], [14 x i8]* @"\01L_selector_data(setIsEnabled:)", i32 0, i32 0), // CHECK-32: i8* getelementptr inbounds ([10 x i8], [10 x i8]* {{@[0-9]+}}, i32 0, i32 0), -// CHECK-32: i8* bitcast (void (%0*, i8*, {{(i8|i1)}})* @"$s13objc_subclass10SwiftGizmoC7enabledSbvsTo" to i8*) +// CHECK-32: i8* bitcast ({{.*}}* @"$s13objc_subclass10SwiftGizmoC7enabledSbvsTo{{(\.ptrauth)?}}" to i8*) // CHECK-32: }, { i8*, i8*, i8* } { // CHECK-32: i8* getelementptr inbounds ([17 x i8], [17 x i8]* @"\01L_selector_data(initWithBellsOn:)", i32 0, i32 0), // CHECK-32: i8* getelementptr inbounds ([10 x i8], [10 x i8]* {{@[0-9]+}}, i32 0, i32 0), -// CHECK-32: i8* bitcast (%0* (%0*, i8*, i32)* @"$s13objc_subclass10SwiftGizmoC7bellsOnACSgSi_tcfcTo" to i8*) +// CHECK-32: i8* bitcast ({{.*}}* @"$s13objc_subclass10SwiftGizmoC7bellsOnACSgSi_tcfcTo{{(\.ptrauth)?}}" to i8*) // CHECK-32: }, { i8*, i8*, i8* } { // CHECK-32: i8* getelementptr inbounds ([15 x i8], [15 x i8]* @"\01L_selector_data(.cxx_construct)", i32 0, i32 0), // CHECK-32: i8* getelementptr inbounds ([{{[0-9]+}} x i8], [{{[0-9]+}} x i8]* {{@[0-9]+}}, i32 0, i32 0), -// CHECK-32: i8* bitcast (%0* (%0*, i8*)* @"$s13objc_subclass10SwiftGizmoCfeTo" to i8*) +// CHECK-32: i8* bitcast ({{.*}}* @"$s13objc_subclass10SwiftGizmoCfeTo{{(\.ptrauth)?}}" to i8*) // CHECK-32: }] // CHECK-32: }, section "__DATA, __objc_const", align 4 @@ -118,47 +118,47 @@ // CHECK-64: [11 x { i8*, i8*, i8* }] [{ // CHECK-64: i8* getelementptr inbounds ([2 x i8], [2 x i8]* @"\01L_selector_data(x)", i64 0, i64 0), // CHECK-64: i8* getelementptr inbounds ([8 x i8], [8 x i8]* [[METHOD_TYPE_ENCODING1]], i64 0, i64 0) -// CHECK-64: i8* bitcast (i64 ([[OPAQUE2:%.*]]*, i8*)* @"$s13objc_subclass10SwiftGizmoC1xSivgTo" to i8*) +// CHECK-64: i8* bitcast ({{.*}}* @"$s13objc_subclass10SwiftGizmoC1xSivgTo{{(\.ptrauth)?}}" to i8*) // CHECK-64: }, { // CHECK-64: i8* getelementptr inbounds ([6 x i8], [6 x i8]* @"\01L_selector_data(setX:)", i64 0, i64 0), // CHECK-64: i8* getelementptr inbounds ([11 x i8], [11 x i8]* [[METHOD_TYPE_ENCODING2]], i64 0, i64 0) -// CHECK-64: i8* bitcast (void ([[OPAQUE3:%.*]]*, i8*, i64)* @"$s13objc_subclass10SwiftGizmoC1xSivsTo" to i8*) +// CHECK-64: i8* bitcast ({{.*}}* @"$s13objc_subclass10SwiftGizmoC1xSivsTo{{(\.ptrauth)?}}" to i8*) // CHECK-64: }, { // CHECK-64: i8* getelementptr inbounds ([5 x i8], [5 x i8]* @"\01L_selector_data(getX)", i64 0, i64 0), // CHECK-64: i8* getelementptr inbounds ([8 x i8], [8 x i8]* [[METHOD_TYPE_ENCODING1]], i64 0, i64 0) -// CHECK-64: i8* bitcast (i64 ([[OPAQUE2]]*, i8*)* @"$s13objc_subclass10SwiftGizmoC4getXSiyFTo" to i8*) +// CHECK-64: i8* bitcast ({{.*}}* @"$s13objc_subclass10SwiftGizmoC4getXSiyFTo{{(\.ptrauth)?}}" to i8*) // CHECK-64: }, { // CHECK-64: i8* getelementptr inbounds ([10 x i8], [10 x i8]* @"\01L_selector_data(duplicate)", i64 0, i64 0), // CHECK-64: i8* getelementptr inbounds ([8 x i8], [8 x i8]* [[GETTER_ENCODING]], i64 0, i64 0), -// CHECK-64: i8* bitcast ([[OPAQUE1:.*]]* ([[OPAQUE0:%.*]]*, i8*)* @"$s13objc_subclass10SwiftGizmoC9duplicateSo0D0CyFTo" to i8*) +// CHECK-64: i8* bitcast ({{.*}}* @"$s13objc_subclass10SwiftGizmoC9duplicateSo0D0CyFTo{{(\.ptrauth)?}}" to i8*) // CHECK-64: }, { // CHECK-64: i8* getelementptr inbounds ([5 x i8], [5 x i8]* @"\01L_selector_data(init)", i64 0, i64 0), // CHECK-64: i8* getelementptr inbounds ([8 x i8], [8 x i8]* [[GETTER_ENCODING]], i64 0, i64 0), -// CHECK-64: i8* bitcast ([[OPAQUE5:.*]]* ([[OPAQUE6:.*]]*, i8*)* @"$s13objc_subclass10SwiftGizmoCACycfcTo" to i8*) +// CHECK-64: i8* bitcast ({{.*}}* @"$s13objc_subclass10SwiftGizmoCACycfcTo{{(\.ptrauth)?}}" to i8*) // CHECK-64: }, { // CHECK-64: i8* getelementptr inbounds ([20 x i8], [20 x i8]* @"\01L_selector_data(initWithInt:string:)", i64 0, i64 0), // CHECK-64: i8* getelementptr inbounds ([14 x i8], [14 x i8]* [[INIT_ENCODING]], i64 0, i64 0), -// CHECK-64: i8* bitcast ([[OPAQUE7:%.*]]* ([[OPAQUE8:%.*]]*, i8*, i64, [[OPAQUEONE:.*]]*)* @"$s13objc_subclass10SwiftGizmoC3int6stringACSi_SStcfcTo" to i8*) +// CHECK-64: i8* bitcast ({{.*}}* @"$s13objc_subclass10SwiftGizmoC3int6stringACSi_SStcfcTo{{(\.ptrauth)?}}" to i8*) // CHECK-64: }, { // CHECK-64: i8* getelementptr inbounds ([8 x i8], [8 x i8]* @"\01L_selector_data(dealloc)", i64 0, i64 0), // CHECK-64: i8* getelementptr inbounds ([8 x i8], [8 x i8]* [[DEALLOC_ENCODING]], i64 0, i64 0), -// CHECK-64: i8* bitcast (void ([[OPAQUE10:%.*]]*, i8*)* @"$s13objc_subclass10SwiftGizmoCfDTo" to i8*) +// CHECK-64: i8* bitcast ({{.*}}* @"$s13objc_subclass10SwiftGizmoCfDTo{{(\.ptrauth)?}}" to i8*) // CHECK-64: }, { // CHECK-64: i8* getelementptr inbounds ([10 x i8], [10 x i8]* @"\01L_selector_data(isEnabled)", i64 0, i64 0), // CHECK-64: i8* getelementptr inbounds ([8 x i8], [8 x i8]* {{@[0-9]+}}, i64 0, i64 0), -// CHECK-64: i8* bitcast ({{(i8|i1)}} ([[OPAQUE11:%.*]]*, i8*)* @"$s13objc_subclass10SwiftGizmoC7enabledSbvgTo" to i8*) +// CHECK-64: i8* bitcast ({{.*}}* @"$s13objc_subclass10SwiftGizmoC7enabledSbvgTo{{(\.ptrauth)?}}" to i8*) // CHECK-64: }, { // CHECK-64: i8* getelementptr inbounds ([14 x i8], [14 x i8]* @"\01L_selector_data(setIsEnabled:)", i64 0, i64 0), // CHECK-64: i8* getelementptr inbounds ([11 x i8], [11 x i8]* {{@[0-9]+}}, i64 0, i64 0), -// CHECK-64: i8* bitcast (void ([[OPAQUE12:%.*]]*, i8*, {{(i8|i1)}})* @"$s13objc_subclass10SwiftGizmoC7enabledSbvsTo" to i8*) +// CHECK-64: i8* bitcast ({{.*}}* @"$s13objc_subclass10SwiftGizmoC7enabledSbvsTo{{(\.ptrauth)?}}" to i8*) // CHECK-64: }, { // CHECK-64: i8* getelementptr inbounds ([17 x i8], [17 x i8]* @"\01L_selector_data(initWithBellsOn:)", i64 0, i64 0), // CHECK-64: i8* getelementptr inbounds ([11 x i8], [11 x i8]* {{@[0-9]+}}, i64 0, i64 0), -// CHECK-64: i8* bitcast ([[OPAQUE11:%.*]]* ([[OPAQUE12:%.*]]*, i8*, i64)* @"$s13objc_subclass10SwiftGizmoC7bellsOnACSgSi_tcfcTo" to i8*) +// CHECK-64: i8* bitcast ({{.*}}* @"$s13objc_subclass10SwiftGizmoC7bellsOnACSgSi_tcfcTo{{(\.ptrauth)?}}" to i8*) // CHECK-64: }, { // CHECK-64: i8* getelementptr inbounds ([15 x i8], [15 x i8]* @"\01L_selector_data(.cxx_construct)", i64 0, i64 0), // CHECK-64: i8* getelementptr inbounds ([{{[0-9]+}} x i8], [{{[0-9]+}} x i8]* {{@[0-9]+}}, i64 0, i64 0), -// CHECK-64: i8* bitcast ([[OPAQUE5]]* ([[OPAQUE6]]*, i8*)* @"$s13objc_subclass10SwiftGizmoCfeTo" to i8*) +// CHECK-64: i8* bitcast ({{.*}}* @"$s13objc_subclass10SwiftGizmoCfeTo{{(\.ptrauth)?}}" to i8*) // CHECK-64: }] // CHECK-64: }, section "__DATA, __objc_const", align 8 @@ -228,23 +228,23 @@ // CHECK-32: { // CHECK-32: i8* getelementptr inbounds ([3 x i8], [3 x i8]* @"\01L_selector_data(sg)", i32 0, i32 0), // CHECK-32: i8* getelementptr inbounds ([7 x i8], [7 x i8]* [[GETTER_ENCODING]], i32 0, i32 0), -// CHECK-32: i8* bitcast (%0* (%3*, i8*)* @"$s13objc_subclass11SwiftGizmo2C2sgAA0C5GizmoCvgTo" to i8*) +// CHECK-32: i8* bitcast ({{.*}}* @"$s13objc_subclass11SwiftGizmo2C2sgAA0C5GizmoCvgTo{{(\.ptrauth)?}}" to i8*) // CHECK-32: }, { // CHECK-32: i8* getelementptr inbounds ([7 x i8], [7 x i8]* @"\01L_selector_data(setSg:)", i32 0, i32 0), // CHECK-32: i8* getelementptr inbounds ([10 x i8], [10 x i8]* [[SETTER_ENCODING]], i32 0, i32 0), -// CHECK-32: i8* bitcast (void (%3*, i8*, %0*)* @"$s13objc_subclass11SwiftGizmo2C2sgAA0C5GizmoCvsTo" to i8*) +// CHECK-32: i8* bitcast ({{.*}}* @"$s13objc_subclass11SwiftGizmo2C2sgAA0C5GizmoCvsTo{{(\.ptrauth)?}}" to i8*) // CHECK-32: }, { // CHECK-32: i8* getelementptr inbounds ([5 x i8], [5 x i8]* @"\01L_selector_data(init)", i32 0, i32 0), // CHECK-32: i8* getelementptr inbounds ([7 x i8], [7 x i8]* [[GETTER_ENCODING]], i32 0, i32 0), -// CHECK-32: i8* bitcast (%3* (%3*, i8*)* @"$s13objc_subclass11SwiftGizmo2CACycfcTo" to i8*) +// CHECK-32: i8* bitcast ({{.*}}* @"$s13objc_subclass11SwiftGizmo2CACycfcTo{{(\.ptrauth)?}}" to i8*) // CHECK-32: }, { // CHECK-32: i8* getelementptr inbounds ([17 x i8], [17 x i8]* @"\01L_selector_data(initWithBellsOn:)", i32 0, i32 0), // CHECK-32: i8* getelementptr inbounds ([10 x i8], [10 x i8]* {{@[0-9]+}}, i32 0, i32 0), -// CHECK-32: i8* bitcast (%3* (%3*, i8*, i32)* @"$s13objc_subclass11SwiftGizmo2C7bellsOnACSgSi_tcfcTo" to i8*) +// CHECK-32: i8* bitcast ({{.*}}* @"$s13objc_subclass11SwiftGizmo2C7bellsOnACSgSi_tcfcTo{{(\.ptrauth)?}}" to i8*) // CHECK-32: }, { // CHECK-32: i8* getelementptr inbounds ([14 x i8], [14 x i8]* @"\01L_selector_data(.cxx_destruct)", i32 0, i32 0), // CHECK-32: i8* getelementptr inbounds ([{{[0-9]+}} x i8], [{{[0-9]+}} x i8]* {{@[0-9]+}}, i32 0, i32 0), -// CHECK-32: i8* bitcast (void (%3*, i8*)* @"$s13objc_subclass11SwiftGizmo2CfETo" to i8*) +// CHECK-32: i8* bitcast ({{.*}}* @"$s13objc_subclass11SwiftGizmo2CfETo{{(\.ptrauth)?}}" to i8*) // CHECK-32: } // CHECK-32: ] // CHECK-32: }, section "__DATA, __objc_const", align 4 @@ -256,23 +256,23 @@ // CHECK-64: { // CHECK-64: i8* getelementptr inbounds ([3 x i8], [3 x i8]* @"\01L_selector_data(sg)", i64 0, i64 0), // CHECK-64: i8* getelementptr inbounds ([8 x i8], [8 x i8]* [[GETTER_ENCODING]], i64 0, i64 0), -// CHECK-64: i8* bitcast ([[OPAQUE13:%.*]]* ([[OPAQUE14:%.*]]*, i8*)* @"$s13objc_subclass11SwiftGizmo2C2sgAA0C5GizmoCvgTo" to i8*) +// CHECK-64: i8* bitcast ({{.*}}* @"$s13objc_subclass11SwiftGizmo2C2sgAA0C5GizmoCvgTo{{(\.ptrauth)?}}" to i8*) // CHECK-64: }, { // CHECK-64: i8* getelementptr inbounds ([7 x i8], [7 x i8]* @"\01L_selector_data(setSg:)", i64 0, i64 0), // CHECK-64: i8* getelementptr inbounds ([11 x i8], [11 x i8]* [[SETTER_ENCODING]], i64 0, i64 0), -// CHECK-64: i8* bitcast (void ([[OPAQUE15:%.*]]*, i8*, [[OPAQUE16:%.*]]*)* @"$s13objc_subclass11SwiftGizmo2C2sgAA0C5GizmoCvsTo" to i8*) +// CHECK-64: i8* bitcast ({{.*}}* @"$s13objc_subclass11SwiftGizmo2C2sgAA0C5GizmoCvsTo{{(\.ptrauth)?}}" to i8*) // CHECK-64: }, { // CHECK-64: i8* getelementptr inbounds ([5 x i8], [5 x i8]* @"\01L_selector_data(init)", i64 0, i64 0), // CHECK-64: i8* getelementptr inbounds ([8 x i8], [8 x i8]* [[GETTER_ENCODING]], i64 0, i64 0), -// CHECK-64: i8* bitcast ([[OPAQUE18:%.*]]* ([[OPAQUE19:%.*]]*, i8*)* @"$s13objc_subclass11SwiftGizmo2CACycfcTo" to i8*) +// CHECK-64: i8* bitcast ({{.*}}* @"$s13objc_subclass11SwiftGizmo2CACycfcTo{{(\.ptrauth)?}}" to i8*) // CHECK-64: }, { // CHECK-64: i8* getelementptr inbounds ([17 x i8], [17 x i8]* @"\01L_selector_data(initWithBellsOn:)", i64 0, i64 0), // CHECK-64: i8* getelementptr inbounds ([11 x i8], [11 x i8]* {{@[0-9]+}}, i64 0, i64 0), -// CHECK-64: i8* bitcast ([[OPAQUE21:%.*]]* ([[OPAQUE22:%.*]]*, i8*, i64)* @"$s13objc_subclass11SwiftGizmo2C7bellsOnACSgSi_tcfcTo" to i8*) +// CHECK-64: i8* bitcast ({{.*}}* @"$s13objc_subclass11SwiftGizmo2C7bellsOnACSgSi_tcfcTo{{(\.ptrauth)?}}" to i8*) // CHECK-64: }, { // CHECK-64: i8* getelementptr inbounds ([14 x i8], [14 x i8]* @"\01L_selector_data(.cxx_destruct)", i64 0, i64 0), // CHECK-64: i8* getelementptr inbounds ([{{[0-9]+}} x i8], [{{[0-9]+}} x i8]* {{@[0-9]+}}, i64 0, i64 0) -// CHECK-64: i8* bitcast (void ([[OPAQUE20:%.*]]*, i8*)* @"$s13objc_subclass11SwiftGizmo2CfETo" to i8*) +// CHECK-64: i8* bitcast ({{.*}}* @"$s13objc_subclass11SwiftGizmo2CfETo{{(\.ptrauth)?}}" to i8*) // CHECK-64: } // CHECK-64: ] } diff --git a/test/IRGen/opaque_values_irgen.sil b/test/IRGen/opaque_values_irgen.sil index 9fd5d5c12a9a7..5af2ca69eb851 100644 --- a/test/IRGen/opaque_values_irgen.sil +++ b/test/IRGen/opaque_values_irgen.sil @@ -1,4 +1,4 @@ -// RUN: %target-swift-frontend -enable-sil-opaque-values -parse-stdlib -primary-file %s -emit-ir | %FileCheck %s +// RUN: %target-swift-frontend -enable-sil-opaque-values -parse-stdlib -primary-file %s -emit-ir | %FileCheck --check-prefix=CHECK --check-prefix=CHECK-%target-cpu %s import Builtin @@ -7,6 +7,8 @@ sil_stage canonical // CHECK: define hidden swiftcc void @f010_irgen_identity(%swift.opaque* noalias nocapture sret %0, %swift.opaque* noalias nocapture %1, %swift.type* %T) // CHECK: entry: // CHECK-NOT: call +// CHECK-arm64e: call i64 @llvm.ptrauth.blend.i64 +// CHECK-NOT: call // CHECK: %{{.*}} = call %swift.opaque* %initializeWithTake(%swift.opaque* noalias %0, %swift.opaque* noalias %1, %swift.type* %T) // CHECK-NOT: call // CHECK: ret void diff --git a/test/IRGen/optional_metatype.sil b/test/IRGen/optional_metatype.sil index 25348e464cd74..17c8aaa931365 100644 --- a/test/IRGen/optional_metatype.sil +++ b/test/IRGen/optional_metatype.sil @@ -14,6 +14,8 @@ import gizmo // i386: icmp eq i32 %0, 0 // arm64-LABEL: define{{( protected)?}} swiftcc void @optional_objc_metatype(i64 %0) // arm64: icmp eq i64 %0, 0 +// arm64e-LABEL: define{{( protected)?}} swiftcc void @optional_objc_metatype(i64 %0) +// arm64e: icmp eq i64 %0, 0 // armv7-LABEL: define{{( protected)?}} swiftcc void @optional_objc_metatype(i32 %0) // armv7: icmp eq i32 %0, 0 // armv7s-LABEL: define{{( protected)?}} swiftcc void @optional_objc_metatype(i32 %0) @@ -38,6 +40,8 @@ cont: // i386: icmp eq i32 %0, 0 // arm64-LABEL: define{{( protected)?}} swiftcc void @optional_swift_metatype(i64 %0) // arm64: icmp eq i64 %0, 0 +// arm64e-LABEL: define{{( protected)?}} swiftcc void @optional_swift_metatype(i64 %0) +// arm64e: icmp eq i64 %0, 0 // armv7-LABEL: define{{( protected)?}} swiftcc void @optional_swift_metatype(i32 %0) // armv7: icmp eq i32 %0, 0 // armv7s-LABEL: define{{( protected)?}} swiftcc void @optional_swift_metatype(i32 %0) diff --git a/test/IRGen/pic.swift b/test/IRGen/pic.swift index 2670f87328179..8afc50ec49846 100644 --- a/test/IRGen/pic.swift +++ b/test/IRGen/pic.swift @@ -80,6 +80,12 @@ public func use_global() -> Int { // aarch64: bl swift_endAccess // aarch64: ldr x0, [sp] +// arm64e-LABEL: _$s4main10use_globalSiyF: +// arm64e: adrp [[REG1:x[0-9]+]], _$s4main6globalSivp@PAGE +// arm64e: add [[REG1]], [[REG1]], _$s4main6globalSivp@PAGEOFF +// arm64e: bl _swift_beginAccess +// arm64e: ldr {{x[0-9]+}}, {{\[}}[[REG1]]{{\]}} + // powerpc64le-LABEL: {{_?}}$s4main10use_globalSiyF: // powerpc64le: bl swift_beginAccess // powerpc64le: addi 3, 3, ($s4main6globalSivp)@toc@l diff --git a/test/IRGen/prespecialized-metadata/enum-fileprivate-inmodule-1argument-1distinct_use.swift b/test/IRGen/prespecialized-metadata/enum-fileprivate-inmodule-1argument-1distinct_use.swift index 968a3a3552386..189efc4770b1d 100644 --- a/test/IRGen/prespecialized-metadata/enum-fileprivate-inmodule-1argument-1distinct_use.swift +++ b/test/IRGen/prespecialized-metadata/enum-fileprivate-inmodule-1argument-1distinct_use.swift @@ -14,7 +14,7 @@ // CHECK-SAME: }> <{ // i8** getelementptr inbounds (%swift.enum_vwtable, %swift.enum_vwtable* @"$s4main5Value[[UNIQUE_ID_1]]OySiGWV", i32 0, i32 0), // CHECK-SAME: [[INT]] 513, -// CHECK-SAME: %swift.type_descriptor* bitcast (<{ i32, i32, i32, i32, i32, i32, i32, i32, i32, i16, i16, i16, i16, i8, i8, i8, i8 }>* @"$s4main5Value[[UNIQUE_ID_1]]OMn" to %swift.type_descriptor*), +// CHECK-SAME: %swift.type_descriptor* bitcast ({{.*}}$s4main5Value[[UNIQUE_ID_1]]OMn{{.*}} to %swift.type_descriptor*), // CHECK-SAME: %swift.type* @"$sSiN", // CHECK-SAME: i64 3 // CHECK-SAME: }>, align [[ALIGNMENT]] @@ -83,6 +83,14 @@ doit() // CHECK-SAME: [[INT]] 0 // CHECK-SAME: } // CHECK: [[EXIT_NORMAL]]: -// CHECK: {{%[0-9]+}} = call swiftcc %swift.metadata_response @__swift_instantiateGenericMetadata([[INT]] %0, i8* [[ERASED_TYPE]], i8* undef, i8* undef, %swift.type_descriptor* bitcast (<{ i32, i32, i32, i32, i32, i32, i32, i32, i32, i16, i16, i16, i16, i8, i8, i8, i8 }>* @"$s4main5Value[[UNIQUE_ID_1]]OMn" to %swift.type_descriptor*)) #{{[0-9]+}} +// CHECK: {{%[0-9]+}} = call swiftcc %swift.metadata_response @__swift_instantiateGenericMetadata( +// CHECK-SAME: [[INT]] %0, +// CHECK-SAME: i8* [[ERASED_TYPE]], +// CHECK-SAME: i8* undef, +// CHECK-SAME: i8* undef, +// CHECK-SAME: %swift.type_descriptor* bitcast ( +// CHECK-SAME: {{.*}}$s4main5Value[[UNIQUE_ID_1]]OMn{{.*}} to %swift.type_descriptor* +// CHECK-SAME: ) +// CHECK-SAME: ) #{{[0-9]+}} // CHECK: ret %swift.metadata_response {{%[0-9]+}} // CHECK: } diff --git a/test/IRGen/prespecialized-metadata/enum-inmodule-0argument-within-class-1argument-1distinct_use.swift b/test/IRGen/prespecialized-metadata/enum-inmodule-0argument-within-class-1argument-1distinct_use.swift index 18b485ad8699f..edc2e5c2fa271 100644 --- a/test/IRGen/prespecialized-metadata/enum-inmodule-0argument-within-class-1argument-1distinct_use.swift +++ b/test/IRGen/prespecialized-metadata/enum-inmodule-0argument-within-class-1argument-1distinct_use.swift @@ -18,7 +18,7 @@ // i32 0 // ), // CHECK-SAME: [[INT]] 513, -// CHECK-SAME: %swift.type_descriptor* bitcast (<{ i32, i32, i32, i32, i32, i32, i32, i32, i32, i16, i16, i16, i16, i8, i8, i8, i8 }>* @"$s4main9NamespaceC5ValueOMn" to %swift.type_descriptor*), +// CHECK-SAME: %swift.type_descriptor* bitcast ({{.*}}$s4main9NamespaceC5ValueOMn{{.*}} to %swift.type_descriptor*), // CHECK-SAME: %swift.type* @"$sSiN", // CHECK-SAME: i64 3 // CHECK-SAME: }>, align [[ALIGNMENT]] @@ -90,6 +90,14 @@ doit() // CHECK-SAME: [[INT]] 0 // CHECK-SAME: } // CHECK: [[EXIT_NORMAL]]: -// CHECK: {{%[0-9]+}} = call swiftcc %swift.metadata_response @__swift_instantiateGenericMetadata([[INT]] %0, i8* [[ERASED_TYPE_1]], i8* undef, i8* undef, %swift.type_descriptor* bitcast (<{ i32, i32, i32, i32, i32, i32, i32, i32, i32, i16, i16, i16, i16, i8, i8, i8, i8 }>* @"$s4main9NamespaceC5ValueOMn" to %swift.type_descriptor*)) #{{[0-9]+}} +// CHECK: {{%[0-9]+}} = call swiftcc %swift.metadata_response @__swift_instantiateGenericMetadata( +// CHECK-SAME: [[INT]] %0, +// CHECK-SAME: i8* [[ERASED_TYPE_1]], +// CHECK-SAME: i8* undef, +// CHECK-SAME: i8* undef, +// CHECK-SAME: %swift.type_descriptor* bitcast ( +// CHECK-SAME: {{.*}}$s4main9NamespaceC5ValueOMn{{.*}} to %swift.type_descriptor* +// CHECK-SAME: ) +// CHECK-SAME: ) #{{[0-9]+}} // CHECK: ret %swift.metadata_response {{%[0-9]+}} // CHECK: } diff --git a/test/IRGen/prespecialized-metadata/enum-inmodule-1argument-0distinct_use.swift b/test/IRGen/prespecialized-metadata/enum-inmodule-1argument-0distinct_use.swift index 82edee93c8373..10cd548bd85e1 100644 --- a/test/IRGen/prespecialized-metadata/enum-inmodule-1argument-0distinct_use.swift +++ b/test/IRGen/prespecialized-metadata/enum-inmodule-1argument-0distinct_use.swift @@ -31,9 +31,7 @@ doit() // CHECK-SAME: i8* undef, // CHECK-SAME: i8* undef, // CHECK-SAME: %swift.type_descriptor* bitcast ( -// CHECK-SAME: <{ i32, i32, i32, i32, i32, i32, i32, i32, i32, i16, i16, i16, i16, i8, i8, i8, i8 }>* -// CHECK-SAME: @"$s4main5ValueOMn" -// CHECK-SAME: to %swift.type_descriptor* +// CHECK-SAME: {{.*}}$s4main5ValueOMn{{.*}} to %swift.type_descriptor* // CHECK-SAME: ) // CHECK-SAME: ) #{{[0-9]+}} // CHECK: ret %swift.metadata_response {{%[0-9]+}} diff --git a/test/IRGen/prespecialized-metadata/enum-inmodule-1argument-1conformance-1distinct_use.swift b/test/IRGen/prespecialized-metadata/enum-inmodule-1argument-1conformance-1distinct_use.swift index a529c4736f79e..129e4e580ea9b 100644 --- a/test/IRGen/prespecialized-metadata/enum-inmodule-1argument-1conformance-1distinct_use.swift +++ b/test/IRGen/prespecialized-metadata/enum-inmodule-1argument-1conformance-1distinct_use.swift @@ -17,7 +17,9 @@ // CHECK-SAME: }> <{ // CHECK-SAME: i8** getelementptr inbounds (%swift.enum_vwtable, %swift.enum_vwtable* @"$s4main5ValueOySiGWV", i32 0, i32 0), // CHECK-SAME: [[INT]] 513, -// CHECK-SAME: %swift.type_descriptor* bitcast (<{ i32, i32, i32, i32, i32, i32, i32, i32, i32, i16, i16, i16, i16, i8, i8, i8, i8, i32, i32, i32 }>* @"$s4main5ValueOMn" to %swift.type_descriptor*), +// CHECK-SAME: %swift.type_descriptor* bitcast ( +// CHECK-SAME: {{.*}}$s4main5ValueOMn{{.*}} to %swift.type_descriptor* +// CHECK-SAME: ), // CHECK-SAME: %swift.type* @"$sSiN", // CHECK-SAME: i8** getelementptr inbounds ([1 x i8*], [1 x i8*]* @"$sSi4main1PAAWP", i32 0, i32 0), // CHECK-SAME: i64 3 @@ -92,6 +94,14 @@ doit() // CHECK-SAME: [[INT]] 0 // CHECK-SAME: } // CHECK: [[EXIT_NORMAL]]: -// CHECK: {{%[0-9]+}} = call swiftcc %swift.metadata_response @__swift_instantiateGenericMetadata([[INT]] %0, i8* [[ERASED_TYPE]], i8* [[ERASED_TABLE]], i8* undef, %swift.type_descriptor* bitcast (<{ i32, i32, i32, i32, i32, i32, i32, i32, i32, i16, i16, i16, i16, i8, i8, i8, i8, i32, i32, i32 }>* @"$s4main5ValueOMn" to %swift.type_descriptor*)) +// CHECK: {{%[0-9]+}} = call swiftcc %swift.metadata_response @__swift_instantiateGenericMetadata( +// CHECK-SAME: [[INT]] %0, +// CHECK-SAME: i8* [[ERASED_TYPE]], +// CHECK-SAME: i8* [[ERASED_TABLE]], +// CHECK-SAME: i8* undef, +// CHECK-SAME: %swift.type_descriptor* bitcast ( +// CHECK-SAME: {{.*}}$s4main5ValueOMn{{.*}} to %swift.type_descriptor* +// CHECK-SAME: ) +// CHECK-SAME: ) // CHECK: ret %swift.metadata_response {{%[0-9]+}} // CHECK: } diff --git a/test/IRGen/prespecialized-metadata/enum-inmodule-1argument-1conformance-external_nonresilient-1distinct_use.swift b/test/IRGen/prespecialized-metadata/enum-inmodule-1argument-1conformance-external_nonresilient-1distinct_use.swift index 4549e0944fb28..b01eaee58d60b 100644 --- a/test/IRGen/prespecialized-metadata/enum-inmodule-1argument-1conformance-external_nonresilient-1distinct_use.swift +++ b/test/IRGen/prespecialized-metadata/enum-inmodule-1argument-1conformance-external_nonresilient-1distinct_use.swift @@ -65,7 +65,9 @@ doit() // CHECK-SAME: i8* [[ERASED_TYPE]], // CHECK-SAME: i8* [[ERASED_TABLE]], // CHECK-SAME: i8* undef, -// CHECK-SAME: %swift.type_descriptor* bitcast (<{ i32, i32, i32, i32, i32, i32, i32, i32, i32, i16, i16, i16, i16, i8, i8, i8, i8, i32, i32, i32 }>* @"$s4main5ValueOMn" to %swift.type_descriptor*) +// CHECK-SAME: %swift.type_descriptor* bitcast ( +// CHECK-SAME: {{.*}}$s4main5ValueOMn{{.*}} to %swift.type_descriptor* +// CHECK-SAME: ) // CHECK-SAME: ) // CHECK: ret %swift.metadata_response {{%[0-9]+}} // CHECK: } diff --git a/test/IRGen/prespecialized-metadata/enum-inmodule-1argument-1conformance-external_resilient-1distinct_use.swift b/test/IRGen/prespecialized-metadata/enum-inmodule-1argument-1conformance-external_resilient-1distinct_use.swift index 1a55065719c32..941e5195b3471 100644 --- a/test/IRGen/prespecialized-metadata/enum-inmodule-1argument-1conformance-external_resilient-1distinct_use.swift +++ b/test/IRGen/prespecialized-metadata/enum-inmodule-1argument-1conformance-external_resilient-1distinct_use.swift @@ -51,7 +51,9 @@ doit() // CHECK-SAME: i8* [[ERASED_TYPE]], // CHECK-SAME: i8* [[ERASED_TABLE]], // CHECK-SAME: i8* undef, -// CHECK-SAME: %swift.type_descriptor* bitcast (<{ i32, i32, i32, i32, i32, i32, i32, i32, i32, i16, i16, i16, i16, i8, i8, i8, i8, i32, i32, i32 }>* @"$s4main5ValueOMn" to %swift.type_descriptor*) +// CHECK-SAME: %swift.type_descriptor* bitcast ( +// CHECK-SAME: {{.*}}$s4main5ValueOMn{{.*}} to %swift.type_descriptor* +// CHECK-SAME: ) // CHECK-SAME: ) // CHECK: ret %swift.metadata_response {{%[0-9]+}} // CHECK: } diff --git a/test/IRGen/prespecialized-metadata/enum-inmodule-1argument-1conformance-public-1distinct_use.swift b/test/IRGen/prespecialized-metadata/enum-inmodule-1argument-1conformance-public-1distinct_use.swift index 8a0c9f27ac343..de96de5c8537c 100644 --- a/test/IRGen/prespecialized-metadata/enum-inmodule-1argument-1conformance-public-1distinct_use.swift +++ b/test/IRGen/prespecialized-metadata/enum-inmodule-1argument-1conformance-public-1distinct_use.swift @@ -17,7 +17,9 @@ // CHECK-SAME: }> <{ // CHECK-SAME: i8** getelementptr inbounds (%swift.enum_vwtable, %swift.enum_vwtable* @"$s4main5ValueOySiGWV", i32 0, i32 0), // CHECK-SAME: [[INT]] 513, -// CHECK-SAME: %swift.type_descriptor* bitcast (<{ i32, i32, i32, i32, i32, i32, i32, i32, i32, i16, i16, i16, i16, i8, i8, i8, i8, i32, i32, i32 }>* @"$s4main5ValueOMn" to %swift.type_descriptor*), +// CHECK-SAME: %swift.type_descriptor* bitcast ( +// CHECK-SAME: {{.*}}$s4main5ValueOMn{{.*}} to %swift.type_descriptor* +// CHECK-SAME: ), // CHECK-SAME: %swift.type* @"$sSiN", // CHECK-SAME: i8** getelementptr inbounds ([1 x i8*], [1 x i8*]* @"$sSi4main1PAAWP", i32 0, i32 0), // CHECK-SAME: i64 3 @@ -92,6 +94,14 @@ doit() // CHECK-SAME: [[INT]] 0 // CHECK-SAME: } // CHECK: [[EXIT_NORMAL]]: -// CHECK: {{%[0-9]+}} = call swiftcc %swift.metadata_response @__swift_instantiateGenericMetadata([[INT]] %0, i8* [[ERASED_TYPE]], i8* [[ERASED_TABLE]], i8* undef, %swift.type_descriptor* bitcast (<{ i32, i32, i32, i32, i32, i32, i32, i32, i32, i16, i16, i16, i16, i8, i8, i8, i8, i32, i32, i32 }>* @"$s4main5ValueOMn" to %swift.type_descriptor*)) +// CHECK: {{%[0-9]+}} = call swiftcc %swift.metadata_response @__swift_instantiateGenericMetadata( +// CHECK-SAME: [[INT]] %0, +// CHECK-SAME: i8* [[ERASED_TYPE]], +// CHECK-SAME: i8* [[ERASED_TABLE]], +// CHECK-SAME: i8* undef, +// CHECK-SAME: %swift.type_descriptor* bitcast ( +// CHECK-SAME: {{.*}}$s4main5ValueOMn{{.*}} to %swift.type_descriptor* +// CHECK-SAME: ) +// CHECK-SAME: ) // CHECK: ret %swift.metadata_response {{%[0-9]+}} // CHECK: } diff --git a/test/IRGen/prespecialized-metadata/enum-inmodule-1argument-1conformance-stdlib_equatable-1distinct_use.swift b/test/IRGen/prespecialized-metadata/enum-inmodule-1argument-1conformance-stdlib_equatable-1distinct_use.swift index e753fad55a3b6..8d395f11186d9 100644 --- a/test/IRGen/prespecialized-metadata/enum-inmodule-1argument-1conformance-stdlib_equatable-1distinct_use.swift +++ b/test/IRGen/prespecialized-metadata/enum-inmodule-1argument-1conformance-stdlib_equatable-1distinct_use.swift @@ -36,8 +36,7 @@ doit() // CHECK-SAME: i8* [[ERASED_CONFORMANCE]], // CHECK-SAME: i8* undef, // CHECK-SAME: %swift.type_descriptor* bitcast ( -// CHECK-SAME: <{ i32, i32, i32, i32, i32, i32, i32, i32, i32, i16, i16, i16, i16, i8, i8, i8, i8, i32, i32, i32 }>* @"$s4main5ValueOMn" -// CHECK-SAME: to %swift.type_descriptor* +// CHECK-SAME: {{.*}}$s4main5ValueOMn{{.*}} to %swift.type_descriptor* // CHECK-SAME: ) // CHECK-SAME: ) #{{[0-9]+}} // CHECK: ret %swift.metadata_response {{%[0-9]+}} diff --git a/test/IRGen/prespecialized-metadata/enum-inmodule-1argument-1distinct_generic_use.swift b/test/IRGen/prespecialized-metadata/enum-inmodule-1argument-1distinct_generic_use.swift index 4469578b00cd5..a991e4041c361 100644 --- a/test/IRGen/prespecialized-metadata/enum-inmodule-1argument-1distinct_generic_use.swift +++ b/test/IRGen/prespecialized-metadata/enum-inmodule-1argument-1distinct_generic_use.swift @@ -21,8 +21,7 @@ // CHECK-SAME: ), // CHECK-SAME: [[INT]] 513, // CHECK-SAME: %swift.type_descriptor* bitcast ( -// CHECK-SAME: <{ i32, i32, i32, i32, i32, i32, i32, i32, i32, i16, i16, i16, i16, i8, i8, i8, i8 }>* @"$s4main5OuterOMn" -// CHECK-SAME: to %swift.type_descriptor* +// CHECK-SAME: {{.*}}$s4main5OuterOMn{{.*}} to %swift.type_descriptor* // CHECK-SAME: ), // CHECK-SAME: %swift.type* getelementptr inbounds ( // CHECK-SAME: %swift.full_type, @@ -92,9 +91,7 @@ doit() // CHECK-SAME: i8* undef, // CHECK-SAME: i8* undef, // CHECK-SAME: %swift.type_descriptor* bitcast ( -// CHECK-SAME: <{ i32, i32, i32, i32, i32, i32, i32, i32, i32, i16, i16, i16, i16, i8, i8, i8, i8 }>* -// CHECK-SAME: @"$s4main5OuterOMn" -// CHECK-SAME: to %swift.type_descriptor* +// CHECK-SAME: {{.*}}$s4main5OuterOMn{{.*}} to %swift.type_descriptor* // CHECK-SAME: ) // CHECK-SAME: ) #{{[0-9]+}} // CHECK: ret %swift.metadata_response {{%[0-9]+}} diff --git a/test/IRGen/prespecialized-metadata/enum-inmodule-1argument-1distinct_use.swift b/test/IRGen/prespecialized-metadata/enum-inmodule-1argument-1distinct_use.swift index 1c301b39dc4c1..f3b9bf1e8c802 100644 --- a/test/IRGen/prespecialized-metadata/enum-inmodule-1argument-1distinct_use.swift +++ b/test/IRGen/prespecialized-metadata/enum-inmodule-1argument-1distinct_use.swift @@ -6,20 +6,21 @@ // UNSUPPORTED: CPU=armv7s && OS=ios // CHECK: @"$s4main5ValueOySiGWV" = linkonce_odr hidden constant %swift.enum_vwtable { -// CHECK-SAME: i8* bitcast ({{(%swift.opaque\* \(\[[0-9]+ x i8\]\*, \[[0-9]+ x i8\]\*, %swift.type\*\)\* @"\$[a-zA-Z0-9_]+" to i8\*|i8\* \(i8\*, i8\*, %swift.type\*\)\* @__swift_memcpy[0-9]+_[0-9]+ to i8\*)}}), -// CHECK-SAME: i8* bitcast (void (i8*, %swift.type*)* @__swift_noop_void_return to i8*), -// CHECK-SAME: i8* bitcast (i8* (i8*, i8*, %swift.type*)* @__swift_memcpy{{[0-9]+}}_{{[0-9]+}} to i8*), -// CHECK-SAME: i8* bitcast (i8* (i8*, i8*, %swift.type*)* @__swift_memcpy{{[0-9]+}}_{{[0-9]+}} to i8*), -// CHECK-SAME: i8* bitcast (i8* (i8*, i8*, %swift.type*)* @__swift_memcpy{{[0-9]+}}_{{[0-9]+}} to i8*), -// CHECK-SAME: i8* bitcast (i8* (i8*, i8*, %swift.type*)* @__swift_memcpy{{[0-9]+}}_{{[0-9]+}} to i8*), -// CHECK-SAME: i8* bitcast (i32 (%swift.opaque*, i32, %swift.type*)* @"$s4main5ValueOySiGwet" to i8*), -// CHECK-SAME: i8* bitcast (void (%swift.opaque*, i32, i32, %swift.type*)* @"$s4main5ValueOySiGwst" to i8*), +// CHECK-SAME: i8* bitcast ({{(%swift.opaque\* \(\[[0-9]+ x i8\]\*, \[[0-9]+ x i8\]\*, %swift.type\*\)\* @"\$[a-zA-Z0-9_]+" to i8\*|[^@]+@__swift_memcpy[0-9]+_[0-9]+[^\)]* to i8\*)}}), +// CHECK-SAME: i8* bitcast ({{[^@]+}}@__swift_noop_void_return{{[^\)]*}} to i8*), +// CHECK-SAME: i8* bitcast ({{[^@]+}}@__swift_memcpy{{[0-9]+}}_{{[0-9]+}}{{[^)]*}} to i8*), +// CHECK-SAME: i8* bitcast ({{[^@]+}}@__swift_memcpy{{[0-9]+}}_{{[0-9]+}}{{[^)]*}} to i8*), +// CHECK-SAME: i8* bitcast ({{[^@]+}}@__swift_memcpy{{[0-9]+}}_{{[0-9]+}}{{[^)]*}} to i8*), +// CHECK-SAME: i8* bitcast ({{[^@]+}}@__swift_memcpy{{[0-9]+}}_{{[0-9]+}}{{[^)]*}} to i8*), +// CHECK-SAME: i8* bitcast ({{[^@]+}}@"$s4main5ValueOySiGwet{{[^)]+}} to i8*), +// CHECK-SAME: i8* bitcast ({{[^@]+}}@"$s4main5ValueOySiGwst{{[^)]+}} to i8*), // CHECK-SAME: [[INT]] [[ALIGNMENT]], // CHECK-SAME: [[INT]] [[ALIGNMENT]], // CHECK-SAME: i32 {{[0-9]+}}, -// CHECK-SAME: i32 0, i8* bitcast (i32 (%swift.opaque*, %swift.type*)* @"$s4main5ValueOySiGwug" to i8*), -// CHECK-SAME: i8* bitcast (void (%swift.opaque*, %swift.type*)* @"$s4main5ValueOySiGwup" to i8*), -// CHECK-SAME: i8* bitcast (void (%swift.opaque*, i32, %swift.type*)* @"$s4main5ValueOySiGwui" to i8*) +// CHECK-SAME: i32 0, +// CHECK-SAME: i8* bitcast ({{[^@]+}}@"$s4main5ValueOySiGwug{{[^)]+}} to i8*), +// CHECK-SAME: i8* bitcast ({{[^@]+}}@"$s4main5ValueOySiGwup{{[^)]+}} to i8*), +// CHECK-SAME: i8* bitcast ({{[^@]+}}@"$s4main5ValueOySiGwui{{[^)]+}} to i8*) // CHECK-SAME: }, align [[ALIGNMENT]] // CHECK: @"$s4main5ValueOySiGMf" = linkonce_odr hidden constant <{ // CHECK-SAME: i8**, @@ -30,7 +31,9 @@ // CHECK-SAME: }> <{ // CHECK-SAME: i8** getelementptr inbounds (%swift.enum_vwtable, %swift.enum_vwtable* @"$s4main5ValueOySiGWV", i32 0, i32 0), // CHECK-SAME: [[INT]] 513, -// CHECK-SAME: %swift.type_descriptor* bitcast (<{ i32, i32, i32, i32, i32, i32, i32, i32, i32, i16, i16, i16, i16, i8, i8, i8, i8 }>* @"$s4main5ValueOMn" to %swift.type_descriptor*), +// CHECK-SAME: %swift.type_descriptor* bitcast ( +// CHECK-SAME: {{.*}}$s4main5ValueOMn{{.*}} to %swift.type_descriptor* +// CHECK-SAME: ), // CHECK-SAME: %swift.type* @"$sSiN", // CHECK-SAME: i64 3 // CHECK-SAME: }>, align [[ALIGNMENT]] @@ -72,7 +75,9 @@ doit() // CHECK-SAME: i8* %2, // CHECK-SAME: i8* undef, // CHECK-SAME: i8* undef, -// CHECK-SAME: %swift.type_descriptor* bitcast (<{ i32, i32, i32, i32, i32, i32, i32, i32, i32, i16, i16, i16, i16, i8, i8, i8, i8 }>* @"$s4main5ValueOMn" to %swift.type_descriptor*) +// CHECK-SAME: %swift.type_descriptor* bitcast ( +// CHECK-SAME: {{.*}}$s4main5ValueOMn{{.*}} to %swift.type_descriptor* +// CHECK-SAME: ) // CHECK-SAME: ) #{{[0-9]+}} // CHECK: ret %swift.metadata_response {{%[0-9]+}} // CHECK: } diff --git a/test/IRGen/prespecialized-metadata/enum-inmodule-1argument-within-class-1argument-1distinct_use.swift b/test/IRGen/prespecialized-metadata/enum-inmodule-1argument-within-class-1argument-1distinct_use.swift index df2c791959058..97411bb9e3a8d 100644 --- a/test/IRGen/prespecialized-metadata/enum-inmodule-1argument-within-class-1argument-1distinct_use.swift +++ b/test/IRGen/prespecialized-metadata/enum-inmodule-1argument-within-class-1argument-1distinct_use.swift @@ -16,9 +16,7 @@ // i8** getelementptr inbounds (%swift.enum_vwtable, %swift.enum_vwtable* @"$s4main9NamespaceC5ValueOySS_SiGWV", i32 0, i32 0), // CHECK-SAME: [[INT]] 513, // CHECK-SAME: %swift.type_descriptor* bitcast ( -// CHECK-SAME: <{ i32, i32, i32, i32, i32, i32, i32, i32, i32, i16, i16, i16, i16, i8, i8, i8, i8 }>* -// CHECK-SAME: @"$s4main9NamespaceC5ValueOMn" -// CHECK-SAME: to %swift.type_descriptor* +// CHECK-SAME: {{.*}}$s4main9NamespaceC5ValueOMn{{.*}} to %swift.type_descriptor* // CHECK-SAME: ), // CHECK-SAME: %swift.type* @"$sSSN", // CHECK-SAME: %swift.type* @"$sSiN", @@ -102,9 +100,7 @@ doit() // CHECK-SAME: i8* [[ERASED_TYPE_2]], // CHECK-SAME: i8* undef, // CHECK-SAME: %swift.type_descriptor* bitcast ( -// CHECK-SAME: <{ i32, i32, i32, i32, i32, i32, i32, i32, i32, i16, i16, i16, i16, i8, i8, i8, i8 }>* -// CHECK-SAME: @"$s4main9NamespaceC5ValueOMn" -// CHECK-SAME: to %swift.type_descriptor* +// CHECK-SAME: {{.*}}$s4main9NamespaceC5ValueOMn{{.*}} to %swift.type_descriptor* // CHECK-SAME: ) // CHECK-SAME: ) #{{[0-9]+}} // CHECK: ret %swift.metadata_response {{%[0-9]+}} diff --git a/test/IRGen/prespecialized-metadata/enum-inmodule-1argument-within-enum-1argument-1distinct_use.swift b/test/IRGen/prespecialized-metadata/enum-inmodule-1argument-within-enum-1argument-1distinct_use.swift index b645be1bd5c60..16d18ceb2d919 100644 --- a/test/IRGen/prespecialized-metadata/enum-inmodule-1argument-within-enum-1argument-1distinct_use.swift +++ b/test/IRGen/prespecialized-metadata/enum-inmodule-1argument-within-enum-1argument-1distinct_use.swift @@ -16,9 +16,7 @@ // i8** getelementptr inbounds (%swift.enum_vwtable, %swift.enum_vwtable* @"$s4main9NamespaceO5ValueOySS_SiGWV", i32 0, i32 0) // CHECK-SAME: [[INT]] 513, // CHECK-SAME: %swift.type_descriptor* bitcast ( -// CHECK-SAME: <{ i32, i32, i32, i32, i32, i32, i32, i32, i32, i16, i16, i16, i16, i8, i8, i8, i8 }>* -// CHECK-SAME: @"$s4main9NamespaceO5ValueOMn" -// CHECK-SAME: to %swift.type_descriptor* +// CHECK-SAME: {{.*}}$s4main9NamespaceO5ValueOMn{{.*}} to %swift.type_descriptor* // CHECK-SAME: ), // CHECK-SAME: %swift.type* @"$sSSN", // CHECK-SAME: %swift.type* @"$sSiN", @@ -102,9 +100,7 @@ doit() // CHECK-SAME: i8* [[ERASED_TYPE_2]], // CHECK-SAME: i8* undef, // CHECK-SAME: %swift.type_descriptor* bitcast ( -// CHECK-SAME: <{ i32, i32, i32, i32, i32, i32, i32, i32, i32, i16, i16, i16, i16, i8, i8, i8, i8 }>* -// CHECK-SAME: @"$s4main9NamespaceO5ValueOMn" -// CHECK-SAME: to %swift.type_descriptor* +// CHECK-SAME: {{.*}}$s4main9NamespaceO5ValueOMn{{.*}} to %swift.type_descriptor* // CHECK-SAME: ) // CHECK-SAME: ) #{{[0-9]+}} // CHECK: ret %swift.metadata_response {{%[0-9]+}} diff --git a/test/IRGen/prespecialized-metadata/enum-inmodule-1argument-within-struct-1argument-1distinct_use.swift b/test/IRGen/prespecialized-metadata/enum-inmodule-1argument-within-struct-1argument-1distinct_use.swift index c8ef86825afac..a94543fd86e22 100644 --- a/test/IRGen/prespecialized-metadata/enum-inmodule-1argument-within-struct-1argument-1distinct_use.swift +++ b/test/IRGen/prespecialized-metadata/enum-inmodule-1argument-within-struct-1argument-1distinct_use.swift @@ -16,9 +16,7 @@ // i8** getelementptr inbounds (%swift.enum_vwtable, %swift.enum_vwtable* @"$s4main9NamespaceV5ValueOySS_SiGWV", i32 0, i32 0), // CHECK-SAME: [[INT]] 513, // CHECK-SAME: %swift.type_descriptor* bitcast ( -// CHECK-SAME: <{ i32, i32, i32, i32, i32, i32, i32, i32, i32, i16, i16, i16, i16, i8, i8, i8, i8 }>* -// CHECK-SAME: @"$s4main9NamespaceV5ValueOMn" -// CHECK-SAME: to %swift.type_descriptor* +// CHECK-SAME: {{.*}}$s4main9NamespaceV5ValueOMn{{.*}} to %swift.type_descriptor* // CHECK-SAME: ), // CHECK-SAME: %swift.type* @"$sSSN", // CHECK-SAME: %swift.type* @"$sSiN", @@ -101,9 +99,7 @@ doit() // CHECK-SAME: i8* [[ERASED_TYPE_2]], // CHECK-SAME: i8* undef, // CHECK-SAME: %swift.type_descriptor* bitcast ( -// CHECK-SAME: <{ i32, i32, i32, i32, i32, i32, i32, i32, i32, i16, i16, i16, i16, i8, i8, i8, i8 }>* -// CHECK-SAME: @"$s4main9NamespaceV5ValueOMn" -// CHECK-SAME: to %swift.type_descriptor* +// CHECK-SAME: {{.*}}$s4main9NamespaceV5ValueOMn{{.*}} to %swift.type_descriptor* // CHECK-SAME: ) // CHECK-SAME: ) #{{[0-9]+}} // CHECK: ret %swift.metadata_response {{%[0-9]+}} diff --git a/test/IRGen/prespecialized-metadata/enum-inmodule-2argument-1distinct_use.swift b/test/IRGen/prespecialized-metadata/enum-inmodule-2argument-1distinct_use.swift index 45df509cdf9a9..3e84bbf699608 100644 --- a/test/IRGen/prespecialized-metadata/enum-inmodule-2argument-1distinct_use.swift +++ b/test/IRGen/prespecialized-metadata/enum-inmodule-2argument-1distinct_use.swift @@ -6,21 +6,21 @@ // UNSUPPORTED: CPU=armv7s && OS=ios // CHECK: @"$s4main5ValueOyS2iGWV" = linkonce_odr hidden constant %swift.enum_vwtable { -// CHECK-SAME: i8* bitcast ({{(%swift.opaque\* \(\[[0-9]+ x i8\]\*, \[[0-9]+ x i8\]\*, %swift.type\*\)\* @"\$[a-zA-Z0-9_]+" to i8\*|i8\* \(i8\*, i8\*, %swift.type\*\)\* @__swift_memcpy[0-9]+_[0-9]+ to i8\*)}}), -// CHECK-SAME: i8* bitcast (void (i8*, %swift.type*)* @__swift_noop_void_return to i8*), -// CHECK-SAME: i8* bitcast (i8* (i8*, i8*, %swift.type*)* @__swift_memcpy{{[0-9]+}}_{{[0-9]+}} to i8*), -// CHECK-SAME: i8* bitcast (i8* (i8*, i8*, %swift.type*)* @__swift_memcpy{{[0-9]+}}_{{[0-9]+}} to i8*), -// CHECK-SAME: i8* bitcast (i8* (i8*, i8*, %swift.type*)* @__swift_memcpy{{[0-9]+}}_{{[0-9]+}} to i8*), -// CHECK-SAME: i8* bitcast (i8* (i8*, i8*, %swift.type*)* @__swift_memcpy{{[0-9]+}}_{{[0-9]+}} to i8*), -// CHECK-SAME: i8* bitcast (i32 (%swift.opaque*, i32, %swift.type*)* @"$s4main5ValueOyS2iGwet" to i8*), -// CHECK-SAME: i8* bitcast (void (%swift.opaque*, i32, i32, %swift.type*)* @"$s4main5ValueOyS2iGwst" to i8*), +// CHECK-SAME: i8* bitcast ({{(%swift.opaque\* \(\[[0-9]+ x i8\]\*, \[[0-9]+ x i8\]\*, %swift.type\*\)\* @"\$[a-zA-Z0-9_]+" to i8\*|[^@]+@__swift_memcpy[0-9]+_[0-9]+[^\)]* to i8\*)}}), +// CHECK-SAME: i8* bitcast ({{[^@]+}}@__swift_noop_void_return{{[^)]*}} to i8*), +// CHECK-SAME: i8* bitcast ({{[^@]+}}@__swift_memcpy{{[0-9]+}}_{{[0-9]+}}{{[^)]*}} to i8*), +// CHECK-SAME: i8* bitcast ({{[^@]+}}@__swift_memcpy{{[0-9]+}}_{{[0-9]+}}{{[^)]*}} to i8*), +// CHECK-SAME: i8* bitcast ({{[^@]+}}@__swift_memcpy{{[0-9]+}}_{{[0-9]+}}{{[^)]*}} to i8*), +// CHECK-SAME: i8* bitcast ({{[^@]+}}@__swift_memcpy{{[0-9]+}}_{{[0-9]+}}{{[^)]*}} to i8*), +// CHECK-SAME: i8* bitcast ({{[^@]+}}@"$s4main5ValueOyS2iGwet{{[^)]+}} to i8*), +// CHECK-SAME: i8* bitcast ({{[^@]+}}@"$s4main5ValueOyS2iGwst{{[^)]+}} to i8*), // CHECK-SAME: [[INT]] {{[0-9]+}}, // CHECK-SAME: [[INT]] {{[0-9]+}}, // CHECK-SAME: i32 {{[0-9]+}}, // CHECK-SAME: i32 {{[0-9]+}}, -// CHECK-SAME: i8* bitcast (i32 (%swift.opaque*, %swift.type*)* @"$s4main5ValueOyS2iGwug" to i8*), -// CHECK-SAME: i8* bitcast (void (%swift.opaque*, %swift.type*)* @"$s4main5ValueOyS2iGwup" to i8*), -// CHECK-SAME i8* bitcast (void (%swift.opaque*, i32, %swift.type*)* @"$s4main5ValueOyS2iGwui" to i8*) +// CHECK-SAME: i8* bitcast ({{[^@]+}}@"$s4main5ValueOyS2iGwug{{[^)]+}} to i8*), +// CHECK-SAME: i8* bitcast ({{[^@]+}}@"$s4main5ValueOyS2iGwup{{[^)]+}} to i8*), +// CHECK-SAME i8* bitcast ({{[^@]+}}@"$s4main5ValueOyS2iGwui{{[^)]+}} to i8*) // CHECK-SAME: }, align [[ALIGNMENT]] // CHECK: @"$s4main5ValueOyS2iGMf" = linkonce_odr hidden constant <{ // CHECK-SAME: i8**, @@ -31,7 +31,9 @@ // CHECK-SAME: }> <{ // CHECK-SAME: i8** getelementptr inbounds (%swift.enum_vwtable, %swift.enum_vwtable* @"$s4main5ValueOyS2iGWV", i32 0, i32 0), // CHECK-SAME: [[INT]] 513, -// CHECK-SAME: %swift.type_descriptor* bitcast (<{ i32, i32, i32, i32, i32, i32, i32, i32, i32, i16, i16, i16, i16, i8, i8, i8, i8 }>* @"$s4main5ValueOMn" to %swift.type_descriptor*), +// CHECK-SAME: %swift.type_descriptor* bitcast ( +// CHECK-SAME: {{.*}}$s4main5ValueOMn{{.*}} to %swift.type_descriptor* +// CHECK-SAME: ), // CHECK-SAME: %swift.type* @"$sSiN", // CHECK-SAME: %swift.type* @"$sSiN", // CHECK-SAME: [[INT]] {{16|8}}, @@ -108,11 +110,13 @@ doit() // CHECK-SAME: } // CHECK: [[EXIT_NORMAL]]: // CHECK: {{%[0-9]+}} = call swiftcc %swift.metadata_response @__swift_instantiateGenericMetadata( -// CHECK-SAME: [[INT]] %0, -// CHECK-SAME: i8* [[ERASED_TYPE_1]], -// CHECK-SAME: i8* [[ERASED_TYPE_2]], -// CHECK-SAME: i8* undef, -// CHECK-SAME: %swift.type_descriptor* bitcast (<{ i32, i32, i32, i32, i32, i32, i32, i32, i32, i16, i16, i16, i16, i8, i8, i8, i8 }>* @"$s4main5ValueOMn" to %swift.type_descriptor*) -// CHECK-SAME: ) #{{[0-9]+}} +// CHECK-SAME: [[INT]] %0, +// CHECK-SAME: i8* [[ERASED_TYPE_1]], +// CHECK-SAME: i8* [[ERASED_TYPE_2]], +// CHECK-SAME: i8* undef, +// CHECK-SAME: %swift.type_descriptor* bitcast ( +// CHECK-SAME: {{.*}}$s4main5ValueOMn{{.*}} to %swift.type_descriptor* +// CHECK-SAME: ) +// CHECK-SAME: ) #{{[0-9]+}} // CHECK: ret %swift.metadata_response {{%[0-9]+}} // CHECK: } diff --git a/test/IRGen/prespecialized-metadata/enum-inmodule-3argument-1distinct_use.swift b/test/IRGen/prespecialized-metadata/enum-inmodule-3argument-1distinct_use.swift index 8a7129e0db46d..f934d9f75d0a1 100644 --- a/test/IRGen/prespecialized-metadata/enum-inmodule-3argument-1distinct_use.swift +++ b/test/IRGen/prespecialized-metadata/enum-inmodule-3argument-1distinct_use.swift @@ -6,21 +6,21 @@ // UNSUPPORTED: CPU=armv7s && OS=ios // CHECK: @"$s4main5ValueOyS3iGWV" = linkonce_odr hidden constant %swift.enum_vwtable { -// CHECK-SAME: i8* bitcast ({{(%swift.opaque\* \(\[[0-9]+ x i8\]\*, \[[0-9]+ x i8\]\*, %swift.type\*\)\* @"\$[a-zA-Z0-9_]+" to i8\*|i8\* \(i8\*, i8\*, %swift.type\*\)\* @__swift_memcpy[0-9]+_[0-9]+ to i8\*)}}), -// CHECK-SAME: i8* bitcast (void (i8*, %swift.type*)* @__swift_noop_void_return to i8*), -// CHECK-SAME: i8* bitcast (i8* (i8*, i8*, %swift.type*)* @__swift_memcpy{{[0-9]+}}_{{[0-9]+}} to i8*), -// CHECK-SAME: i8* bitcast (i8* (i8*, i8*, %swift.type*)* @__swift_memcpy{{[0-9]+}}_{{[0-9]+}} to i8*), -// CHECK-SAME: i8* bitcast (i8* (i8*, i8*, %swift.type*)* @__swift_memcpy{{[0-9]+}}_{{[0-9]+}} to i8*), -// CHECK-SAME: i8* bitcast (i8* (i8*, i8*, %swift.type*)* @__swift_memcpy{{[0-9]+}}_{{[0-9]+}} to i8*), -// CHECK-SAME: i8* bitcast (i32 (%swift.opaque*, i32, %swift.type*)* @"$s4main5ValueOyS3iGwet" to i8*), -// CHECK-SAME: i8* bitcast (void (%swift.opaque*, i32, i32, %swift.type*)* @"$s4main5ValueOyS3iGwst" to i8*), +// CHECK-SAME: i8* bitcast ({{([^@]+@"\$s4main5ValueOyS3iGwCP[^\)]+ to i8\*|[^@]+@__swift_memcpy[0-9]+_[0-9]+[^\)]+ to i8\*)}}), +// CHECK-SAME: i8* bitcast ({{[^@]+}}@__swift_noop_void_return{{[^)]*}} to i8*), +// CHECK-SAME: i8* bitcast ({{[^@]+}}@__swift_memcpy{{[0-9]+}}_{{[0-9]+}}{{[^)]*}} to i8*), +// CHECK-SAME: i8* bitcast ({{[^@]+}}@__swift_memcpy{{[0-9]+}}_{{[0-9]+}}{{[^)]*}} to i8*), +// CHECK-SAME: i8* bitcast ({{[^@]+}}@__swift_memcpy{{[0-9]+}}_{{[0-9]+}}{{[^)]*}} to i8*), +// CHECK-SAME: i8* bitcast ({{[^@]+}}@__swift_memcpy{{[0-9]+}}_{{[0-9]+}}{{[^)]*}} to i8*), +// CHECK-SAME: i8* bitcast ({{[^@]+}}@"$s4main5ValueOyS3iGwet{{[^)]+}} to i8*), +// CHECK-SAME: i8* bitcast ({{[^@]+}}@"$s4main5ValueOyS3iGwst{{[^)]+}} to i8*), // CHECK-SAME: [[INT]] {{[0-9]+}}, // CHECK-SAME: [[INT]] {{[0-9]+}}, // CHECK-SAME: i32 {{[0-9]+}}, // CHECK-SAME: i32 {{[0-9]+}}, -// CHECK-SAME: i8* bitcast (i32 (%swift.opaque*, %swift.type*)* @"$s4main5ValueOyS3iGwug" to i8*), -// CHECK-SAME: i8* bitcast (void (%swift.opaque*, %swift.type*)* @"$s4main5ValueOyS3iGwup" to i8*), -// CHECK-SAME i8* bitcast (void (%swift.opaque*, i32, %swift.type*)* @"$s4main5ValueOyS3iGwui" to i8*) +// CHECK-SAME: i8* bitcast ({{[^@]+}}@"$s4main5ValueOyS3iGwug{{[^)]+}} to i8*), +// CHECK-SAME: i8* bitcast ({{[^@]+}}@"$s4main5ValueOyS3iGwup{{[^)]+}} to i8*), +// CHECK-SAME i8* bitcast ({{[^@]+}}@"$s4main5ValueOyS3iGwui{{[^)]+}} to i8*) // CHECK-SAME: }, align [[ALIGNMENT]] // CHECK: @"$s4main5ValueOyS3iGMf" = linkonce_odr hidden constant <{ // CHECK-SAME: i8**, @@ -31,7 +31,9 @@ // CHECK-SAME: }> <{ // CHECK-SAME: i8** getelementptr inbounds (%swift.enum_vwtable, %swift.enum_vwtable* @"$s4main5ValueOyS3iGWV", i32 0, i32 0), // CHECK-SAME: [[INT]] 513, -// CHECK-SAME: %swift.type_descriptor* bitcast (<{ i32, i32, i32, i32, i32, i32, i32, i32, i32, i16, i16, i16, i16, i8, i8, i8, i8 }>* @"$s4main5ValueOMn" to %swift.type_descriptor*), +// CHECK-SAME: %swift.type_descriptor* bitcast ( +// CHECK-SAME: {{.*}}$s4main5ValueOMn{{.*}} to %swift.type_descriptor* +// CHECK-SAME: ), // CHECK-SAME: %swift.type* @"$sSiN", // CHECK-SAME: %swift.type* @"$sSiN", // CHECK-SAME: %swift.type* @"$sSiN", @@ -117,11 +119,13 @@ doit() // CHECK-SAME: } // CHECK: [[EXIT_NORMAL]]: // CHECK: {{%[0-9]+}} = call swiftcc %swift.metadata_response @__swift_instantiateGenericMetadata( -// CHECK-SAME: [[INT]] %0, -// CHECK-SAME: i8* [[ERASED_TYPE_1]], -// CHECK-SAME: i8* [[ERASED_TYPE_2]], -// CHECK-SAME: i8* [[ERASED_TYPE_3]], -// CHECK-SAME: %swift.type_descriptor* bitcast (<{ i32, i32, i32, i32, i32, i32, i32, i32, i32, i16, i16, i16, i16, i8, i8, i8, i8 }>* @"$s4main5ValueOMn" to %swift.type_descriptor*) -// CHECK-SAME: ) #{{[0-9]+}} +// CHECK-SAME: [[INT]] %0, +// CHECK-SAME: i8* [[ERASED_TYPE_1]], +// CHECK-SAME: i8* [[ERASED_TYPE_2]], +// CHECK-SAME: i8* [[ERASED_TYPE_3]], +// CHECK-SAME: %swift.type_descriptor* bitcast ( +// CHECK-SAME: {{.*}}$s4main5ValueOMn{{.*}} to %swift.type_descriptor* +// CHECK-SAME: ) +// CHECK-SAME: ) #{{[0-9]+}} // CHECK: ret %swift.metadata_response {{%[0-9]+}} // CHECK: } diff --git a/test/IRGen/prespecialized-metadata/enum-inmodule-4argument-1distinct_use.swift b/test/IRGen/prespecialized-metadata/enum-inmodule-4argument-1distinct_use.swift index fe4c6bd8c9b71..8f1bdc4aa4aaf 100644 --- a/test/IRGen/prespecialized-metadata/enum-inmodule-4argument-1distinct_use.swift +++ b/test/IRGen/prespecialized-metadata/enum-inmodule-4argument-1distinct_use.swift @@ -6,21 +6,21 @@ // UNSUPPORTED: CPU=armv7s && OS=ios // CHECK: @"$s4main5ValueOyS4iGWV" = linkonce_odr hidden constant %swift.enum_vwtable { -// CHECK-SAME: i8* bitcast ({{(%swift.opaque\* \(\[[0-9]+ x i8\]\*, \[[0-9]+ x i8\]\*, %swift.type\*\)\* @"\$[a-zA-Z0-9_]+" to i8\*|i8\* \(i8\*, i8\*, %swift.type\*\)\* @__swift_memcpy[0-9]+_[0-9]+ to i8\*)}}), -// CHECK-SAME: i8* bitcast (void (i8*, %swift.type*)* @__swift_noop_void_return to i8*), -// CHECK-SAME: i8* bitcast (i8* (i8*, i8*, %swift.type*)* @__swift_memcpy{{[0-9]+}}_{{[0-9]+}} to i8*), -// CHECK-SAME: i8* bitcast (i8* (i8*, i8*, %swift.type*)* @__swift_memcpy{{[0-9]+}}_{{[0-9]+}} to i8*), -// CHECK-SAME: i8* bitcast (i8* (i8*, i8*, %swift.type*)* @__swift_memcpy{{[0-9]+}}_{{[0-9]+}} to i8*), -// CHECK-SAME: i8* bitcast (i8* (i8*, i8*, %swift.type*)* @__swift_memcpy{{[0-9]+}}_{{[0-9]+}} to i8*), -// CHECK-SAME: i8* bitcast (i32 (%swift.opaque*, i32, %swift.type*)* @"$s4main5ValueOyS4iGwet" to i8*), -// CHECK-SAME: i8* bitcast (void (%swift.opaque*, i32, i32, %swift.type*)* @"$s4main5ValueOyS4iGwst" to i8*), +// CHECK-SAME: i8* bitcast ({{([^@]+@"\$s4main5ValueOyS4iGwCP+[^\)]+ to i8\*|[^@]+@__swift_memcpy[0-9]+_[0-9]+[^\)]+ to i8\*)}}), +// CHECK-SAME: i8* bitcast ({{[^@]+}}@__swift_noop_void_return{{[^)]*}} to i8*), +// CHECK-SAME: i8* bitcast ({{[^@]+}}@__swift_memcpy{{[0-9]+}}_{{[0-9]+}}{{[^)]*}} to i8*), +// CHECK-SAME: i8* bitcast ({{[^@]+}}@__swift_memcpy{{[0-9]+}}_{{[0-9]+}}{{[^)]*}} to i8*), +// CHECK-SAME: i8* bitcast ({{[^@]+}}@__swift_memcpy{{[0-9]+}}_{{[0-9]+}}{{[^)]*}} to i8*), +// CHECK-SAME: i8* bitcast ({{[^@]+}}@__swift_memcpy{{[0-9]+}}_{{[0-9]+}}{{[^)]*}} to i8*), +// CHECK-SAME: i8* bitcast ({{[^@]+}}@"$s4main5ValueOyS4iGwet{{[^)]+}} to i8*), +// CHECK-SAME: i8* bitcast ({{[^@]+}}@"$s4main5ValueOyS4iGwst{{[^)]+}} to i8*), // CHECK-SAME: [[INT]] {{[0-9]+}}, // CHECK-SAME: [[INT]] {{[0-9]+}}, // CHECK-SAME: i32 {{[0-9]+}}, // CHECK-SAME: i32 {{[0-9]+}}, -// CHECK-SAME: i8* bitcast (i32 (%swift.opaque*, %swift.type*)* @"$s4main5ValueOyS4iGwug" to i8*), -// CHECK-SAME: i8* bitcast (void (%swift.opaque*, %swift.type*)* @"$s4main5ValueOyS4iGwup" to i8*), -// CHECK-SAME i8* bitcast (void (%swift.opaque*, i32, %swift.type*)* @"$s4main5ValueOyS4iGwui" to i8*) +// CHECK-SAME: i8* bitcast ({{[^@]+}}@"$s4main5ValueOyS4iGwug{{[^)]+}} to i8*), +// CHECK-SAME: i8* bitcast ({{[^@]+}}@"$s4main5ValueOyS4iGwup{{[^)]+}} to i8*), +// CHECK-SAME i8* bitcast ({{[^@]+}}@"$s4main5ValueOyS4iGwui{{[^)]+}} to i8*) // CHECK-SAME: }, align [[ALIGNMENT]] // CHECK: @"$s4main5ValueOyS4iGMf" = linkonce_odr hidden constant <{ // CHECK-SAME: i8**, @@ -31,7 +31,9 @@ // CHECK-SAME: }> <{ // CHECK-SAME: i8** getelementptr inbounds (%swift.enum_vwtable, %swift.enum_vwtable* @"$s4main5ValueOyS4iGWV", i32 0, i32 0), // CHECK-SAME: [[INT]] 513, -// CHECK-SAME: %swift.type_descriptor* bitcast (<{ i32, i32, i32, i32, i32, i32, i32, i32, i32, i16, i16, i16, i16, i8, i8, i8, i8 }>* @"$s4main5ValueOMn" to %swift.type_descriptor*), +// CHECK-SAME: %swift.type_descriptor* bitcast ( +// CHECK-SAME: {{.*}}$s4main5ValueOMn{{.*}} to %swift.type_descriptor* +// CHECK-SAME: ), // CHECK-SAME: %swift.type* @"$sSiN", // CHECK-SAME: %swift.type* @"$sSiN", // CHECK-SAME: %swift.type* @"$sSiN", @@ -129,9 +131,11 @@ doit() // CHECK-SAME: } // CHECK: [[EXIT_NORMAL]]: // CHECK: {{%[0-9]+}} = call swiftcc %swift.metadata_response @swift_getGenericMetadata( -// CHECK-SAME: [[INT]] %0, -// CHECK-SAME: i8* [[ERASED_BUFFER]], -// CHECK-SAME: %swift.type_descriptor* bitcast (<{ i32, i32, i32, i32, i32, i32, i32, i32, i32, i16, i16, i16, i16, i8, i8, i8, i8 }>* @"$s4main5ValueOMn" to %swift.type_descriptor*) -// CHECK-SAME: ) #{{[0-9]+}} +// CHECK-SAME: [[INT]] %0, +// CHECK-SAME: i8* [[ERASED_BUFFER]], +// CHECK-SAME: %swift.type_descriptor* bitcast ( +// CHECK-SAME: {{.*}}$s4main5ValueOMn{{.*}} to %swift.type_descriptor* +// CHECK-SAME: ) +// CHECK-SAME: ) #{{[0-9]+}} // CHECK: ret %swift.metadata_response {{%[0-9]+}} // CHECK: } diff --git a/test/IRGen/prespecialized-metadata/enum-inmodule-5argument-1distinct_use.swift b/test/IRGen/prespecialized-metadata/enum-inmodule-5argument-1distinct_use.swift index a7c85109fc715..72fce0915a4fd 100644 --- a/test/IRGen/prespecialized-metadata/enum-inmodule-5argument-1distinct_use.swift +++ b/test/IRGen/prespecialized-metadata/enum-inmodule-5argument-1distinct_use.swift @@ -6,21 +6,21 @@ // UNSUPPORTED: CPU=armv7s && OS=ios // CHECK: @"$s4main5ValueOyS5iGWV" = linkonce_odr hidden constant %swift.enum_vwtable { -// CHECK-SAME: i8* bitcast ({{(%swift.opaque\* \(\[[0-9]+ x i8\]\*, \[[0-9]+ x i8\]\*, %swift.type\*\)\* @"\$[a-zA-Z0-9_]+" to i8\*|i8\* \(i8\*, i8\*, %swift.type\*\)\* @__swift_memcpy[0-9]+_[0-9]+ to i8\*)}}), -// CHECK-SAME: i8* bitcast (void (i8*, %swift.type*)* @__swift_noop_void_return to i8*), -// CHECK-SAME: i8* bitcast (i8* (i8*, i8*, %swift.type*)* @__swift_memcpy{{[0-9]+}}_{{[0-9]+}} to i8*), -// CHECK-SAME: i8* bitcast (i8* (i8*, i8*, %swift.type*)* @__swift_memcpy{{[0-9]+}}_{{[0-9]+}} to i8*), -// CHECK-SAME: i8* bitcast (i8* (i8*, i8*, %swift.type*)* @__swift_memcpy{{[0-9]+}}_{{[0-9]+}} to i8*), -// CHECK-SAME: i8* bitcast (i8* (i8*, i8*, %swift.type*)* @__swift_memcpy{{[0-9]+}}_{{[0-9]+}} to i8*), -// CHECK-SAME: i8* bitcast (i32 (%swift.opaque*, i32, %swift.type*)* @"$s4main5ValueOyS5iGwet" to i8*), -// CHECK-SAME: i8* bitcast (void (%swift.opaque*, i32, i32, %swift.type*)* @"$s4main5ValueOyS5iGwst" to i8*), +// CHECK-SAME: i8* bitcast ({{([^@]+@"\$s4main5ValueOyS5iGwCP+[^\)]+ to i8\*|[^@]+@__swift_memcpy[0-9]+_[0-9]+[^)]+ to i8\*)}}), +// CHECK-SAME: i8* bitcast ({{[^@]+}}@__swift_noop_void_return{{[^)]*}} to i8*), +// CHECK-SAME: i8* bitcast ({{[^@]+}}@__swift_memcpy{{[0-9]+}}_{{[0-9]+}}{{[^)]*}} to i8*), +// CHECK-SAME: i8* bitcast ({{[^@]+}}@__swift_memcpy{{[0-9]+}}_{{[0-9]+}}{{[^)]*}} to i8*), +// CHECK-SAME: i8* bitcast ({{[^@]+}}@__swift_memcpy{{[0-9]+}}_{{[0-9]+}}{{[^)]*}} to i8*), +// CHECK-SAME: i8* bitcast ({{[^@]+}}@__swift_memcpy{{[0-9]+}}_{{[0-9]+}}{{[^)]*}} to i8*), +// CHECK-SAME: i8* bitcast ({{[^@]+}}@"$s4main5ValueOyS5iGwet{{[^)]+}} to i8*), +// CHECK-SAME: i8* bitcast ({{[^@]+}}@"$s4main5ValueOyS5iGwst{{[^)]+}} to i8*), // CHECK-SAME: [[INT]] {{[0-9]+}}, // CHECK-SAME: [[INT]] {{[0-9]+}}, // CHECK-SAME: i32 {{[0-9]+}}, // CHECK-SAME: i32 {{[0-9]+}}, -// CHECK-SAME: i8* bitcast (i32 (%swift.opaque*, %swift.type*)* @"$s4main5ValueOyS5iGwug" to i8*), -// CHECK-SAME: i8* bitcast (void (%swift.opaque*, %swift.type*)* @"$s4main5ValueOyS5iGwup" to i8*), -// CHECK-SAME i8* bitcast (void (%swift.opaque*, i32, %swift.type*)* @"$s4main5ValueOyS5iGwui" to i8*) +// CHECK-SAME: i8* bitcast ({{[^@]+}}@"$s4main5ValueOyS5iGwug{{[^)]+}} to i8*), +// CHECK-SAME: i8* bitcast ({{[^@]+}}@"$s4main5ValueOyS5iGwup{{[^)]+}} to i8*), +// CHECK-SAME i8* bitcast ({{[^@]+}}@"$s4main5ValueOyS5iGwui{{[^)]+}} to i8*) // CHECK-SAME: }, align [[ALIGNMENT]] // CHECK: @"$s4main5ValueOyS5iGMf" = linkonce_odr hidden constant <{ // CHECK-SAME: i8**, @@ -31,7 +31,9 @@ // CHECK-SAME: }> <{ // CHECK-SAME: i8** getelementptr inbounds (%swift.enum_vwtable, %swift.enum_vwtable* @"$s4main5ValueOyS5iGWV", i32 0, i32 0), // CHECK-SAME: [[INT]] 513, -// CHECK-SAME: %swift.type_descriptor* bitcast (<{ i32, i32, i32, i32, i32, i32, i32, i32, i32, i16, i16, i16, i16, i8, i8, i8, i8, i8, i8, i8, i8 }>* @"$s4main5ValueOMn" to %swift.type_descriptor*), +// CHECK-SAME: %swift.type_descriptor* bitcast ( +// CHECK-SAME: {{.*}}$s4main5ValueOMn{{.*}} to %swift.type_descriptor* +// CHECK-SAME: ), // CHECK-SAME: %swift.type* @"$sSiN", // CHECK-SAME: [[INT]] {{40|20}}, // CHECK-SAME: i64 3 @@ -133,9 +135,11 @@ doit() // CHECK-SAME: } // CHECK: [[EXIT_NORMAL]]: // CHECK: {{%[0-9]+}} = call swiftcc %swift.metadata_response @swift_getGenericMetadata( -// CHECK-SAME: [[INT]] %0, -// CHECK-SAME: i8* [[ERASED_BUFFER]], -// CHECK-SAME: %swift.type_descriptor* bitcast (<{ i32, i32, i32, i32, i32, i32, i32, i32, i32, i16, i16, i16, i16, i8, i8, i8, i8, i8, i8, i8, i8 }>* @"$s4main5ValueOMn" to %swift.type_descriptor*) -// CHECK-SAME: ) #{{[0-9]+}} +// CHECK-SAME: [[INT]] %0, +// CHECK-SAME: i8* [[ERASED_BUFFER]], +// CHECK-SAME: %swift.type_descriptor* bitcast ( +// CHECK-SAME: {{.*}}$s4main5ValueOMn{{.*}} to %swift.type_descriptor* +// CHECK-SAME: ) +// CHECK-SAME: ) #{{[0-9]+}} // CHECK: ret %swift.metadata_response {{%[0-9]+}} // CHECK: } diff --git a/test/IRGen/prespecialized-metadata/enum-inmodule-evolution-1argument-1distinct_use-external_resilient-frozen.swift b/test/IRGen/prespecialized-metadata/enum-inmodule-evolution-1argument-1distinct_use-external_resilient-frozen.swift index 12c1cf5390ad2..acaf0cff5542f 100644 --- a/test/IRGen/prespecialized-metadata/enum-inmodule-evolution-1argument-1distinct_use-external_resilient-frozen.swift +++ b/test/IRGen/prespecialized-metadata/enum-inmodule-evolution-1argument-1distinct_use-external_resilient-frozen.swift @@ -20,7 +20,9 @@ import TestModule // CHECK-SAME: <{ // CHECK-SAME: i8** getelementptr inbounds (%swift.enum_vwtable, %swift.enum_vwtable* @"$s4main5ValueOy10TestModule7IntegerVGWV", i32 0, i32 0), // CHECK-SAME: [[INT]] 513, -// CHECK-SAME: %swift.type_descriptor* bitcast (<{ i32, i32, i32, i32, i32, i32, i32, i32, i32, i16, i16, i16, i16, i8, i8, i8, i8 }>* @"$s4main5ValueOMn" to %swift.type_descriptor*), +// CHECK-SAME: %swift.type_descriptor* bitcast ( +// CHECK-SAME: {{.*}}$s4main5ValueOMn{{.*}} to %swift.type_descriptor* +// CHECK-SAME: ), // CHECK-SAME: %swift.type* @"$s10TestModule7IntegerVN", // CHECK-SAME: i64 3 // CHECK-SAME: }>, align [[ALIGNMENT]] @@ -94,7 +96,9 @@ doit() // CHECK-SAME: i8* %2, // CHECK-SAME: i8* undef, // CHECK-SAME: i8* undef, -// CHECK-SAME: %swift.type_descriptor* bitcast (<{ i32, i32, i32, i32, i32, i32, i32, i32, i32, i16, i16, i16, i16, i8, i8, i8, i8 }>* @"$s4main5ValueOMn" to %swift.type_descriptor*) +// CHECK-SAME: %swift.type_descriptor* bitcast ( +// CHECK-SAME: {{.*}}$s4main5ValueOMn{{.*}} to %swift.type_descriptor* +// CHECK-SAME: ) // CHECK-SAME: ) #{{[0-9]+}} // CHECK: ret %swift.metadata_response {{%[0-9]+}} // CHECK: } diff --git a/test/IRGen/prespecialized-metadata/enum-inmodule-evolution-1argument-1distinct_use-external_resilient-nonfrozen.swift b/test/IRGen/prespecialized-metadata/enum-inmodule-evolution-1argument-1distinct_use-external_resilient-nonfrozen.swift index 984cdc68d569a..e3413fa9736d4 100644 --- a/test/IRGen/prespecialized-metadata/enum-inmodule-evolution-1argument-1distinct_use-external_resilient-nonfrozen.swift +++ b/test/IRGen/prespecialized-metadata/enum-inmodule-evolution-1argument-1distinct_use-external_resilient-nonfrozen.swift @@ -42,7 +42,9 @@ doit() // CHECK-SAME: i8* [[ERASED_TYPE]], // CHECK-SAME: i8* undef, // CHECK-SAME: i8* undef, -// CHECK-SAME: %swift.type_descriptor* bitcast (<{ i32, i32, i32, i32, i32, i32, i32, i32, i32, i16, i16, i16, i16, i8, i8, i8, i8 }>* @"$s4main5ValueOMn" to %swift.type_descriptor*) +// CHECK-SAME: %swift.type_descriptor* bitcast ( +// CHECK-SAME: {{.*}}$s4main5ValueOMn{{.*}} to %swift.type_descriptor* +// CHECK-SAME: ) // CHECK-SAME: ) #{{[0-9]+}} // CHECK: ret %swift.metadata_response {{%[0-9]+}} // CHECK: } diff --git a/test/IRGen/prespecialized-metadata/struct-fileprivate-inmodule-1argument-1distinct_use.swift b/test/IRGen/prespecialized-metadata/struct-fileprivate-inmodule-1argument-1distinct_use.swift index da010db18e5dd..ba6d6e172b0d8 100644 --- a/test/IRGen/prespecialized-metadata/struct-fileprivate-inmodule-1argument-1distinct_use.swift +++ b/test/IRGen/prespecialized-metadata/struct-fileprivate-inmodule-1argument-1distinct_use.swift @@ -16,7 +16,7 @@ // i8** @"$sB[[INT]]_WV", // i8** getelementptr inbounds (%swift.vwtable, %swift.vwtable* @"$s4main5Value33_BD97D79156BC586FAA2AE8FB32F3D812LLVySiGWV", i32 0, i32 0), // CHECK-SAME: [[INT]] 512, -// CHECK-SAME: %swift.type_descriptor* bitcast (<{ i32, i32, i32, i32, i32, i32, i32, i32, i32, i16, i16, i16, i16, i8, i8, i8, i8 }>* @"$s4main5Value[[UNIQUE_ID_1:[0-9A-Z_]+]]VMn" to %swift.type_descriptor*), +// CHECK-SAME: %swift.type_descriptor* bitcast ({{.+}}$s4main5Value[[UNIQUE_ID_1:[0-9A-Z_]+]]VMn{{.+}} to %swift.type_descriptor*), // CHECK-SAME: %swift.type* @"$sSiN", // CHECK-SAME: i32 0{{(, \[4 x i8\] zeroinitializer)?}}, // CHECK-SAME: i64 3 @@ -52,6 +52,6 @@ doit() // CHECK: [[EXIT_PRESPECIALIZED]]: // CHECK: ret %swift.metadata_response { %swift.type* getelementptr inbounds (%swift.full_type, %swift.full_type* bitcast (<{ i8**, [[INT]], %swift.type_descriptor*, %swift.type*, i32{{(, \[4 x i8\])?}}, i64 }>* @"$s4main5Value[[UNIQUE_ID_1]]VySiGMf" to %swift.full_type*), i32 0, i32 1), [[INT]] 0 } // CHECK: [[EXIT_NORMAL]]: -// CHECK: {{%[0-9]+}} = call swiftcc %swift.metadata_response @__swift_instantiateGenericMetadata([[INT]] %0, i8* [[ERASED_TYPE]], i8* undef, i8* undef, %swift.type_descriptor* bitcast (<{ i32, i32, i32, i32, i32, i32, i32, i32, i32, i16, i16, i16, i16, i8, i8, i8, i8 }>* @"$s4main5Value[[UNIQUE_ID_1]]VMn" to %swift.type_descriptor*)) #{{[0-9]+}} +// CHECK: {{%[0-9]+}} = call swiftcc %swift.metadata_response @__swift_instantiateGenericMetadata([[INT]] %0, i8* [[ERASED_TYPE]], i8* undef, i8* undef, %swift.type_descriptor* bitcast ({{.+}}$s4main5Value[[UNIQUE_ID_1]]VMn{{.+}} to %swift.type_descriptor*)) #{{[0-9]+}} // CHECK: ret %swift.metadata_response {{%[0-9]+}} // CHECK: } diff --git a/test/IRGen/prespecialized-metadata/struct-inmodule-0argument-within-class-1argument-1distinct_use.swift b/test/IRGen/prespecialized-metadata/struct-inmodule-0argument-within-class-1argument-1distinct_use.swift index bcb6e153a18e7..c977ff866059f 100644 --- a/test/IRGen/prespecialized-metadata/struct-inmodule-0argument-within-class-1argument-1distinct_use.swift +++ b/test/IRGen/prespecialized-metadata/struct-inmodule-0argument-within-class-1argument-1distinct_use.swift @@ -15,7 +15,7 @@ // i8** @"$sB[[INT]]_WV", // getelementptr inbounds (%swift.vwtable, %swift.vwtable* @"$s4main9NamespaceC5ValueVySi_GWV", i32 0, i32 0), // CHECK-SAME: [[INT]] 512, -// CHECK-SAME: %swift.type_descriptor* bitcast (<{ i32, i32, i32, i32, i32, i32, i32, i32, i32, i16, i16, i16, i16, i8, i8, i8, i8 }>* @"$s4main9NamespaceC5ValueVMn" to %swift.type_descriptor*), +// CHECK-SAME: %swift.type_descriptor* bitcast ({{.+}}$s4main9NamespaceC5ValueVMn{{.+}} to %swift.type_descriptor*), // CHECK-SAME: %swift.type* @"$sSiN", // CHECK-SAME: i32 0{{(, \[4 x i8\] zeroinitializer)?}}, // CHECK-SAME: i64 3 @@ -54,6 +54,6 @@ doit() // CHECK: [[EXIT_PRESPECIALIZED_1]]: // CHECK: ret %swift.metadata_response { %swift.type* getelementptr inbounds (%swift.full_type, %swift.full_type* bitcast (<{ i8**, [[INT]], %swift.type_descriptor*, %swift.type*, i32{{(, \[4 x i8\])?}}, i64 }>* @"$s4main9NamespaceC5ValueVySi_GMf" to %swift.full_type*), i32 0, i32 1), [[INT]] 0 } // CHECK: [[EXIT_NORMAL]]: -// CHECK: {{%[0-9]+}} = call swiftcc %swift.metadata_response @__swift_instantiateGenericMetadata([[INT]] %0, i8* [[ERASED_TYPE_1]], i8* undef, i8* undef, %swift.type_descriptor* bitcast (<{ i32, i32, i32, i32, i32, i32, i32, i32, i32, i16, i16, i16, i16, i8, i8, i8, i8 }>* @"$s4main9NamespaceC5ValueVMn" to %swift.type_descriptor*)) #{{[0-9]+}} +// CHECK: {{%[0-9]+}} = call swiftcc %swift.metadata_response @__swift_instantiateGenericMetadata([[INT]] %0, i8* [[ERASED_TYPE_1]], i8* undef, i8* undef, %swift.type_descriptor* bitcast ({{.+}}$s4main9NamespaceC5ValueVMn{{.+}} to %swift.type_descriptor*)) #{{[0-9]+}} // CHECK: ret %swift.metadata_response {{%[0-9]+}} // CHECK: } diff --git a/test/IRGen/prespecialized-metadata/struct-inmodule-1argument-0distinct_use.swift b/test/IRGen/prespecialized-metadata/struct-inmodule-1argument-0distinct_use.swift index 39213abad8591..43c1694f983b3 100644 --- a/test/IRGen/prespecialized-metadata/struct-inmodule-1argument-0distinct_use.swift +++ b/test/IRGen/prespecialized-metadata/struct-inmodule-1argument-0distinct_use.swift @@ -25,6 +25,6 @@ doit() // CHECK: define hidden swiftcc %swift.metadata_response @"$s4main5ValueVMa"([[INT]] %0, %swift.type* %1) #{{[0-9]+}} { // CHECK: entry: // CHECK: [[ERASED_TYPE:%[0-9]+]] = bitcast %swift.type* %1 to i8* -// CHECK: {{%[0-9]+}} = call swiftcc %swift.metadata_response @__swift_instantiateGenericMetadata([[INT]] %0, i8* [[ERASED_TYPE]], i8* undef, i8* undef, %swift.type_descriptor* bitcast (<{ i32, i32, i32, i32, i32, i32, i32, i32, i32, i16, i16, i16, i16, i8, i8, i8, i8 }>* @"$s4main5ValueVMn" to %swift.type_descriptor*)) #{{[0-9]+}} +// CHECK: {{%[0-9]+}} = call swiftcc %swift.metadata_response @__swift_instantiateGenericMetadata([[INT]] %0, i8* [[ERASED_TYPE]], i8* undef, i8* undef, %swift.type_descriptor* bitcast ({{.+}}$s4main5ValueVMn{{.+}} to %swift.type_descriptor*)) #{{[0-9]+}} // CHECK: ret %swift.metadata_response {{%[0-9]+}} // CHECK: } diff --git a/test/IRGen/prespecialized-metadata/struct-inmodule-1argument-1conformance-1distinct_use.swift b/test/IRGen/prespecialized-metadata/struct-inmodule-1argument-1conformance-1distinct_use.swift index d15fd7d0fe00a..4b904ed09cc01 100644 --- a/test/IRGen/prespecialized-metadata/struct-inmodule-1argument-1conformance-1distinct_use.swift +++ b/test/IRGen/prespecialized-metadata/struct-inmodule-1argument-1conformance-1distinct_use.swift @@ -19,7 +19,7 @@ // i8** @"$sB[[INT]]_WV", // i8** getelementptr inbounds (%swift.vwtable, %swift.vwtable* @"$s4main5ValueVySiGWV", i32 0, i32 0), // CHECK-SAME: [[INT]] 512, -// CHECK-SAME: %swift.type_descriptor* bitcast (<{ i32, i32, i32, i32, i32, i32, i32, i32, i32, i16, i16, i16, i16, i8, i8, i8, i8, i32, i32, i32 }>* @"$s4main5ValueVMn" to %swift.type_descriptor*), +// CHECK-SAME: %swift.type_descriptor* bitcast ({{.+}}$s4main5ValueVMn{{.+}} to %swift.type_descriptor*), // CHECK-SAME: %swift.type* @"$sSiN", // CHECK-SAME: i8** getelementptr inbounds ([1 x i8*], [1 x i8*]* @"$sSi4main1PAAWP", i32 0, i32 0), // CHECK-SAME: i32 0{{(, \[4 x i8\] zeroinitializer)?}}, @@ -59,6 +59,6 @@ doit() // CHECK: [[EXIT_PRESPECIALIZED]]: // CHECK: ret %swift.metadata_response { %swift.type* getelementptr inbounds (%swift.full_type, %swift.full_type* bitcast (<{ i8**, [[INT]], %swift.type_descriptor*, %swift.type*, i8**, i32{{(, \[4 x i8\])?}}, i64 }>* @"$s4main5ValueVySiGMf" to %swift.full_type*), i32 0, i32 1), [[INT]] 0 } // CHECK: [[EXIT_NORMAL]]: -// CHECK: {{%[0-9]+}} = call swiftcc %swift.metadata_response @__swift_instantiateGenericMetadata([[INT]] %0, i8* [[ERASED_TYPE]], i8* [[ERASED_TABLE]], i8* undef, %swift.type_descriptor* bitcast (<{ i32, i32, i32, i32, i32, i32, i32, i32, i32, i16, i16, i16, i16, i8, i8, i8, i8, i32, i32, i32 }>* @"$s4main5ValueVMn" to %swift.type_descriptor*)) +// CHECK: {{%[0-9]+}} = call swiftcc %swift.metadata_response @__swift_instantiateGenericMetadata([[INT]] %0, i8* [[ERASED_TYPE]], i8* [[ERASED_TABLE]], i8* undef, %swift.type_descriptor* bitcast ({{.+}}$s4main5ValueVMn{{.+}} to %swift.type_descriptor*)) // CHECK: ret %swift.metadata_response {{%[0-9]+}} // CHECK: } diff --git a/test/IRGen/prespecialized-metadata/struct-inmodule-1argument-1conformance-stdlib_equatable-1distinct_use.swift b/test/IRGen/prespecialized-metadata/struct-inmodule-1argument-1conformance-stdlib_equatable-1distinct_use.swift index ac49ffcb3bee5..81e9ef5b5c96a 100644 --- a/test/IRGen/prespecialized-metadata/struct-inmodule-1argument-1conformance-stdlib_equatable-1distinct_use.swift +++ b/test/IRGen/prespecialized-metadata/struct-inmodule-1argument-1conformance-stdlib_equatable-1distinct_use.swift @@ -30,6 +30,6 @@ doit() // CHECK: entry: // CHECK: [[ERASED_TYPE:%[0-9]+]] = bitcast %swift.type* %1 to i8* // CHECK: [[ERASED_CONFORMANCE:%[0-9]+]] = bitcast i8** %2 to i8* -// CHECK: {{%[0-9]+}} = call swiftcc %swift.metadata_response @__swift_instantiateGenericMetadata([[INT]] %0, i8* [[ERASED_TYPE]], i8* [[ERASED_CONFORMANCE]], i8* undef, %swift.type_descriptor* bitcast (<{ i32, i32, i32, i32, i32, i32, i32, i32, i32, i16, i16, i16, i16, i8, i8, i8, i8, i32, i32, i32 }>* @"$s4main5ValueVMn" to %swift.type_descriptor*)) #{{[0-9]+}} +// CHECK: {{%[0-9]+}} = call swiftcc %swift.metadata_response @__swift_instantiateGenericMetadata([[INT]] %0, i8* [[ERASED_TYPE]], i8* [[ERASED_CONFORMANCE]], i8* undef, %swift.type_descriptor* bitcast ({{.+}}$s4main5ValueVMn{{.+}} to %swift.type_descriptor*)) #{{[0-9]+}} // CHECK: ret %swift.metadata_response {{%[0-9]+}} // CHECK: } diff --git a/test/IRGen/prespecialized-metadata/struct-inmodule-1argument-1distinct_generic_use.swift b/test/IRGen/prespecialized-metadata/struct-inmodule-1argument-1distinct_generic_use.swift index 2e84778e287cc..174353f07fc17 100644 --- a/test/IRGen/prespecialized-metadata/struct-inmodule-1argument-1distinct_generic_use.swift +++ b/test/IRGen/prespecialized-metadata/struct-inmodule-1argument-1distinct_generic_use.swift @@ -107,9 +107,7 @@ doit() // CHECK-SAME: i8* undef, // CHECK-SAME: i8* undef, // CHECK-SAME: %swift.type_descriptor* bitcast ( -// CHECK-SAME: <{ i32, i32, i32, i32, i32, i32, i32, i32, i32, i16, i16, i16, i16, i8, i8, i8, i8 }>* -// CHECK-SAME: @"$s4main5OuterVMn" -// CHECK-SAME: to %swift.type_descriptor* +// CHECK-SAME: {{.+}}$s4main5OuterVMn{{.+}} to %swift.type_descriptor* // CHECK-SAME: ) // CHECK-SAME: ) #{{[0-9]+}} // CHECK: ret %swift.metadata_response {{%[0-9]+}} @@ -152,9 +150,7 @@ doit() // CHECK-SAME: i8* undef, // CHECK-SAME: i8* undef, // CHECK-SAME: %swift.type_descriptor* bitcast ( -// CHECK-SAME: <{ i32, i32, i32, i32, i32, i32, i32, i32, i32, i16, i16, i16, i16, i8, i8, i8, i8 }>* -// CHECK-SAME: @"$s4main5InnerVMn" -// CHECK-SAME: to %swift.type_descriptor* +// CHECK-SAME: {{.+}}$s4main5InnerVMn{{.+}} to %swift.type_descriptor* // CHECK-SAME: ) // CHECK-SAME: ) #{{[0-9]+}} // CHECK: ret %swift.metadata_response {{%[0-9]+}} diff --git a/test/IRGen/prespecialized-metadata/struct-inmodule-1argument-1distinct_use.swift b/test/IRGen/prespecialized-metadata/struct-inmodule-1argument-1distinct_use.swift index 22042edc3e72a..4fe989575ef83 100644 --- a/test/IRGen/prespecialized-metadata/struct-inmodule-1argument-1distinct_use.swift +++ b/test/IRGen/prespecialized-metadata/struct-inmodule-1argument-1distinct_use.swift @@ -16,7 +16,7 @@ // i8** @"$sB[[INT]]_WV", // i8** getelementptr inbounds (%swift.vwtable, %swift.vwtable* @"$s4main5ValueVySiGWV", i32 0, i32 0), // CHECK-SAME: [[INT]] 512, -// CHECK-SAME: %swift.type_descriptor* bitcast (<{ i32, i32, i32, i32, i32, i32, i32, i32, i32, i16, i16, i16, i16, i8, i8, i8, i8 }>* @"$s4main5ValueVMn" to %swift.type_descriptor*), +// CHECK-SAME: %swift.type_descriptor* bitcast ({{.+}}$s4main5ValueVMn{{.+}} to %swift.type_descriptor*), // CHECK-SAME: %swift.type* @"$sSiN", // CHECK-SAME: i32 0{{(, \[4 x i8\] zeroinitializer)?}}, // CHECK-SAME: i64 3 @@ -52,6 +52,6 @@ doit() // CHECK: [[EXIT_PRESPECIALIZED]]: // CHECK: ret %swift.metadata_response { %swift.type* getelementptr inbounds (%swift.full_type, %swift.full_type* bitcast (<{ i8**, [[INT]], %swift.type_descriptor*, %swift.type*, i32{{(, \[4 x i8\])?}}, i64 }>* @"$s4main5ValueVySiGMf" to %swift.full_type*), i32 0, i32 1), [[INT]] 0 } // CHECK: [[EXIT_NORMAL]]: -// CHECK: {{%[0-9]+}} = call swiftcc %swift.metadata_response @__swift_instantiateGenericMetadata([[INT]] %0, i8* [[ERASED_TYPE]], i8* undef, i8* undef, %swift.type_descriptor* bitcast (<{ i32, i32, i32, i32, i32, i32, i32, i32, i32, i16, i16, i16, i16, i8, i8, i8, i8 }>* @"$s4main5ValueVMn" to %swift.type_descriptor*)) #{{[0-9]+}} +// CHECK: {{%[0-9]+}} = call swiftcc %swift.metadata_response @__swift_instantiateGenericMetadata([[INT]] %0, i8* [[ERASED_TYPE]], i8* undef, i8* undef, %swift.type_descriptor* bitcast ({{.+}}$s4main5ValueVMn{{.+}} to %swift.type_descriptor*)) #{{[0-9]+}} // CHECK: ret %swift.metadata_response {{%[0-9]+}} // CHECK: } diff --git a/test/IRGen/prespecialized-metadata/struct-inmodule-1argument-2conformance-1distinct_use.swift b/test/IRGen/prespecialized-metadata/struct-inmodule-1argument-2conformance-1distinct_use.swift index 4ea756bc704c2..15874f76018ff 100644 --- a/test/IRGen/prespecialized-metadata/struct-inmodule-1argument-2conformance-1distinct_use.swift +++ b/test/IRGen/prespecialized-metadata/struct-inmodule-1argument-2conformance-1distinct_use.swift @@ -20,7 +20,7 @@ // i8** @"$sB[[INT]]_WV", // i8** getelementptr inbounds (%swift.vwtable, %swift.vwtable* @"$s4main5ValueVySiGWV", i32 0, i32 0), // CHECK-SAME: [[INT]] 512, -// CHECK-SAME: %swift.type_descriptor* bitcast (<{ i32, i32, i32, i32, i32, i32, i32, i32, i32, i16, i16, i16, i16, i8, i8, i8, i8, i32, i32, i32, i32, i32, i32 }>* @"$s4main5ValueVMn" to %swift.type_descriptor*), +// CHECK-SAME: %swift.type_descriptor* bitcast ({{.+}}$s4main5ValueVMn{{.+}} to %swift.type_descriptor*), // CHECK-SAME: %swift.type* @"$sSiN", // CHECK-SAME: i8** getelementptr inbounds ([1 x i8*], [1 x i8*]* @"$sSi4main1PAAWP", i32 0, i32 0), // CHECK-SAME: i8** getelementptr inbounds ([1 x i8*], [1 x i8*]* @"$sSi4main1QAAWP", i32 0, i32 0), @@ -64,6 +64,6 @@ doit() // CHECK: [[EXIT_PRESPECIALIZED]]: // CHECK: ret %swift.metadata_response { %swift.type* getelementptr inbounds (%swift.full_type, %swift.full_type* bitcast (<{ i8**, [[INT]], %swift.type_descriptor*, %swift.type*, i8**, i8**, i32{{(, \[4 x i8\])?}}, i64 }>* @"$s4main5ValueVySiGMf" to %swift.full_type*), i32 0, i32 1), [[INT]] 0 } // CHECK: [[EXIT_NORMAL]]: -// CHECK: {{%[0-9]+}} = call swiftcc %swift.metadata_response @__swift_instantiateGenericMetadata([[INT]] %0, i8* [[ERASED_TYPE]], i8* [[ERASED_TABLE_1]], i8* [[ERASED_TABLE_2]], %swift.type_descriptor* bitcast (<{ i32, i32, i32, i32, i32, i32, i32, i32, i32, i16, i16, i16, i16, i8, i8, i8, i8, i32, i32, i32, i32, i32, i32 }>* @"$s4main5ValueVMn" to %swift.type_descriptor*)) #{{[0-9]+}} +// CHECK: {{%[0-9]+}} = call swiftcc %swift.metadata_response @__swift_instantiateGenericMetadata([[INT]] %0, i8* [[ERASED_TYPE]], i8* [[ERASED_TABLE_1]], i8* [[ERASED_TABLE_2]], %swift.type_descriptor* bitcast ({{.+}}$s4main5ValueVMn{{.+}} to %swift.type_descriptor*)) #{{[0-9]+}} // CHECK: ret %swift.metadata_response {{%[0-9]+}} // CHECK: } diff --git a/test/IRGen/prespecialized-metadata/struct-inmodule-1argument-2distinct_use.swift b/test/IRGen/prespecialized-metadata/struct-inmodule-1argument-2distinct_use.swift index f0e1320e98c38..604f867e7efb0 100644 --- a/test/IRGen/prespecialized-metadata/struct-inmodule-1argument-2distinct_use.swift +++ b/test/IRGen/prespecialized-metadata/struct-inmodule-1argument-2distinct_use.swift @@ -16,7 +16,7 @@ // i8** @"$sBi64_WV", // i8** getelementptr inbounds (%swift.vwtable, %swift.vwtable* @"$s4main5ValueVySdGWV", i32 0, i32 0), // CHECk-SAME: [[INT]] 512, -// CHECK-SAME: %swift.type_descriptor* bitcast (<{ i32, i32, i32, i32, i32, i32, i32, i32, i32, i16, i16, i16, i16, i8, i8, i8, i8 }>* @"$s4main5ValueVMn" to %swift.type_descriptor*), +// CHECK-SAME: %swift.type_descriptor* bitcast ({{.+}}$s4main5ValueVMn{{.+}} to %swift.type_descriptor*), // CHECK-SAME: %swift.type* @"$sSdN", // CHECK-SAME: i32 0{{(, \[4 x i8\] zeroinitializer)?}}, // CHECK-SAME: i64 3 @@ -33,7 +33,7 @@ // i8** @"$sB[[INT]]_WV", // i8** getelementptr inbounds (%swift.vwtable, %swift.vwtable* @"$s4main5ValueVySiGWV", i32 0, i32 0), // CHECK-SAME: [[INT]] 512, -// CHECK-SAME: %swift.type_descriptor* bitcast (<{ i32, i32, i32, i32, i32, i32, i32, i32, i32, i16, i16, i16, i16, i8, i8, i8, i8 }>* @"$s4main5ValueVMn" to %swift.type_descriptor*), +// CHECK-SAME: %swift.type_descriptor* bitcast ({{.+}}$s4main5ValueVMn{{.+}} to %swift.type_descriptor*), // CHECK-SAME: %swift.type* @"$sSiN", // CHECK-SAME: i32 0{{(, \[4 x i8\] zeroinitializer)?}}, // CHECK-SAME: i64 3 @@ -77,6 +77,6 @@ doit() // CHECK: [[EXIT_PRESPECIALIZED_2]]: // CHECK: ret %swift.metadata_response { %swift.type* getelementptr inbounds (%swift.full_type, %swift.full_type* bitcast (<{ i8**, [[INT]], %swift.type_descriptor*, %swift.type*, i32{{(, \[4 x i8\])?}}, i64 }>* @"$s4main5ValueVySdGMf" to %swift.full_type*), i32 0, i32 1), [[INT]] 0 } // CHECK: [[EXIT_NORMAL]]: -// CHECK: {{%[0-9]+}} = call swiftcc %swift.metadata_response @__swift_instantiateGenericMetadata([[INT]] %0, i8* [[ERASED_TYPE]], i8* undef, i8* undef, %swift.type_descriptor* bitcast (<{ i32, i32, i32, i32, i32, i32, i32, i32, i32, i16, i16, i16, i16, i8, i8, i8, i8 }>* @"$s4main5ValueVMn" to %swift.type_descriptor*)) #{{[0-9]+}} +// CHECK: {{%[0-9]+}} = call swiftcc %swift.metadata_response @__swift_instantiateGenericMetadata([[INT]] %0, i8* [[ERASED_TYPE]], i8* undef, i8* undef, %swift.type_descriptor* bitcast ({{.+}}$s4main5ValueVMn{{.+}} to %swift.type_descriptor*)) #{{[0-9]+}} // CHECK: ret %swift.metadata_response {{%[0-9]+}} // CHECK: } diff --git a/test/IRGen/prespecialized-metadata/struct-inmodule-1argument-3conformance-1distinct_use.swift b/test/IRGen/prespecialized-metadata/struct-inmodule-1argument-3conformance-1distinct_use.swift index ae717f872767c..9b0790f395684 100644 --- a/test/IRGen/prespecialized-metadata/struct-inmodule-1argument-3conformance-1distinct_use.swift +++ b/test/IRGen/prespecialized-metadata/struct-inmodule-1argument-3conformance-1distinct_use.swift @@ -21,7 +21,7 @@ // i8** @"$sB[[INT]]_WV", // i8** getelementptr inbounds (%swift.vwtable, %swift.vwtable* @"$s4main5ValueVySiGWV", i32 0, i32 0), // CHECK-SAME: [[INT]] 512, -// CHECK-SAME: %swift.type_descriptor* bitcast (<{ i32, i32, i32, i32, i32, i32, i32, i32, i32, i16, i16, i16, i16, i8, i8, i8, i8, i32, i32, i32, i32, i32, i32, i32, i32, i32 }>* @"$s4main5ValueVMn" to %swift.type_descriptor*), +// CHECK-SAME: %swift.type_descriptor* bitcast ({{.+}}$s4main5ValueVMn{{.+}} to %swift.type_descriptor*), // CHECK-SAME: %swift.type* @"$sSiN", // CHECK-SAME: i8** getelementptr inbounds ([1 x i8*], [1 x i8*]* @"$sSi4main1PAAWP", i32 0, i32 0), // CHECK-SAME: i8** getelementptr inbounds ([1 x i8*], [1 x i8*]* @"$sSi4main1QAAWP", i32 0, i32 0), @@ -68,6 +68,6 @@ doit() // CHECK: [[EXIT_PRESPECIALIZED]]: // CHECK: ret %swift.metadata_response { %swift.type* getelementptr inbounds (%swift.full_type, %swift.full_type* bitcast (<{ i8**, [[INT]], %swift.type_descriptor*, %swift.type*, i8**, i8**, i8**, i32{{(, \[4 x i8\])?}}, i64 }>* @"$s4main5ValueVySiGMf" to %swift.full_type*), i32 0, i32 1), [[INT]] 0 } // CHECK: [[EXIT_NORMAL]]: -// CHECK: {{%[0-9]+}} = call swiftcc %swift.metadata_response @swift_getGenericMetadata([[INT]] %0, i8* [[ERASED_ARGUMENT_BUFFER]], %swift.type_descriptor* bitcast (<{ i32, i32, i32, i32, i32, i32, i32, i32, i32, i16, i16, i16, i16, i8, i8, i8, i8, i32, i32, i32, i32, i32, i32, i32, i32, i32 }>* @"$s4main5ValueVMn" to %swift.type_descriptor*)) #{{[0-9]+}} +// CHECK: {{%[0-9]+}} = call swiftcc %swift.metadata_response @swift_getGenericMetadata([[INT]] %0, i8* [[ERASED_ARGUMENT_BUFFER]], %swift.type_descriptor* bitcast ({{.+}}$s4main5ValueVMn{{.+}} to %swift.type_descriptor*)) #{{[0-9]+}} // CHECK: ret %swift.metadata_response {{%[0-9]+}} // CHECK: } diff --git a/test/IRGen/prespecialized-metadata/struct-inmodule-1argument-3distinct_use.swift b/test/IRGen/prespecialized-metadata/struct-inmodule-1argument-3distinct_use.swift index 35f14e1eb5e7f..3e3c890e24d46 100644 --- a/test/IRGen/prespecialized-metadata/struct-inmodule-1argument-3distinct_use.swift +++ b/test/IRGen/prespecialized-metadata/struct-inmodule-1argument-3distinct_use.swift @@ -6,14 +6,14 @@ // UNSUPPORTED: CPU=armv7s && OS=ios // CHECK: @"$s4main5ValueVySSGWV" = linkonce_odr hidden constant %swift.vwtable { -// CHECK-SAME: i8* bitcast (%swift.opaque* ([{{[0-9]+}} x i8]*, [{{[0-9]+}} x i8]*, %swift.type*)* @"$s4main5ValueVySSGwCP" to i8*), -// CHECK-SAME: i8* bitcast (void (%swift.opaque*, %swift.type*)* @"$s4main5ValueVySSGwxx" to i8*), -// CHECK-SAME: i8* bitcast (%swift.opaque* (%swift.opaque*, %swift.opaque*, %swift.type*)* @"$s4main5ValueVySSGwcp" to i8*), -// CHECK-SAME: i8* bitcast (%swift.opaque* (%swift.opaque*, %swift.opaque*, %swift.type*)* @"$s4main5ValueVySSGwca" to i8*), -// CHECK-SAME: i8* bitcast (i8* (i8*, i8*, %swift.type*)* @__swift_memcpy{{[0-9]+}}_[[ALIGNMENT]] to i8*), -// CHECK-SAME: i8* bitcast (%swift.opaque* (%swift.opaque*, %swift.opaque*, %swift.type*)* @"$s4main5ValueVySSGwta" to i8*), -// CHECK-SAME: i8* bitcast (i32 (%swift.opaque*, i32, %swift.type*)* @"$s4main5ValueVySSGwet" to i8*), -// CHECK-SAME: i8* bitcast (void (%swift.opaque*, i32, i32, %swift.type*)* @"$s4main5ValueVySSGwst" to i8*), +// CHECK-SAME: i8* bitcast ({{[^@]*}}@"$s4main5ValueVySSGwCP{{[^@]* to i8\*}}), +// CHECK-SAME: i8* bitcast ({{[^@]*}}@"$s4main5ValueVySSGwxx{{[^@]* to i8\*}}), +// CHECK-SAME: i8* bitcast ({{[^@]*}}@"$s4main5ValueVySSGwcp{{[^@]* to i8\*}}), +// CHECK-SAME: i8* bitcast ({{[^@]*}}@"$s4main5ValueVySSGwca{{[^@]* to i8\*}}), +// CHECK-SAME: i8* bitcast ({{[^@]*}}@__swift_memcpy{{[^[:space:]]+ to i8\*}}), +// CHECK-SAME: i8* bitcast ({{[^@]*}}@"$s4main5ValueVySSGwta{{[^@]* to i8\*}}), +// CHECK-SAME: i8* bitcast ({{[^@]*}}@"$s4main5ValueVySSGwet{{[^@]* to i8\*}}), +// CHECK-SAME: i8* bitcast ({{[^@]*}}@"$s4main5ValueVySSGwst{{[^@]* to i8\*}}), // CHECK-SAME: [[INT]] {{[0-9]+}}, // CHECK-SAME: [[INT]] {{[0-9]+}}, // CHECK-SAME: i32 {{[0-9]+}}, @@ -22,7 +22,7 @@ // NOTE: ignore COMDAT on PE/COFF targets // CHECK-SAME: align [[ALIGNMENT]] -// CHECK: @"$s4main5ValueVySSGMf" = linkonce_odr hidden constant <{ i8**, [[INT]], %swift.type_descriptor*, %swift.type*, i32{{(, \[4 x i8\])?}}, i64 }> <{ i8** getelementptr inbounds (%swift.vwtable, %swift.vwtable* @"$s4main5ValueVySSGWV", i32 0, i32 0), [[INT]] 512, %swift.type_descriptor* bitcast (<{ i32, i32, i32, i32, i32, i32, i32, i32, i32, i16, i16, i16, i16, i8, i8, i8, i8 }>* @"$s4main5ValueVMn" to %swift.type_descriptor*), %swift.type* @"$sSSN", i32 0{{(, \[4 x i8\] zeroinitializer)?}}, i64 3 }>, align [[ALIGNMENT]] +// CHECK: @"$s4main5ValueVySSGMf" = linkonce_odr hidden constant {{.+}}$s4main5ValueVMn{{.+}} to %swift.type_descriptor*), %swift.type* @"$sSSN", i32 0{{(, \[4 x i8\] zeroinitializer)?}}, i64 3 }>, align [[ALIGNMENT]] // CHECK: @"$s4main5ValueVySdGMf" = linkonce_odr hidden constant <{ // CHECK-SAME: i8**, @@ -35,7 +35,7 @@ // i8** @"$sBi64_WV", // i8** getelementptr inbounds (%swift.vwtable, %swift.vwtable* @"$s4main5ValueVySdGWV", i32 0, i32 0), // CHECK-SAME: [[INT]] 512, -// CHECK-SAME: %swift.type_descriptor* bitcast (<{ i32, i32, i32, i32, i32, i32, i32, i32, i32, i16, i16, i16, i16, i8, i8, i8, i8 }>* @"$s4main5ValueVMn" to %swift.type_descriptor*), +// CHECK-SAME: %swift.type_descriptor* bitcast ({{.+}}$s4main5ValueVMn{{.+}} to %swift.type_descriptor*), // CHECK-SAME: %swift.type* @"$sSdN", // CHECK-SAME: i32 0{{(, \[4 x i8\] zeroinitializer)?}}, // CHECK-SAME: i64 3 @@ -52,7 +52,7 @@ // i8** @"$sB[[INT]]_WV", // i8** getelementptr inbounds (%swift.vwtable, %swift.vwtable* @"$s4main5ValueVySiGWV", i32 0, i32 0), // CHECK-SAME: [[INT]] 512, -// CHECK-SAME: %swift.type_descriptor* bitcast (<{ i32, i32, i32, i32, i32, i32, i32, i32, i32, i16, i16, i16, i16, i8, i8, i8, i8 }>* @"$s4main5ValueVMn" to %swift.type_descriptor*), +// CHECK-SAME: %swift.type_descriptor* bitcast ({{.+}}$s4main5ValueVMn{{.+}} to %swift.type_descriptor*), // CHECK-SAME: %swift.type* @"$sSiN", // CHECK-SAME: i32 0{{(, \[4 x i8\] zeroinitializer)?}}, // CHECK-SAME: i64 3 @@ -104,6 +104,6 @@ doit() // CHECK: [[EXIT_PRESPECIALIZED_3]]: // CHECK: ret %swift.metadata_response { %swift.type* getelementptr inbounds (%swift.full_type, %swift.full_type* bitcast (<{ i8**, [[INT]], %swift.type_descriptor*, %swift.type*, i32{{(, \[4 x i8\])?}}, i64 }>* @"$s4main5ValueVySSGMf" to %swift.full_type*), i32 0, i32 1), [[INT]] 0 } // CHECK: [[EXIT_NORMAL]]: -// CHECK: {{%[0-9]+}} = call swiftcc %swift.metadata_response @__swift_instantiateGenericMetadata([[INT]] %0, i8* [[ERASED_TYPE]], i8* undef, i8* undef, %swift.type_descriptor* bitcast (<{ i32, i32, i32, i32, i32, i32, i32, i32, i32, i16, i16, i16, i16, i8, i8, i8, i8 }>* @"$s4main5ValueVMn" to %swift.type_descriptor*)) #{{[0-9]+}} +// CHECK: {{%[0-9]+}} = call swiftcc %swift.metadata_response @__swift_instantiateGenericMetadata([[INT]] %0, i8* [[ERASED_TYPE]], i8* undef, i8* undef, %swift.type_descriptor* bitcast ({{.+}}$s4main5ValueVMn{{.+}} to %swift.type_descriptor*)) #{{[0-9]+}} // CHECK: ret %swift.metadata_response {{%[0-9]+}} // CHECK: } diff --git a/test/IRGen/prespecialized-metadata/struct-inmodule-1argument-4conformance-1distinct_use.swift b/test/IRGen/prespecialized-metadata/struct-inmodule-1argument-4conformance-1distinct_use.swift index bf5aa4c372939..64632a842a242 100644 --- a/test/IRGen/prespecialized-metadata/struct-inmodule-1argument-4conformance-1distinct_use.swift +++ b/test/IRGen/prespecialized-metadata/struct-inmodule-1argument-4conformance-1distinct_use.swift @@ -22,7 +22,7 @@ // i8** @"$sB[[INT]]_WV", // i8** getelementptr inbounds (%swift.vwtable, %swift.vwtable* @"$s4main5ValueVySiGWV", i32 0, i32 0), // CHECK-SAME: [[INT]] 512, -// CHECK-SAME: %swift.type_descriptor* bitcast (<{ i32, i32, i32, i32, i32, i32, i32, i32, i32, i16, i16, i16, i16, i8, i8, i8, i8, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32 }>* @"$s4main5ValueVMn" to %swift.type_descriptor*), +// CHECK-SAME: %swift.type_descriptor* bitcast ({{.+}}$s4main5ValueVMn{{.+}} to %swift.type_descriptor*), // CHECK-SAME: %swift.type* @"$sSiN", // CHECK-SAME: i8** getelementptr inbounds ([1 x i8*], [1 x i8*]* @"$sSi4main1PAAWP", i32 0, i32 0), // CHECK-SAME: i8** getelementptr inbounds ([1 x i8*], [1 x i8*]* @"$sSi4main1QAAWP", i32 0, i32 0), @@ -72,6 +72,6 @@ doit() // CHECK: [[EXIT_PRESPECIALIZED]]: // CHECK: ret %swift.metadata_response { %swift.type* getelementptr inbounds (%swift.full_type, %swift.full_type* bitcast (<{ i8**, [[INT]], %swift.type_descriptor*, %swift.type*, i8**, i8**, i8**, i8**, i32{{(, \[4 x i8\])?}}, i64 }>* @"$s4main5ValueVySiGMf" to %swift.full_type*), i32 0, i32 1), [[INT]] 0 } // CHECK: [[EXIT_NORMAL]]: -// CHECK: {{%[0-9]+}} = call swiftcc %swift.metadata_response @swift_getGenericMetadata([[INT]] %0, i8* [[ERASED_ARGUMENT_BUFFER]], %swift.type_descriptor* bitcast (<{ i32, i32, i32, i32, i32, i32, i32, i32, i32, i16, i16, i16, i16, i8, i8, i8, i8, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32 }>* @"$s4main5ValueVMn" to %swift.type_descriptor*)) #{{[0-9]+}} +// CHECK: {{%[0-9]+}} = call swiftcc %swift.metadata_response @swift_getGenericMetadata([[INT]] %0, i8* [[ERASED_ARGUMENT_BUFFER]], %swift.type_descriptor* bitcast ({{.+}}$s4main5ValueVMn{{.+}} to %swift.type_descriptor*)) #{{[0-9]+}} // CHECK: ret %swift.metadata_response {{%[0-9]+}} // CHECK: } diff --git a/test/IRGen/prespecialized-metadata/struct-inmodule-1argument-4distinct_use.swift b/test/IRGen/prespecialized-metadata/struct-inmodule-1argument-4distinct_use.swift index f96ebe6de3006..80e50226d64bf 100644 --- a/test/IRGen/prespecialized-metadata/struct-inmodule-1argument-4distinct_use.swift +++ b/test/IRGen/prespecialized-metadata/struct-inmodule-1argument-4distinct_use.swift @@ -16,13 +16,13 @@ // i8** @"$sBi8_WV", // i8** getelementptr inbounds (%swift.vwtable, %swift.vwtable* @"$s4main5ValueVys5UInt8VGWV", i32 0, i32 0), // CHECK-SAME: [[INT]] 512, -// CHECK-SAME: %swift.type_descriptor* bitcast (<{ i32, i32, i32, i32, i32, i32, i32, i32, i32, i16, i16, i16, i16, i8, i8, i8, i8 }>* @"$s4main5ValueVMn" to %swift.type_descriptor*), +// CHECK-SAME: %swift.type_descriptor* bitcast ({{.+}}$s4main5ValueVMn{{.+}} to %swift.type_descriptor*), // CHECK-SAME: %swift.type* @"$ss5UInt8VN", // CHECK-SAME: i32 0{{(, \[4 x i8\] zeroinitializer)?}}, // CHECK-SAME: i64 3 // CHECK-SAME: }>, align [[ALIGNMENT]] -// CHECK: @"$s4main5ValueVySSGMf" = linkonce_odr hidden constant <{ i8**, [[INT]], %swift.type_descriptor*, %swift.type*, i32{{(, \[4 x i8\])?}}, i64 }> <{ i8** getelementptr inbounds (%swift.vwtable, %swift.vwtable* @"$s4main5ValueVySSGWV", i32 0, i32 0), [[INT]] 512, %swift.type_descriptor* bitcast (<{ i32, i32, i32, i32, i32, i32, i32, i32, i32, i16, i16, i16, i16, i8, i8, i8, i8 }>* @"$s4main5ValueVMn" to %swift.type_descriptor*), %swift.type* @"$sSSN", i32 0{{(, \[4 x i8\] zeroinitializer)?}}, i64 3 }>, align [[ALIGNMENT]] +// CHECK: @"$s4main5ValueVySSGMf" = linkonce_odr hidden constant {{.+}}$s4main5ValueVMn{{.+}} to %swift.type_descriptor*), %swift.type* @"$sSSN", i32 0{{(, \[4 x i8\] zeroinitializer)?}}, i64 3 }>, align [[ALIGNMENT]] // CHECK: @"$s4main5ValueVySdGMf" = linkonce_odr hidden constant <{ // CHECK-SAME: i8**, @@ -35,7 +35,7 @@ // i8** @"$sBi64_WV", // i8** getelementptr inbounds (%swift.vwtable, %swift.vwtable* @"$s4main5ValueVySdGWV", i32 0, i32 0), // CHECK-SAME: [[INT]] 512, -// CHECK-SAME: %swift.type_descriptor* bitcast (<{ i32, i32, i32, i32, i32, i32, i32, i32, i32, i16, i16, i16, i16, i8, i8, i8, i8 }>* @"$s4main5ValueVMn" to %swift.type_descriptor*), +// CHECK-SAME: %swift.type_descriptor* bitcast ({{.+}}$s4main5ValueVMn{{.+}} to %swift.type_descriptor*), // CHECK-SAME: %swift.type* @"$sSdN", // CHECK-SAME: i32 0{{(, \[4 x i8\] zeroinitializer)?}}, // CHECK-SAME: i64 3 @@ -52,7 +52,7 @@ // i8** @"$sB[[INT]]_WV", // i8** getelementptr inbounds (%swift.vwtable, %swift.vwtable* @"$s4main5ValueVySiGWV", i32 0, i32 0), // CHECk-SAME: [[INT]] 512, -// CHECK-SAME: %swift.type_descriptor* bitcast (<{ i32, i32, i32, i32, i32, i32, i32, i32, i32, i16, i16, i16, i16, i8, i8, i8, i8 }>* @"$s4main5ValueVMn" to %swift.type_descriptor*), +// CHECK-SAME: %swift.type_descriptor* bitcast ({{.+}}$s4main5ValueVMn{{.+}} to %swift.type_descriptor*), // CHECK-SAME: %swift.type* @"$sSiN", // CHECK-SAME: i32 0{{(, \[4 x i8\] zeroinitializer)?}}, // CHECK-SAME: i64 3 @@ -111,6 +111,6 @@ doit() // CHECK: [[EXIT_PRESPECIALIZED_4]]: // CHECK: ret %swift.metadata_response { %swift.type* getelementptr inbounds (%swift.full_type, %swift.full_type* bitcast (<{ i8**, [[INT]], %swift.type_descriptor*, %swift.type*, i32{{(, \[4 x i8\])?}}, i64 }>* @"$s4main5ValueVys5UInt8VGMf" to %swift.full_type*), i32 0, i32 1), [[INT]] 0 } // CHECK: [[EXIT_NORMAL]]: -// CHECK: {{%[0-9]+}} = call swiftcc %swift.metadata_response @__swift_instantiateGenericMetadata([[INT]] %0, i8* [[ERASED_TYPE]], i8* undef, i8* undef, %swift.type_descriptor* bitcast (<{ i32, i32, i32, i32, i32, i32, i32, i32, i32, i16, i16, i16, i16, i8, i8, i8, i8 }>* @"$s4main5ValueVMn" to %swift.type_descriptor*)) #{{[0-9]+}} +// CHECK: {{%[0-9]+}} = call swiftcc %swift.metadata_response @__swift_instantiateGenericMetadata([[INT]] %0, i8* [[ERASED_TYPE]], i8* undef, i8* undef, %swift.type_descriptor* bitcast ({{.+}}$s4main5ValueVMn{{.+}} to %swift.type_descriptor*)) #{{[0-9]+}} // CHECK: ret %swift.metadata_response {{%[0-9]+}} // CHECK: } diff --git a/test/IRGen/prespecialized-metadata/struct-inmodule-1argument-5conformance-1distinct_use.swift b/test/IRGen/prespecialized-metadata/struct-inmodule-1argument-5conformance-1distinct_use.swift index dcfb2d298f367..ff974470aa1a3 100644 --- a/test/IRGen/prespecialized-metadata/struct-inmodule-1argument-5conformance-1distinct_use.swift +++ b/test/IRGen/prespecialized-metadata/struct-inmodule-1argument-5conformance-1distinct_use.swift @@ -23,7 +23,7 @@ // i8** @"$sB[[INT]]_WV", // i8** getelementptr inbounds (%swift.vwtable, %swift.vwtable* @"$s4main5ValueVySiGWV", i32 0, i32 0) // CHECK-SAME: [[INT]] 512, -// CHECK-SAME: %swift.type_descriptor* bitcast (<{ i32, i32, i32, i32, i32, i32, i32, i32, i32, i16, i16, i16, i16, i8, i8, i8, i8, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32 }>* @"$s4main5ValueVMn" to %swift.type_descriptor*), +// CHECK-SAME: %swift.type_descriptor* bitcast ({{.+}}$s4main5ValueVMn{{.+}} to %swift.type_descriptor*), // CHECK-SAME: %swift.type* @"$sSiN", // CHECK-SAME: i8** getelementptr inbounds ([1 x i8*], [1 x i8*]* @"$sSi4main1PAAWP", i32 0, i32 0), // CHECK-SAME: i8** getelementptr inbounds ([1 x i8*], [1 x i8*]* @"$sSi4main1QAAWP", i32 0, i32 0), @@ -76,6 +76,6 @@ doit() // CHECK: [[EXIT_PRESPECIALIZED]]: // CHECK: ret %swift.metadata_response { %swift.type* getelementptr inbounds (%swift.full_type, %swift.full_type* bitcast (<{ i8**, [[INT]], %swift.type_descriptor*, %swift.type*, i8**, i8**, i8**, i8**, i8**, i32{{(, \[4 x i8\])?}}, i64 }>* @"$s4main5ValueVySiGMf" to %swift.full_type*), i32 0, i32 1), [[INT]] 0 } // CHECK: [[EXIT_NORMAL]]: -// CHECK: {{%[0-9]+}} = call swiftcc %swift.metadata_response @swift_getGenericMetadata([[INT]] %0, i8* [[ERASED_ARGUMENT_BUFFER]], %swift.type_descriptor* bitcast (<{ i32, i32, i32, i32, i32, i32, i32, i32, i32, i16, i16, i16, i16, i8, i8, i8, i8, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32 }>* @"$s4main5ValueVMn" to %swift.type_descriptor*)) #{{[0-9]+}} +// CHECK: {{%[0-9]+}} = call swiftcc %swift.metadata_response @swift_getGenericMetadata([[INT]] %0, i8* [[ERASED_ARGUMENT_BUFFER]], %swift.type_descriptor* bitcast ({{.+}}$s4main5ValueVMn{{.+}} to %swift.type_descriptor*)) #{{[0-9]+}} // CHECK: ret %swift.metadata_response {{%[0-9]+}} // CHECK: } diff --git a/test/IRGen/prespecialized-metadata/struct-inmodule-1argument-5distinct_use.swift b/test/IRGen/prespecialized-metadata/struct-inmodule-1argument-5distinct_use.swift index f284e9f4092a2..365fd0fb65d4e 100644 --- a/test/IRGen/prespecialized-metadata/struct-inmodule-1argument-5distinct_use.swift +++ b/test/IRGen/prespecialized-metadata/struct-inmodule-1argument-5distinct_use.swift @@ -17,7 +17,7 @@ // i8** @"$sBi8_WV", // i8** getelementptr inbounds (%swift.vwtable, %swift.vwtable* @"$s4main5ValueVys4Int8VGWV", i32 0, i32 0), // CHECK-SAME: [[INT]] 512, -// CHECK-SAME: %swift.type_descriptor* bitcast (<{ i32, i32, i32, i32, i32, i32, i32, i32, i32, i16, i16, i16, i16, i8, i8, i8, i8 }>* @"$s4main5ValueVMn" to %swift.type_descriptor*), +// CHECK-SAME: %swift.type_descriptor* bitcast ({{.+}}$s4main5ValueVMn{{.+}} to %swift.type_descriptor*), // CHECK-SAME: %swift.type* @"$ss4Int8VN", // CHECK-SAME: i32 0{{(, \[4 x i8\] zeroinitializer)?}}, // CHECK-SAME: i64 3 @@ -34,21 +34,21 @@ // i8** @"$sBi8_WV", // i8** getelementptr inbounds (%swift.vwtable, %swift.vwtable* @"$s4main5ValueVys5UInt8VGWV", i32 0, i32 0), // CHECK-SAME: [[INT]] 512, -// CHECK-SAME: %swift.type_descriptor* bitcast (<{ i32, i32, i32, i32, i32, i32, i32, i32, i32, i16, i16, i16, i16, i8, i8, i8, i8 }>* @"$s4main5ValueVMn" to %swift.type_descriptor*), +// CHECK-SAME: %swift.type_descriptor* bitcast ({{.+}}$s4main5ValueVMn{{.+}} to %swift.type_descriptor*), // CHECK-SAME: %swift.type* @"$ss5UInt8VN", // CHECK-SAME: i32 0{{(, \[4 x i8\] zeroinitializer)?}}, // CHECK-SAME: i64 3 // CHECK-SAME: }>, align [[ALIGNMENT]] // CHECK: @"$s4main5ValueVySSGWV" = linkonce_odr hidden constant %swift.vwtable { -// CHECK-SAME: i8* bitcast (%swift.opaque* ([{{[0-9]+}} x i8]*, [{{[0-9]+}} x i8]*, %swift.type*)* @"$s4main5ValueVySSGwCP" to i8*), -// CHECK-SAME: i8* bitcast (void (%swift.opaque*, %swift.type*)* @"$s4main5ValueVySSGwxx" to i8*), -// CHECK-SAME: i8* bitcast (%swift.opaque* (%swift.opaque*, %swift.opaque*, %swift.type*)* @"$s4main5ValueVySSGwcp" to i8*), -// CHECK-SAME: i8* bitcast (%swift.opaque* (%swift.opaque*, %swift.opaque*, %swift.type*)* @"$s4main5ValueVySSGwca" to i8*), -// CHECK-SAME: i8* bitcast (i8* (i8*, i8*, %swift.type*)* @__swift_memcpy{{[0-9]+}}_[[ALIGNMENT]] to i8*), -// CHECK-SAME: i8* bitcast (%swift.opaque* (%swift.opaque*, %swift.opaque*, %swift.type*)* @"$s4main5ValueVySSGwta" to i8*), -// CHECK-SAME: i8* bitcast (i32 (%swift.opaque*, i32, %swift.type*)* @"$s4main5ValueVySSGwet" to i8*), -// CHECK-SAME: i8* bitcast (void (%swift.opaque*, i32, i32, %swift.type*)* @"$s4main5ValueVySSGwst" to i8*), +// CHECK-SAME: i8* bitcast ({{.+}}$s4main5ValueVySSGwCP{{[^[:space:]]+ to i8\*}}), +// CHECK-SAME: i8* bitcast ({{[^@]+}}@"$s4main5ValueVySSGwxx{{[^[:space:]]+ to i8\*}}), +// CHECK-SAME: i8* bitcast ({{[^@]+}}@"$s4main5ValueVySSGwcp{{[^[:space:]]+ to i8\*}}), +// CHECK-SAME: i8* bitcast ({{[^@]+}}@"$s4main5ValueVySSGwca{{[^[:space:]]+ to i8\*}}), +// CHECK-SAME: i8* bitcast ({{[^@]+}}@__swift_memcpy{{[^[:space:]]+ to i8\*}}), +// CHECK-SAME: i8* bitcast ({{[^@]+}}@"$s4main5ValueVySSGwta{{[^[:space:]]+ to i8\*}}), +// CHECK-SAME: i8* bitcast ({{[^@]+}}@"$s4main5ValueVySSGwet{{[^[:space:]]+ to i8\*}}), +// CHECK-SAME: i8* bitcast ({{[^@]+}}@"$s4main5ValueVySSGwst{{[^[:space:]]+ to i8\*}}), // CHECK-SAME: [[INT]] {{[0-9]+}}, // CHECK-SAME: [[INT]] {{[0-9]+}}, // CHECK-SAME: i32 {{[0-9]+}}, @@ -57,7 +57,7 @@ // NOTE: ignore COMDAT on PE/COFF target // CHECK-SAME: align [[ALIGNMENT]] -// CHECK: @"$s4main5ValueVySSGMf" = linkonce_odr hidden constant <{ i8**, [[INT]], %swift.type_descriptor*, %swift.type*, i32{{(, \[4 x i8\])?}}, i64 }> <{ i8** getelementptr inbounds (%swift.vwtable, %swift.vwtable* @"$s4main5ValueVySSGWV", i32 0, i32 0), [[INT]] 512, %swift.type_descriptor* bitcast (<{ i32, i32, i32, i32, i32, i32, i32, i32, i32, i16, i16, i16, i16, i8, i8, i8, i8 }>* @"$s4main5ValueVMn" to %swift.type_descriptor*), %swift.type* @"$sSSN", i32 0{{(, \[4 x i8\] zeroinitializer)?}}, i64 3 }>, align [[ALIGNMENT]] +// CHECK: @"$s4main5ValueVySSGMf" = linkonce_odr hidden constant {{.+}}$s4main5ValueVMn{{.+}} to %swift.type_descriptor*), %swift.type* @"$sSSN", i32 0{{(, \[4 x i8\] zeroinitializer)?}}, i64 3 }>, align [[ALIGNMENT]] // CHECK: @"$s4main5ValueVySdGMf" = linkonce_odr hidden constant <{ // CHECK-SAME: i8**, @@ -70,7 +70,7 @@ // i8** @"$sBi64_WV", // i8** getelementptr inbounds (%swift.vwtable, %swift.vwtable* @"$s4main5ValueVySdGWV", i32 0, i32 0), // CHECK-SAME: [[INT]] 512, -// CHECK-SAME: %swift.type_descriptor* bitcast (<{ i32, i32, i32, i32, i32, i32, i32, i32, i32, i16, i16, i16, i16, i8, i8, i8, i8 }>* @"$s4main5ValueVMn" to %swift.type_descriptor*), +// CHECK-SAME: %swift.type_descriptor* bitcast ({{.+}}$s4main5ValueVMn{{.+}} to %swift.type_descriptor*), // CHECK-SAME: %swift.type* @"$sSdN", // CHECK-SAME: i32 0{{(, \[4 x i8\] zeroinitializer)?}}, // CHECK-SAME: i64 3 @@ -87,7 +87,7 @@ // i8** @"$sB[[INT]]_WV", // i8** getelementptr inbounds (%swift.vwtable, %swift.vwtable* @"$s4main5ValueVySiGWV", i32 0, i32 0), // CHECK-SAME: [[INT]] 512, -// CHECK-SAME: %swift.type_descriptor* bitcast (<{ i32, i32, i32, i32, i32, i32, i32, i32, i32, i16, i16, i16, i16, i8, i8, i8, i8 }>* @"$s4main5ValueVMn" to %swift.type_descriptor*), +// CHECK-SAME: %swift.type_descriptor* bitcast ({{.+}}$s4main5ValueVMn{{.+}} to %swift.type_descriptor*), // CHECK-SAME: %swift.type* @"$sSiN", // CHECK-SAME: i32 0{{(, \[4 x i8\] zeroinitializer)?}}, // CHECK-SAME: i64 3 @@ -155,6 +155,6 @@ doit() // CHECK: [[EXIT_PRESPECIALIZED_5]]: // CHECK: ret %swift.metadata_response { %swift.type* getelementptr inbounds (%swift.full_type, %swift.full_type* bitcast (<{ i8**, [[INT]], %swift.type_descriptor*, %swift.type*, i32{{(, \[4 x i8\])?}}, i64 }>* @"$s4main5ValueVys4Int8VGMf" to %swift.full_type*), i32 0, i32 1), [[INT]] 0 } // CHECK: [[EXIT_NORMAL]]: -// CHECK: {{%[0-9]+}} = call swiftcc %swift.metadata_response @__swift_instantiateGenericMetadata([[INT]] %0, i8* [[ERASED_TYPE]], i8* undef, i8* undef, %swift.type_descriptor* bitcast (<{ i32, i32, i32, i32, i32, i32, i32, i32, i32, i16, i16, i16, i16, i8, i8, i8, i8 }>* @"$s4main5ValueVMn" to %swift.type_descriptor*)) #{{[0-9]+}} +// CHECK: {{%[0-9]+}} = call swiftcc %swift.metadata_response @__swift_instantiateGenericMetadata([[INT]] %0, i8* [[ERASED_TYPE]], i8* undef, i8* undef, %swift.type_descriptor* bitcast ({{.+}}$s4main5ValueVMn{{.+}} to %swift.type_descriptor*)) #{{[0-9]+}} // CHECK: ret %swift.metadata_response {{%[0-9]+}} // CHECK: } diff --git a/test/IRGen/prespecialized-metadata/struct-inmodule-1argument-clang_node-1distinct_use.swift b/test/IRGen/prespecialized-metadata/struct-inmodule-1argument-clang_node-1distinct_use.swift index 4e3557f23a6f4..6ecb89750a045 100644 --- a/test/IRGen/prespecialized-metadata/struct-inmodule-1argument-clang_node-1distinct_use.swift +++ b/test/IRGen/prespecialized-metadata/struct-inmodule-1argument-clang_node-1distinct_use.swift @@ -38,6 +38,6 @@ doit() // CHECK: define hidden swiftcc %swift.metadata_response @"$s4main5ValueVMa"([[INT]] %0, %swift.type* %1) #{{[0-9]+}} { // CHECK: entry: // CHECK: [[ERASED_TYPE:%[0-9]+]] = bitcast %swift.type* %1 to i8* -// CHECK: {{%[0-9]+}} = call swiftcc %swift.metadata_response @__swift_instantiateGenericMetadata([[INT]] %0, i8* [[ERASED_TYPE]], i8* undef, i8* undef, %swift.type_descriptor* bitcast (<{ i32, i32, i32, i32, i32, i32, i32, i32, i32, i16, i16, i16, i16, i8, i8, i8, i8 }>* @"$s4main5ValueVMn" to %swift.type_descriptor*)) #{{[0-9]+}} +// CHECK: {{%[0-9]+}} = call swiftcc %swift.metadata_response @__swift_instantiateGenericMetadata([[INT]] %0, i8* [[ERASED_TYPE]], i8* undef, i8* undef, %swift.type_descriptor* bitcast ({{.+}}$s4main5ValueVMn{{.+}} to %swift.type_descriptor*)) #{{[0-9]+}} // CHECK: ret %swift.metadata_response {{%[0-9]+}} // CHECK: } diff --git a/test/IRGen/prespecialized-metadata/struct-inmodule-1argument-within-class-1argument-1distinct_use.swift b/test/IRGen/prespecialized-metadata/struct-inmodule-1argument-within-class-1argument-1distinct_use.swift index de7ad60859204..e9a4f074aedf8 100644 --- a/test/IRGen/prespecialized-metadata/struct-inmodule-1argument-within-class-1argument-1distinct_use.swift +++ b/test/IRGen/prespecialized-metadata/struct-inmodule-1argument-within-class-1argument-1distinct_use.swift @@ -18,9 +18,7 @@ // i8** getelementptr inbounds (%swift.vwtable, %swift.vwtable* @"$s4main9NamespaceC5ValueVySS_SiGWV", i32 0, i32 0), // CHECK-SAME: [[INT]] 512, // CHECK-SAME: %swift.type_descriptor* bitcast ( -// CHECK-SAME: <{ i32, i32, i32, i32, i32, i32, i32, i32, i32, i16, i16, i16, i16, i8, i8, i8, i8 }>* -// CHECK-SAME: @"$s4main9NamespaceC5ValueVMn" -// CHECK-SAME: to %swift.type_descriptor* +// CHECK-SAME: {{.*}}$s4main9NamespaceC5ValueVMn{{.*}} to %swift.type_descriptor* // CHECK-SAME: ), // CHECK-SAME: %swift.type* @"$sSSN", // CHECK-SAME: %swift.type* @"$sSiN", @@ -107,9 +105,7 @@ doit() // CHECK-SAME: i8* [[ERASED_TYPE_2]], // CHECK-SAME: i8* undef, // CHECK-SAME: %swift.type_descriptor* bitcast ( -// CHECK-SAME: <{ i32, i32, i32, i32, i32, i32, i32, i32, i32, i16, i16, i16, i16, i8, i8, i8, i8 }>* -// CHECK-SAME: @"$s4main9NamespaceC5ValueVMn" -// CHECK-SAME: to %swift.type_descriptor* +// CHECK-SAME: {{.+}}$s4main9NamespaceC5ValueVMn{{.+}} to %swift.type_descriptor* // CHECK-SAME: ) // CHECK-SAME: ) #{{[0-9]+}} // CHECK: ret %swift.metadata_response {{%[0-9]+}} diff --git a/test/IRGen/prespecialized-metadata/struct-inmodule-1argument-within-enum-1argument-1distinct_use.swift b/test/IRGen/prespecialized-metadata/struct-inmodule-1argument-within-enum-1argument-1distinct_use.swift index 56bf17447aba0..2c4b5d76c63dc 100644 --- a/test/IRGen/prespecialized-metadata/struct-inmodule-1argument-within-enum-1argument-1distinct_use.swift +++ b/test/IRGen/prespecialized-metadata/struct-inmodule-1argument-within-enum-1argument-1distinct_use.swift @@ -18,9 +18,7 @@ // i8** getelementptr inbounds (%swift.vwtable, %swift.vwtable* @"$s4main9NamespaceO5ValueVySS_SiGWV", i32 0, i32 0) // CHECK-SAME: [[INT]] 512, // CHECK-SAME: %swift.type_descriptor* bitcast ( -// CHECK-SAME: <{ i32, i32, i32, i32, i32, i32, i32, i32, i32, i16, i16, i16, i16, i8, i8, i8, i8 }>* -// CHECK-SAME: @"$s4main9NamespaceO5ValueVMn" -// CHECK-SAME: to %swift.type_descriptor* +// CHECK-SAME: {{.*}}$s4main9NamespaceO5ValueVMn{{.*}} to %swift.type_descriptor* // CHECK-SAME: ), // CHECK-SAME: %swift.type* @"$sSSN", // CHECK-SAME: %swift.type* @"$sSiN", @@ -107,9 +105,7 @@ doit() // CHECK-SAME: i8* [[ERASED_TYPE_2]], // CHECK-SAME: i8* undef, // CHECK-SAME: %swift.type_descriptor* bitcast ( -// CHECK-SAME: <{ i32, i32, i32, i32, i32, i32, i32, i32, i32, i16, i16, i16, i16, i8, i8, i8, i8 }>* -// CHECK-SAME: @"$s4main9NamespaceO5ValueVMn" -// CHECK-SAME: to %swift.type_descriptor* +// CHECK-SAME: {{.+}}$s4main9NamespaceO5ValueVMn{{.+}} to %swift.type_descriptor* // CHECK-SAME: ) // CHECK-SAME: ) #{{[0-9]+}} // CHECK: ret %swift.metadata_response {{%[0-9]+}} diff --git a/test/IRGen/prespecialized-metadata/struct-inmodule-1argument-within-struct-1argument-1distinct_use.swift b/test/IRGen/prespecialized-metadata/struct-inmodule-1argument-within-struct-1argument-1distinct_use.swift index b9cbdd876d37b..f2cdb53ab20cc 100644 --- a/test/IRGen/prespecialized-metadata/struct-inmodule-1argument-within-struct-1argument-1distinct_use.swift +++ b/test/IRGen/prespecialized-metadata/struct-inmodule-1argument-within-struct-1argument-1distinct_use.swift @@ -18,9 +18,7 @@ // i8** getelementptr inbounds (%swift.vwtable, %swift.vwtable* @"$s4main9NamespaceV5ValueVySS_SiGWV", i32 0, i32 0), // CHECK-SAME: [[INT]] 512, // CHECK-SAME: %swift.type_descriptor* bitcast ( -// CHECK-SAME: <{ i32, i32, i32, i32, i32, i32, i32, i32, i32, i16, i16, i16, i16, i8, i8, i8, i8 }>* -// CHECK-SAME: @"$s4main9NamespaceV5ValueVMn" -// CHECK-SAME: to %swift.type_descriptor* +// CHECK-SAME: {{.*}}$s4main9NamespaceV5ValueVMn{{.*}} to %swift.type_descriptor* // CHECK-SAME: ), // CHECK-SAME: %swift.type* @"$sSSN", // CHECK-SAME: %swift.type* @"$sSiN", @@ -106,9 +104,7 @@ doit() // CHECK-SAME: i8* [[ERASED_TYPE_2]], // CHECK-SAME: i8* undef, // CHECK-SAME: %swift.type_descriptor* bitcast ( -// CHECK-SAME: <{ i32, i32, i32, i32, i32, i32, i32, i32, i32, i16, i16, i16, i16, i8, i8, i8, i8 }>* -// CHECK-SAME: @"$s4main9NamespaceV5ValueVMn" -// CHECK-SAME: to %swift.type_descriptor* +// CHECK-SAME: {{.+}}$s4main9NamespaceV5ValueVMn{{.+}} to %swift.type_descriptor* // CHECK-SAME: ) // CHECK-SAME: ) #{{[0-9]+}} // CHECK: ret %swift.metadata_response {{%[0-9]+}} diff --git a/test/IRGen/prespecialized-metadata/struct-inmodule-1argument-within-struct-2argument-constrained_extension-equal_arguments-1distinct_use.swift b/test/IRGen/prespecialized-metadata/struct-inmodule-1argument-within-struct-2argument-constrained_extension-equal_arguments-1distinct_use.swift index 48c394a732c59..5895295b7b6ee 100644 --- a/test/IRGen/prespecialized-metadata/struct-inmodule-1argument-within-struct-2argument-constrained_extension-equal_arguments-1distinct_use.swift +++ b/test/IRGen/prespecialized-metadata/struct-inmodule-1argument-within-struct-2argument-constrained_extension-equal_arguments-1distinct_use.swift @@ -22,11 +22,7 @@ // i32 0 // ), // CHECK-SAME: [[INT]] 512, -// CHECK-SAME: %swift.type_descriptor* bitcast ( -// CHECK-SAME: <{ i32, i32, i32, i32, i32, i32, i32, i32, i32, i16, i16, i16, i16, i8, i8, i8, i8, i32, i32, i32 }>* -// CHECK-SAME: @"$s4main9NamespaceVAAq_RszrlE5ValueVMn" -// CHECK-SAME: to %swift.type_descriptor* -// CHECK-SAME: ), +// CHECK-SAME: %swift.type_descriptor* bitcast ({{.*}}), // CHECK-SAME: %swift.type* @"$sSiN", // CHECK-SAME: %swift.type* @"$sSSN", // CHECK-SAME: i32 0, @@ -116,11 +112,7 @@ doit() // CHECK-SAME: i8* [[ERASED_TYPE_1]], // CHECK-SAME: i8* [[ERASED_TYPE_2]], // CHECK-SAME: i8* undef, -// CHECK-SAME: %swift.type_descriptor* bitcast ( -// CHECK-SAME: <{ i32, i32, i32, i32, i32, i32, i32, i32, i32, i16, i16, i16, i16, i8, i8, i8, i8, i32, i32, i32 }>* -// CHECK-SAME: @"$s4main9NamespaceVAAq_RszrlE5ValueVMn" -// CHECK-SAME: to %swift.type_descriptor* -// CHECK-SAME: ) +// CHECK-SAME: %swift.type_descriptor* bitcast ({{[^)]*}}) // CHECK-SAME: ) #{{[0-9]+}} // CHECK: ret %swift.metadata_response {{%[0-9]+}} // CHECK: } diff --git a/test/IRGen/prespecialized-metadata/struct-inmodule-2argument-0distinct_use.swift b/test/IRGen/prespecialized-metadata/struct-inmodule-2argument-0distinct_use.swift index a49b247524cff..8381bcfec18b0 100644 --- a/test/IRGen/prespecialized-metadata/struct-inmodule-2argument-0distinct_use.swift +++ b/test/IRGen/prespecialized-metadata/struct-inmodule-2argument-0distinct_use.swift @@ -27,6 +27,6 @@ doit() // CHECK: entry: // CHECK: [[ERASED_TYPE_1:%[0-9]+]] = bitcast %swift.type* %1 to i8* // CHECK: [[ERASED_TYPE_2:%[0-9]+]] = bitcast %swift.type* %2 to i8* -// CHECK: {{%[0-9]+}} = call swiftcc %swift.metadata_response @__swift_instantiateGenericMetadata([[INT]] %0, i8* [[ERASED_TYPE_1]], i8* [[ERASED_TYPE_2]], i8* undef, %swift.type_descriptor* bitcast (<{ i32, i32, i32, i32, i32, i32, i32, i32, i32, i16, i16, i16, i16, i8, i8, i8, i8 }>* @"$s4main5ValueVMn" to %swift.type_descriptor*)) #{{[0-9]+}} +// CHECK: {{%[0-9]+}} = call swiftcc %swift.metadata_response @__swift_instantiateGenericMetadata([[INT]] %0, i8* [[ERASED_TYPE_1]], i8* [[ERASED_TYPE_2]], i8* undef, %swift.type_descriptor* bitcast ({{.+}}$s4main5ValueVMn{{.+}} to %swift.type_descriptor*)) #{{[0-9]+}} // CHECK: ret %swift.metadata_response {{%[0-9]+}} // CHECK: } diff --git a/test/IRGen/prespecialized-metadata/struct-inmodule-2argument-1distinct_use.swift b/test/IRGen/prespecialized-metadata/struct-inmodule-2argument-1distinct_use.swift index ef8938cddf10b..da1183d3c20ac 100644 --- a/test/IRGen/prespecialized-metadata/struct-inmodule-2argument-1distinct_use.swift +++ b/test/IRGen/prespecialized-metadata/struct-inmodule-2argument-1distinct_use.swift @@ -6,14 +6,14 @@ // UNSUPPORTED: CPU=armv7s && OS=ios // CHECK: @"$s4main5ValueVyS2iGWV" = linkonce_odr hidden constant %swift.vwtable { -// CHECK-SAME: i8* bitcast ({{(%swift.opaque\* \(\[[0-9]+ x i8\]\*, \[[0-9]+ x i8\]\*, %swift.type\*\)\* @"\$[a-zA-Z0-9]+" to i8\*|i8\* \(i8\*, i8\*, %swift.type\*\)\* @__swift_memcpy[0-9]+_[0-9]+ to i8\*)}}), -// CHECK-SAME: i8* bitcast (void (i8*, %swift.type*)* @__swift_noop_void_return to i8*), -// CHECK-SAME: i8* bitcast (i8* (i8*, i8*, %swift.type*)* @__swift_memcpy{{[0-9]+}}_{{[0-9]+}} to i8*), -// CHECK-SAME: i8* bitcast (i8* (i8*, i8*, %swift.type*)* @__swift_memcpy{{[0-9]+}}_{{[0-9]+}} to i8*), -// CHECK-SAME: i8* bitcast (i8* (i8*, i8*, %swift.type*)* @__swift_memcpy{{[0-9]+}}_{{[0-9]+}} to i8*), -// CHECK-SAME: i8* bitcast (i8* (i8*, i8*, %swift.type*)* @__swift_memcpy{{[0-9]+}}_{{[0-9]+}} to i8*), -// CHECK-SAME: i8* bitcast (i32 (%swift.opaque*, i32, %swift.type*)* @"$s4main5ValueVyS2iGwet" to i8*), -// CHECK-SAME: i8* bitcast (void (%swift.opaque*, i32, i32, %swift.type*)* @"$s4main5ValueVyS2iGwst" to i8*), +// CHECK-SAME: i8* bitcast ({{(%swift.opaque\* \(\[[0-9]+ x i8\]\*, \[[0-9]+ x i8\]\*, %swift.type\*\)\* @"\$[a-zA-Z0-9]+" to i8\*|i8\* \(i8\*, i8\*, %swift.type\*\)\* @__swift_memcpy[0-9]+_[0-9]+ to i8\*|{ i8\*, i32, i64, i64 }\* @__swift_memcpy[0-9]+_[0-9]+.ptrauth to i8\*)}}), +// CHECK-SAME: i8* bitcast ({{[^@]*}}@__swift_noop_void_return{{[^[:space:]]* to i8\*}}), +// CHECK-SAME: i8* bitcast ({{[^@]*}}@__swift_memcpy{{[^[:space:]]+ to i8\*}}), +// CHECK-SAME: i8* bitcast ({{[^@]*}}@__swift_memcpy{{[^[:space:]]+ to i8\*}}), +// CHECK-SAME: i8* bitcast ({{[^@]*}}@__swift_memcpy{{[^[:space:]]+ to i8\*}}), +// CHECK-SAME: i8* bitcast ({{[^@]*}}@__swift_memcpy{{[^[:space:]]+ to i8\*}}), +// CHECK-SAME: i8* bitcast ({{[^@]*}}@"$s4main5ValueVyS2iGwet{{[^[:space:]]* to i8\*}}), +// CHECK-SAME: i8* bitcast ({{[^@]*}}@"$s4main5ValueVyS2iGwst{{[^[:space:]]* to i8\*}}), // CHECK-SAME: [[INT]] {{[0-9]+}}, // CHECK-SAME: [[INT]] {{[0-9]+}}, // CHECK-SAME: i32 {{[0-9]+}}, @@ -22,7 +22,7 @@ // NOTE: ignore COMDAT on PE/COFF targets // CHECK-SAME: align [[ALIGNMENT]] -// CHECK: @"$s4main5ValueVyS2iGMf" = linkonce_odr hidden constant <{ i8**, [[INT]], %swift.type_descriptor*, %swift.type*, %swift.type*, i32, i32, i64 }> <{ i8** getelementptr inbounds (%swift.vwtable, %swift.vwtable* @"$s4main5ValueVyS2iGWV", i32 0, i32 0), [[INT]] 512, %swift.type_descriptor* bitcast (<{ i32, i32, i32, i32, i32, i32, i32, i32, i32, i16, i16, i16, i16, i8, i8, i8, i8 }>* @"$s4main5ValueVMn" to %swift.type_descriptor*), %swift.type* @"$sSiN", %swift.type* @"$sSiN", i32 0, i32 [[ALIGNMENT]], i64 3 }>, align [[ALIGNMENT]] +// CHECK: @"$s4main5ValueVyS2iGMf" = linkonce_odr hidden constant {{.+}}$s4main5ValueVMn{{.+}} to %swift.type_descriptor*), %swift.type* @"$sSiN", %swift.type* @"$sSiN", i32 0, i32 [[ALIGNMENT]], i64 3 }>, align [[ALIGNMENT]] struct Value { let first: First let second: Second @@ -57,6 +57,6 @@ doit() // CHECK: [[EXIT_PRESPECIALIZED_1]]: // CHECK: ret %swift.metadata_response { %swift.type* getelementptr inbounds (%swift.full_type, %swift.full_type* bitcast (<{ i8**, [[INT]], %swift.type_descriptor*, %swift.type*, %swift.type*, i32, i32, i64 }>* @"$s4main5ValueVyS2iGMf" to %swift.full_type*), i32 0, i32 1), [[INT]] 0 } // CHECK: [[EXIT_NORMAL]]: -// CHECK: {{%[0-9]+}} = call swiftcc %swift.metadata_response @__swift_instantiateGenericMetadata([[INT]] %0, i8* [[ERASED_TYPE_1]], i8* [[ERASED_TYPE_2]], i8* undef, %swift.type_descriptor* bitcast (<{ i32, i32, i32, i32, i32, i32, i32, i32, i32, i16, i16, i16, i16, i8, i8, i8, i8 }>* @"$s4main5ValueVMn" to %swift.type_descriptor*)) #{{[0-9]+}} +// CHECK: {{%[0-9]+}} = call swiftcc %swift.metadata_response @__swift_instantiateGenericMetadata([[INT]] %0, i8* [[ERASED_TYPE_1]], i8* [[ERASED_TYPE_2]], i8* undef, %swift.type_descriptor* bitcast ({{.+}}$s4main5ValueVMn{{.+}} to %swift.type_descriptor*)) #{{[0-9]+}} // CHECK: ret %swift.metadata_response {{%[0-9]+}} // CHECK: } diff --git a/test/IRGen/prespecialized-metadata/struct-inmodule-2argument-2distinct_use.swift b/test/IRGen/prespecialized-metadata/struct-inmodule-2argument-2distinct_use.swift index 64dcda8e8f4f0..b21075d56c43c 100644 --- a/test/IRGen/prespecialized-metadata/struct-inmodule-2argument-2distinct_use.swift +++ b/test/IRGen/prespecialized-metadata/struct-inmodule-2argument-2distinct_use.swift @@ -6,14 +6,14 @@ // UNSUPPORTED: CPU=armv7s && OS=ios // CHECK: @"$s4main5ValueVySdSiGWV" = linkonce_odr hidden constant %swift.vwtable { -// CHECK-SAME: i8* bitcast ({{(%swift.opaque\* \(\[[0-9]+ x i8\]\*, \[[0-9]+ x i8\]\*, %swift.type\*\)\* @"\$[a-zA-Z0-9]+" to i8\*|i8\* \(i8\*, i8\*, %swift.type\*\)\* @__swift_memcpy[0-9]+_[0-9]+ to i8\*)}}), -// CHECK-SAME: i8* bitcast (void (i8*, %swift.type*)* @__swift_noop_void_return to i8*), -// CHECK-SAME: i8* bitcast (i8* (i8*, i8*, %swift.type*)* @__swift_memcpy{{[0-9]+}}_{{[0-9]+}} to i8*), -// CHECK-SAME: i8* bitcast (i8* (i8*, i8*, %swift.type*)* @__swift_memcpy{{[0-9]+}}_{{[0-9]+}} to i8*), -// CHECK-SAME: i8* bitcast (i8* (i8*, i8*, %swift.type*)* @__swift_memcpy{{[0-9]+}}_{{[0-9]+}} to i8*), -// CHECK-SAME: i8* bitcast (i8* (i8*, i8*, %swift.type*)* @__swift_memcpy{{[0-9]+}}_{{[0-9]+}} to i8*), -// CHECK-SAME: i8* bitcast (i32 (%swift.opaque*, i32, %swift.type*)* @"$s4main5ValueVySdSiGwet" to i8*), -// CHECK-SAME: i8* bitcast (void (%swift.opaque*, i32, i32, %swift.type*)* @"$s4main5ValueVySdSiGwst" to i8*), +// CHECK-SAME: i8* bitcast ({{(%swift.opaque\* \(\[[0-9]+ x i8\]\*, \[[0-9]+ x i8\]\*, %swift.type\*\)\* @"\$[a-zA-Z0-9]+" to i8\*|[^@]+@__swift_memcpy[^[:space:]]* to i8\*)}}), +// CHECK-SAME: i8* bitcast ({{[^@]+}}@__swift_noop_void_return{{[^[:space:]]* to i8\*}}), +// CHECK-SAME: i8* bitcast ({{[^@]+}}@__swift_memcpy{{[^[:space:]]* to i8\*}}), +// CHECK-SAME: i8* bitcast ({{[^@]+}}@__swift_memcpy{{[^[:space:]]* to i8\*}}), +// CHECK-SAME: i8* bitcast ({{[^@]+}}@__swift_memcpy{{[^[:space:]]* to i8\*}}), +// CHECK-SAME: i8* bitcast ({{[^@]+}}@__swift_memcpy{{[^[:space:]]* to i8\*}}), +// CHECK-SAME: i8* bitcast ({{[^@]+}}@"$s4main5ValueVySdSiGwet{{[^@]+}} to i8*), +// CHECK-SAME: i8* bitcast ({{[^@]+}}@"$s4main5ValueVySdSiGwst{{[^@]+}} to i8*), // CHECK-SAME: [[INT]] {{[0-9]+}}, // CHECK-SAME: [[INT]] {{[0-9]+}}, // CHECK-SAME: i32 {{[0-9]+}}, @@ -22,17 +22,17 @@ // NOTE: ignore COMDAT on PE/COFF targets // CHECK-SAME: align [[ALIGNMENT]] -// CHECK: @"$s4main5ValueVySdSiGMf" = linkonce_odr hidden constant <{ i8**, [[INT]], %swift.type_descriptor*, %swift.type*, %swift.type*, i32, i32, i64 }> <{ i8** getelementptr inbounds (%swift.vwtable, %swift.vwtable* @"$s4main5ValueVySdSiGWV", i32 0, i32 0), [[INT]] 512, %swift.type_descriptor* bitcast (<{ i32, i32, i32, i32, i32, i32, i32, i32, i32, i16, i16, i16, i16, i8, i8, i8, i8 }>* @"$s4main5ValueVMn" to %swift.type_descriptor*), %swift.type* @"$sSdN", %swift.type* @"$sSiN", i32 0, i32 8, i64 3 }>, align [[ALIGNMENT]] +// CHECK: @"$s4main5ValueVySdSiGMf" = linkonce_odr hidden constant {{.+}}$s4main5ValueVMn{{.+}} to %swift.type_descriptor*), %swift.type* @"$sSdN", %swift.type* @"$sSiN", i32 0, i32 8, i64 3 }>, align [[ALIGNMENT]] // CHECK: @"$s4main5ValueVyS2iGWV" = linkonce_odr hidden constant %swift.vwtable { -// CHECK-SAME: i8* bitcast ({{(%swift.opaque\* \(\[[0-9]+ x i8\]\*, \[[0-9]+ x i8\]\*, %swift.type\*\)\* @"\$[a-zA-Z0-9]+" to i8\*|i8\* \(i8\*, i8\*, %swift.type\*\)\* @__swift_memcpy[0-9]+_[0-9]+ to i8\*)}}), -// CHECK-SAME: i8* bitcast (void (i8*, %swift.type*)* @__swift_noop_void_return to i8*), -// CHECK-SAME: i8* bitcast (i8* (i8*, i8*, %swift.type*)* @__swift_memcpy{{[0-9]+}}_{{[0-9]+}} to i8*), -// CHECK-SAME: i8* bitcast (i8* (i8*, i8*, %swift.type*)* @__swift_memcpy{{[0-9]+}}_{{[0-9]+}} to i8*), -// CHECK-SAME: i8* bitcast (i8* (i8*, i8*, %swift.type*)* @__swift_memcpy{{[0-9]+}}_{{[0-9]+}} to i8*), -// CHECK-SAME: i8* bitcast (i8* (i8*, i8*, %swift.type*)* @__swift_memcpy{{[0-9]+}}_{{[0-9]+}} to i8*), -// CHECK-SAME: i8* bitcast (i32 (%swift.opaque*, i32, %swift.type*)* @"$s4main5ValueVyS2iGwet" to i8*), -// CHECK-SAME: i8* bitcast (void (%swift.opaque*, i32, i32, %swift.type*)* @"$s4main5ValueVyS2iGwst" to i8*), +// CHECK-SAME: i8* bitcast ({{(%swift.opaque\* \(\[[0-9]+ x i8\]\*, \[[0-9]+ x i8\]\*, %swift.type\*\)\* @"\$[a-zA-Z0-9]+" to i8\*|[^@]+@__swift_memcpy[^[:space:]]* to i8\*)}}), +// CHECK-SAME: i8* bitcast ({{[^@]*}}@__swift_noop_void_return{{[^[:space:]]* to i8\*}}), +// CHECK-SAME: i8* bitcast ({{[^@]+}}@__swift_memcpy{{[^[:space:]]* to i8\*}}), +// CHECK-SAME: i8* bitcast ({{[^@]+}}@__swift_memcpy{{[^[:space:]]* to i8\*}}), +// CHECK-SAME: i8* bitcast ({{[^@]+}}@__swift_memcpy{{[^[:space:]]* to i8\*}}), +// CHECK-SAME: i8* bitcast ({{[^@]+}}@__swift_memcpy{{[^[:space:]]* to i8\*}}), +// CHECK-SAME: i8* bitcast ({{[^@]+}}@"$s4main5ValueVyS2iGwet{{[^@]+}} to i8*), +// CHECK-SAME: i8* bitcast ({{[^@]+}}@"$s4main5ValueVyS2iGwst{{[^@]+}} to i8*), // CHECK-SAME: [[INT]] {{[0-9]+}}, // CHECK-SAME: [[INT]] {{[0-9]+}}, // CHECK-SAME: i32 {{[0-9]+}}, @@ -41,7 +41,7 @@ // NOTE: ignore COMDAT on PE/COFF targets // CHECK-SAME: align [[ALIGNMENT]] -// CHECK: @"$s4main5ValueVyS2iGMf" = linkonce_odr hidden constant <{ i8**, [[INT]], %swift.type_descriptor*, %swift.type*, %swift.type*, i32, i32, i64 }> <{ i8** getelementptr inbounds (%swift.vwtable, %swift.vwtable* @"$s4main5ValueVyS2iGWV", i32 0, i32 0), [[INT]] 512, %swift.type_descriptor* bitcast (<{ i32, i32, i32, i32, i32, i32, i32, i32, i32, i16, i16, i16, i16, i8, i8, i8, i8 }>* @"$s4main5ValueVMn" to %swift.type_descriptor*), %swift.type* @"$sSiN", %swift.type* @"$sSiN", i32 0, i32 [[ALIGNMENT]], i64 3 }>, align [[ALIGNMENT]] +// CHECK: @"$s4main5ValueVyS2iGMf" = linkonce_odr hidden constant {{.+}}$s4main5ValueVMn{{.+}} to %swift.type_descriptor*), %swift.type* @"$sSiN", %swift.type* @"$sSiN", i32 0, i32 [[ALIGNMENT]], i64 3 }>, align [[ALIGNMENT]] struct Value { let first: First let second: Second @@ -86,6 +86,6 @@ doit() // CHECK: [[EXIT_PRESPECIALIZED_2]]: // CHECK: ret %swift.metadata_response { %swift.type* getelementptr inbounds (%swift.full_type, %swift.full_type* bitcast (<{ i8**, [[INT]], %swift.type_descriptor*, %swift.type*, %swift.type*, i32, i32, i64 }>* @"$s4main5ValueVySdSiGMf" to %swift.full_type*), i32 0, i32 1), [[INT]] 0 } // CHECK: [[EXIT_NORMAL]]: -// CHECK: {{%[0-9]+}} = call swiftcc %swift.metadata_response @__swift_instantiateGenericMetadata([[INT]] %0, i8* [[ERASED_TYPE_1]], i8* [[ERASED_TYPE_2]], i8* undef, %swift.type_descriptor* bitcast (<{ i32, i32, i32, i32, i32, i32, i32, i32, i32, i16, i16, i16, i16, i8, i8, i8, i8 }>* @"$s4main5ValueVMn" to %swift.type_descriptor*)) #{{[0-9]+}} +// CHECK: {{%[0-9]+}} = call swiftcc %swift.metadata_response @__swift_instantiateGenericMetadata([[INT]] %0, i8* [[ERASED_TYPE_1]], i8* [[ERASED_TYPE_2]], i8* undef, %swift.type_descriptor* bitcast ({{.+}}$s4main5ValueVMn{{.+}} to %swift.type_descriptor*)) #{{[0-9]+}} // CHECK: ret %swift.metadata_response {{%[0-9]+}} // CHECK: } diff --git a/test/IRGen/prespecialized-metadata/struct-inmodule-2argument-3distinct_use.swift b/test/IRGen/prespecialized-metadata/struct-inmodule-2argument-3distinct_use.swift index 8f13ae6002add..31fce124fd51f 100644 --- a/test/IRGen/prespecialized-metadata/struct-inmodule-2argument-3distinct_use.swift +++ b/test/IRGen/prespecialized-metadata/struct-inmodule-2argument-3distinct_use.swift @@ -6,14 +6,14 @@ // UNSUPPORTED: CPU=armv7s && OS=ios // CHECK: @"$s4main5ValueVySSSdGWV" = linkonce_odr hidden constant %swift.vwtable { -// CHECK-SAME: i8* bitcast (%swift.opaque* ([{{[0-9]+}} x i8]*, [{{[0-9]+}} x i8]*, %swift.type*)* @"$s4main5ValueVySSSdGwCP" to i8*), -// CHECK-SAME: i8* bitcast (void (%swift.opaque*, %swift.type*)* @"$s4main5ValueVySSSdGwxx" to i8*), -// CHECK-SAME: i8* bitcast (%swift.opaque* (%swift.opaque*, %swift.opaque*, %swift.type*)* @"$s4main5ValueVySSSdGwcp" to i8*), -// CHECK-SAME: i8* bitcast (%swift.opaque* (%swift.opaque*, %swift.opaque*, %swift.type*)* @"$s4main5ValueVySSSdGwca" to i8*), -// CHECK-SAME: i8* bitcast (i8* (i8*, i8*, %swift.type*)* @__swift_memcpy{{[0-9]+}}_{{[0-9]+}} to i8*), -// CHECK-SAME: i8* bitcast (%swift.opaque* (%swift.opaque*, %swift.opaque*, %swift.type*)* @"$s4main5ValueVySSSdGwta" to i8*), -// CHECK-SAME: i8* bitcast (i32 (%swift.opaque*, i32, %swift.type*)* @"$s4main5ValueVySSSdGwet" to i8*), -// CHECK-SAME: i8* bitcast (void (%swift.opaque*, i32, i32, %swift.type*)* @"$s4main5ValueVySSSdGwst" to i8*), +// CHECK-SAME: i8* bitcast ({{[^@]+}}@"$s4main5ValueVySSSdGwCP{{[^@]+}} to i8*), +// CHECK-SAME: i8* bitcast ({{[^@]+}}@"$s4main5ValueVySSSdGwxx{{[^@]+}} to i8*), +// CHECK-SAME: i8* bitcast ({{[^@]+}}@"$s4main5ValueVySSSdGwcp{{[^@]+}} to i8*), +// CHECK-SAME: i8* bitcast ({{[^@]+}}@"$s4main5ValueVySSSdGwca{{[^@]+}} to i8*), +// CHECK-SAME: i8* bitcast ({{[^@]+}}@__swift_memcpy{{[^[:space:]]* to i8\*}}), +// CHECK-SAME: i8* bitcast ({{[^@]+}}@"$s4main5ValueVySSSdGwta{{[^@]+}} to i8*), +// CHECK-SAME: i8* bitcast ({{[^@]+}}@"$s4main5ValueVySSSdGwet{{[^@]+}} to i8*), +// CHECK-SAME: i8* bitcast ({{[^@]+}}@"$s4main5ValueVySSSdGwst{{[^@]+}} to i8*), // CHECK-SAME: [[INT]] {{[0-9]+}}, // CHECK-SAME: [[INT]] {{[0-9]+}}, // CHECK-SAME: i32 {{[0-9]+}}, @@ -22,17 +22,17 @@ // NOTE: ignore COMDAT on PE/COFF targets // CHECK-SAME: align [[ALIGNMENT]] -// CHECK: @"$s4main5ValueVySSSdGMf" = linkonce_odr hidden constant <{ i8**, [[INT]], %swift.type_descriptor*, %swift.type*, %swift.type*, i32, i32, i64 }> <{ i8** getelementptr inbounds (%swift.vwtable, %swift.vwtable* @"$s4main5ValueVySSSdGWV", i32 0, i32 0), [[INT]] 512, %swift.type_descriptor* bitcast (<{ i32, i32, i32, i32, i32, i32, i32, i32, i32, i16, i16, i16, i16, i8, i8, i8, i8 }>* @"$s4main5ValueVMn" to %swift.type_descriptor*), %swift.type* @"$sSSN", %swift.type* @"$sSdN", i32 0, i32 16, i64 3 }>, align [[ALIGNMENT]] +// CHECK: @"$s4main5ValueVySSSdGMf" = linkonce_odr hidden constant {{.+}}$s4main5ValueVMn{{.+}} to %swift.type_descriptor*), %swift.type* @"$sSSN", %swift.type* @"$sSdN", i32 0, i32 16, i64 3 }>, align [[ALIGNMENT]] // CHECK: @"$s4main5ValueVySdSiGWV" = linkonce_odr hidden constant %swift.vwtable { -// CHECK-SAME: i8* bitcast ({{(%swift.opaque\* \(\[[0-9]+ x i8\]\*, \[[0-9]+ x i8\]\*, %swift.type\*\)\* @"\$[a-zA-Z0-9]+" to i8\*|i8\* \(i8\*, i8\*, %swift.type\*\)\* @__swift_memcpy[0-9]+_[0-9]+ to i8\*)}}), -// CHECK-SAME: i8* bitcast (void (i8*, %swift.type*)* @__swift_noop_void_return to i8*), -// CHECK-SAME: i8* bitcast (i8* (i8*, i8*, %swift.type*)* @__swift_memcpy{{[0-9]+}}_{{[0-9]+}} to i8*), -// CHECK-SAME: i8* bitcast (i8* (i8*, i8*, %swift.type*)* @__swift_memcpy{{[0-9]+}}_{{[0-9]+}} to i8*), -// CHECK-SAME: i8* bitcast (i8* (i8*, i8*, %swift.type*)* @__swift_memcpy{{[0-9]+}}_{{[0-9]+}} to i8*), -// CHECK-SAME: i8* bitcast (i8* (i8*, i8*, %swift.type*)* @__swift_memcpy{{[0-9]+}}_{{[0-9]+}} to i8*), -// CHECK-SAME: i8* bitcast (i32 (%swift.opaque*, i32, %swift.type*)* @"$s4main5ValueVySdSiGwet" to i8*), -// CHECK-SAME: i8* bitcast (void (%swift.opaque*, i32, i32, %swift.type*)* @"$s4main5ValueVySdSiGwst" to i8*), +// CHECK-SAME: i8* bitcast ({{(%swift.opaque\* \(\[[0-9]+ x i8\]\*, \[[0-9]+ x i8\]\*, %swift.type\*\)\* @"\$[a-zA-Z0-9]+" to i8\*|[^@]+@__swift_memcpy[^[:space:]]* to i8\*)}}), +// CHECK-SAME: i8* bitcast ({{[^@]*}}@__swift_noop_void_return{{[^[:space:]]* to i8\*}}), +// CHECK-SAME: i8* bitcast ({{[^@]+}}@__swift_memcpy{{[^[:space:]]* to i8\*}}), +// CHECK-SAME: i8* bitcast ({{[^@]+}}@__swift_memcpy{{[^[:space:]]* to i8\*}}), +// CHECK-SAME: i8* bitcast ({{[^@]+}}@__swift_memcpy{{[^[:space:]]* to i8\*}}), +// CHECK-SAME: i8* bitcast ({{[^@]+}}@__swift_memcpy{{[^[:space:]]* to i8\*}}), +// CHECK-SAME: i8* bitcast ({{[^@]+}}@"$s4main5ValueVy{{[^[:space:]]* to i8\*}}), +// CHECK-SAME: i8* bitcast ({{[^@]+}}@"$s4main5ValueVy{{[^[:space:]]* to i8\*}}), // CHECK-SAME: [[INT]] {{[0-9]+}}, // CHECK-SAME: [[INT]] {{[0-9]+}}, // CHECK-SAME: i32 {{[0-9]+}}, @@ -41,17 +41,17 @@ // NOTE: ignore COMDAT on PE/COFF targets // CHECK-SAME: align [[ALIGNMENT]] -// CHECK: @"$s4main5ValueVySdSiGMf" = linkonce_odr hidden constant <{ i8**, [[INT]], %swift.type_descriptor*, %swift.type*, %swift.type*, i32, i32, i64 }> <{ i8** getelementptr inbounds (%swift.vwtable, %swift.vwtable* @"$s4main5ValueVySdSiGWV", i32 0, i32 0), [[INT]] 512, %swift.type_descriptor* bitcast (<{ i32, i32, i32, i32, i32, i32, i32, i32, i32, i16, i16, i16, i16, i8, i8, i8, i8 }>* @"$s4main5ValueVMn" to %swift.type_descriptor*), %swift.type* @"$sSdN", %swift.type* @"$sSiN", i32 0, i32 8, i64 3 }>, align [[ALIGNMENT]] +// CHECK: @"$s4main5ValueVySdSiGMf" = linkonce_odr hidden constant {{.+}}$s4main5ValueVMn{{.+}} to %swift.type_descriptor*), %swift.type* @"$sSdN", %swift.type* @"$sSiN", i32 0, i32 8, i64 3 }>, align [[ALIGNMENT]] // CHECK: @"$s4main5ValueVyS2iGWV" = linkonce_odr hidden constant %swift.vwtable { -// CHECK-SAME: i8* bitcast ({{(%swift.opaque\* \(\[[0-9]+ x i8\]\*, \[[0-9]+ x i8\]\*, %swift.type\*\)\* @"\$[a-zA-Z0-9]+" to i8\*|i8\* \(i8\*, i8\*, %swift.type\*\)\* @__swift_memcpy[0-9]+_[0-9]+ to i8\*)}}), -// CHECK-SAME: i8* bitcast (void (i8*, %swift.type*)* @__swift_noop_void_return to i8*), -// CHECK-SAME: i8* bitcast (i8* (i8*, i8*, %swift.type*)* @__swift_memcpy{{[0-9]+}}_{{[0-9]+}} to i8*), -// CHECK-SAME: i8* bitcast (i8* (i8*, i8*, %swift.type*)* @__swift_memcpy{{[0-9]+}}_{{[0-9]+}} to i8*), -// CHECK-SAME: i8* bitcast (i8* (i8*, i8*, %swift.type*)* @__swift_memcpy{{[0-9]+}}_{{[0-9]+}} to i8*), -// CHECK-SAME: i8* bitcast (i8* (i8*, i8*, %swift.type*)* @__swift_memcpy{{[0-9]+}}_{{[0-9]+}} to i8*), -// CHECK-SAME: i8* bitcast (i32 (%swift.opaque*, i32, %swift.type*)* @"$s4main5ValueVyS2iGwet" to i8*), -// CHECK-SAME: i8* bitcast (void (%swift.opaque*, i32, i32, %swift.type*)* @"$s4main5ValueVyS2iGwst" to i8*), +// CHECK-SAME: i8* bitcast ({{(%swift.opaque\* \(\[[0-9]+ x i8\]\*, \[[0-9]+ x i8\]\*, %swift.type\*\)\* @"\$[a-zA-Z0-9]+" to i8\*|[^@]+@__swift_memcpy[^[:space:]]* to i8\*)}}), +// CHECK-SAME: i8* bitcast ({{[^@]*}}@__swift_noop_void_return{{[^[:space:]]* to i8\*}}), +// CHECK-SAME: i8* bitcast ({{[^@]+}}@__swift_memcpy{{[^[:space:]]* to i8\*}}), +// CHECK-SAME: i8* bitcast ({{[^@]+}}@__swift_memcpy{{[^[:space:]]* to i8\*}}), +// CHECK-SAME: i8* bitcast ({{[^@]+}}@__swift_memcpy{{[^[:space:]]* to i8\*}}), +// CHECK-SAME: i8* bitcast ({{[^@]+}}@__swift_memcpy{{[^[:space:]]* to i8\*}}), +// CHECK-SAME: i8* bitcast ({{[^@]+}}@"$s4main5ValueVyS2iGwet{{[^@]+}} to i8*), +// CHECK-SAME: i8* bitcast ({{[^@]+}}@"$s4main5ValueVyS2iGwst{{[^@]+}} to i8*), // CHECK-SAME: [[INT]] {{[0-9]+}}, // CHECK-SAMEL [[INT]] {{[0-9]+}}, // CHECK-SAME: i32 {{[0-9]+}}, @@ -60,7 +60,7 @@ // NOTE: ignore COMDAT on PE/COFF targets // CHECK-SAME: align [[ALIGNMENT]] -// CHECK: @"$s4main5ValueVyS2iGMf" = linkonce_odr hidden constant <{ i8**, [[INT]], %swift.type_descriptor*, %swift.type*, %swift.type*, i32, i32, i64 }> <{ i8** getelementptr inbounds (%swift.vwtable, %swift.vwtable* @"$s4main5ValueVyS2iGWV", i32 0, i32 0), [[INT]] 512, %swift.type_descriptor* bitcast (<{ i32, i32, i32, i32, i32, i32, i32, i32, i32, i16, i16, i16, i16, i8, i8, i8, i8 }>* @"$s4main5ValueVMn" to %swift.type_descriptor*), %swift.type* @"$sSiN", %swift.type* @"$sSiN", i32 0, i32 [[ALIGNMENT]], i64 3 }>, align [[ALIGNMENT]] +// CHECK: @"$s4main5ValueVyS2iGMf" = linkonce_odr hidden constant {{.+}}$s4main5ValueVMn{{.+}} to %swift.type_descriptor*), %swift.type* @"$sSiN", %swift.type* @"$sSiN", i32 0, i32 [[ALIGNMENT]], i64 3 }>, align [[ALIGNMENT]] struct Value { let first: First let second: Second @@ -115,6 +115,6 @@ doit() // CHECK: [[EXIT_PRESPECIALIZED_3]]: // CHECK: ret %swift.metadata_response { %swift.type* getelementptr inbounds (%swift.full_type, %swift.full_type* bitcast (<{ i8**, [[INT]], %swift.type_descriptor*, %swift.type*, %swift.type*, i32, i32, i64 }>* @"$s4main5ValueVySSSdGMf" to %swift.full_type*), i32 0, i32 1), [[INT]] 0 } // CHECK: [[EXIT_NORMAL]]: -// CHECK: {{%[0-9]+}} = call swiftcc %swift.metadata_response @__swift_instantiateGenericMetadata([[INT]] %0, i8* [[ERASED_TYPE_1]], i8* [[ERASED_TYPE_2]], i8* undef, %swift.type_descriptor* bitcast (<{ i32, i32, i32, i32, i32, i32, i32, i32, i32, i16, i16, i16, i16, i8, i8, i8, i8 }>* @"$s4main5ValueVMn" to %swift.type_descriptor*)) #{{[0-9]+}} +// CHECK: {{%[0-9]+}} = call swiftcc %swift.metadata_response @__swift_instantiateGenericMetadata([[INT]] %0, i8* [[ERASED_TYPE_1]], i8* [[ERASED_TYPE_2]], i8* undef, %swift.type_descriptor* bitcast ({{.+}}$s4main5ValueVMn{{.+}} to %swift.type_descriptor*)) #{{[0-9]+}} // CHECK: ret %swift.metadata_response {{%[0-9]+}} // CHECK: } diff --git a/test/IRGen/prespecialized-metadata/struct-inmodule-2argument-4distinct_use.swift b/test/IRGen/prespecialized-metadata/struct-inmodule-2argument-4distinct_use.swift index 3fc64b98d1e8d..4a151bbe6db25 100644 --- a/test/IRGen/prespecialized-metadata/struct-inmodule-2argument-4distinct_use.swift +++ b/test/IRGen/prespecialized-metadata/struct-inmodule-2argument-4distinct_use.swift @@ -6,14 +6,14 @@ // UNSUPPORTED: CPU=armv7s && OS=ios // CHECK: @"$s4main5ValueVys5UInt8VSSGWV" = linkonce_odr hidden constant %swift.vwtable { -// CHECK-SAME: i8* bitcast (%swift.opaque* ([{{[0-9]+}} x i8]*, [{{[0-9]+}} x i8]*, %swift.type*)* @"$s4main5ValueVys5UInt8VSSGwCP" to i8*), -// CHECK-SAME: i8* bitcast (void (%swift.opaque*, %swift.type*)* @"$s4main5ValueVys5UInt8VSSGwxx" to i8*), -// CHECK-SAME: i8* bitcast (%swift.opaque* (%swift.opaque*, %swift.opaque*, %swift.type*)* @"$s4main5ValueVys5UInt8VSSGwcp" to i8*), -// CHECK-SAME: i8* bitcast (%swift.opaque* (%swift.opaque*, %swift.opaque*, %swift.type*)* @"$s4main5ValueVys5UInt8VSSGwca" to i8*), -// CHECK-SAME: i8* bitcast (i8* (i8*, i8*, %swift.type*)* @__swift_memcpy{{[0-9]+}}_{{[0-9]+}} to i8*), -// CHECK-SAME: i8* bitcast (%swift.opaque* (%swift.opaque*, %swift.opaque*, %swift.type*)* @"$s4main5ValueVys5UInt8VSSGwta" to i8*), -// CHECK-SAME: i8* bitcast (i32 (%swift.opaque*, i32, %swift.type*)* @"$s4main5ValueVys5UInt8VSSGwet" to i8*), -// CHECK-SAME: i8* bitcast (void (%swift.opaque*, i32, i32, %swift.type*)* @"$s4main5ValueVys5UInt8VSSGwst" to i8*), +// CHECK-SAME: i8* bitcast ({{[^@]+}}@"$s4main5ValueVys5UInt8VSSGwCP{{[^@]+}} to i8*), +// CHECK-SAME: i8* bitcast ({{[^@]+}}@"$s4main5ValueVys5UInt8VSSGwxx{{[^@]+}} to i8*), +// CHECK-SAME: i8* bitcast ({{[^@]+}}@"$s4main5ValueVys5UInt8VSSGwcp{{[^@]+}} to i8*), +// CHECK-SAME: i8* bitcast ({{[^@]+}}@"$s4main5ValueVys5UInt8VSSGwca{{[^@]+}} to i8*), +// CHECK-SAME: i8* bitcast ({{[^@]+}}@__swift_memcpy{{[^[:space:]]* to i8\*}}), +// CHECK-SAME: i8* bitcast ({{[^@]+}}@"$s4main5ValueVys5UInt8VSSGwta{{[^@]+}} to i8*), +// CHECK-SAME: i8* bitcast ({{[^@]+}}@"$s4main5ValueVys5UInt8VSSGwet{{[^@]+}} to i8*), +// CHECK-SAME: i8* bitcast ({{[^@]+}}@"$s4main5ValueVys5UInt8VSSGwst{{[^@]+}} to i8*), // CHECK-SAME: [[INT]] {{[0-9]+}}, // CHECK-SAME: [[INT]] {{[0-9]+}}, // CHECK-SAME: i32 {{[0-9]+}}, @@ -22,17 +22,17 @@ // NOTE: ignore COMDAT on PE/COFF targets // CHECK-SAME: align [[ALIGNMENT]] -// CHECK: @"$s4main5ValueVys5UInt8VSSGMf" = linkonce_odr hidden constant <{ i8**, [[INT]], %swift.type_descriptor*, %swift.type*, %swift.type*, i32, i32, i64 }> <{ i8** getelementptr inbounds (%swift.vwtable, %swift.vwtable* @"$s4main5ValueVys5UInt8VSSGWV", i32 0, i32 0), [[INT]] 512, %swift.type_descriptor* bitcast (<{ i32, i32, i32, i32, i32, i32, i32, i32, i32, i16, i16, i16, i16, i8, i8, i8, i8 }>* @"$s4main5ValueVMn" to %swift.type_descriptor*), %swift.type* @"$ss5UInt8VN", %swift.type* @"$sSSN", i32 0, i32 [[ALIGNMENT]], i64 3 }>, align [[ALIGNMENT]] +// CHECK: @"$s4main5ValueVys5UInt8VSSGMf" = linkonce_odr hidden constant {{.+}}$s4main5ValueVMn{{.+}} to %swift.type_descriptor*), %swift.type* @"$ss5UInt8VN", %swift.type* @"$sSSN", i32 0, i32 [[ALIGNMENT]], i64 3 }>, align [[ALIGNMENT]] // CHECK: @"$s4main5ValueVySSSdGWV" = linkonce_odr hidden constant %swift.vwtable { -// CHECK-SAME: i8* bitcast (%swift.opaque* ([{{[0-9]+}} x i8]*, [{{[0-9]+}} x i8]*, %swift.type*)* @"$s4main5ValueVySSSdGwCP" to i8*), -// CHECK-SAME: i8* bitcast (void (%swift.opaque*, %swift.type*)* @"$s4main5ValueVySSSdGwxx" to i8*), -// CHECK-SAME: i8* bitcast (%swift.opaque* (%swift.opaque*, %swift.opaque*, %swift.type*)* @"$s4main5ValueVySSSdGwcp" to i8*), -// CHECK-SAME: i8* bitcast (%swift.opaque* (%swift.opaque*, %swift.opaque*, %swift.type*)* @"$s4main5ValueVySSSdGwca" to i8*), -// CHECK-SAME: i8* bitcast (i8* (i8*, i8*, %swift.type*)* @__swift_memcpy{{[0-9]+}}_{{[0-9]+}} to i8*), -// CHECK-SAME: i8* bitcast (%swift.opaque* (%swift.opaque*, %swift.opaque*, %swift.type*)* @"$s4main5ValueVySSSdGwta" to i8*), -// CHECK-SAME: i8* bitcast (i32 (%swift.opaque*, i32, %swift.type*)* @"$s4main5ValueVySSSdGwet" to i8*), -// CHECK-SAME: i8* bitcast (void (%swift.opaque*, i32, i32, %swift.type*)* @"$s4main5ValueVySSSdGwst" to i8*), +// CHECK-SAME: i8* bitcast ({{[^@]+}}@"$s4main5ValueVySSSdGwCP{{[^@]+}} to i8*), +// CHECK-SAME: i8* bitcast ({{[^@]+}}@"$s4main5ValueVySSSdGwxx{{[^@]+}} to i8*), +// CHECK-SAME: i8* bitcast ({{[^@]+}}@"$s4main5ValueVySSSdGwcp{{[^@]+}} to i8*), +// CHECK-SAME: i8* bitcast ({{[^@]+}}@"$s4main5ValueVySSSdGwca{{[^@]+}} to i8*), +// CHECK-SAME: i8* bitcast ({{[^@]+}}@__swift_memcpy{{[^[:space:]]* to i8\*}}), +// CHECK-SAME: i8* bitcast ({{[^@]+}}@"$s4main5ValueVySSSdGwta{{[^@]+}} to i8*), +// CHECK-SAME: i8* bitcast ({{[^@]+}}@"$s4main5ValueVySSSdGwet{{[^@]+}} to i8*), +// CHECK-SAME: i8* bitcast ({{[^@]+}}@"$s4main5ValueVySSSdGwst{{[^@]+}} to i8*), // CHECK-SAME: [[INT]] {{[0-9]+}}, // CHECK-SAME: [[INT]] {{[0-9]+}}, // CHECK-SAME: i32 {{[0-9]+}}, @@ -41,17 +41,17 @@ // NOTE: ignore COMDAT on PE/COFF targets // CHECK-SAME: align [[ALIGNMENT]] -// CHECK: @"$s4main5ValueVySSSdGMf" = linkonce_odr hidden constant <{ i8**, [[INT]], %swift.type_descriptor*, %swift.type*, %swift.type*, i32, i32, i64 }> <{ i8** getelementptr inbounds (%swift.vwtable, %swift.vwtable* @"$s4main5ValueVySSSdGWV", i32 0, i32 0), [[INT]] 512, %swift.type_descriptor* bitcast (<{ i32, i32, i32, i32, i32, i32, i32, i32, i32, i16, i16, i16, i16, i8, i8, i8, i8 }>* @"$s4main5ValueVMn" to %swift.type_descriptor*), %swift.type* @"$sSSN", %swift.type* @"$sSdN", i32 0, i32 16, i64 3 }>, align [[ALIGNMENT]] +// CHECK: @"$s4main5ValueVySSSdGMf" = linkonce_odr hidden constant {{.+}}$s4main5ValueVMn{{.+}} to %swift.type_descriptor*), %swift.type* @"$sSSN", %swift.type* @"$sSdN", i32 0, i32 16, i64 3 }>, align [[ALIGNMENT]] // CHECK: @"$s4main5ValueVySdSiGWV" = linkonce_odr hidden constant %swift.vwtable { -// CHECK-SAME: i8* bitcast ({{(%swift.opaque\* \(\[[0-9]+ x i8\]\*, \[[0-9]+ x i8\]\*, %swift.type\*\)\* @"\$[a-zA-Z0-9_]+" to i8\*|i8\* \(i8\*, i8\*, %swift.type\*\)\* @__swift_memcpy[0-9]+_[0-9]+ to i8\*)}}), -// CHECK-SAME: i8* bitcast (void (i8*, %swift.type*)* @__swift_noop_void_return to i8*), -// CHECK-SAME: i8* bitcast (i8* (i8*, i8*, %swift.type*)* @__swift_memcpy{{[0-9]+}}_{{[0-9]+}} to i8*), -// CHECK-SAME: i8* bitcast (i8* (i8*, i8*, %swift.type*)* @__swift_memcpy{{[0-9]+}}_{{[0-9]+}} to i8*), -// CHECK-SAME: i8* bitcast (i8* (i8*, i8*, %swift.type*)* @__swift_memcpy{{[0-9]+}}_{{[0-9]+}} to i8*), -// CHECK-SAME: i8* bitcast (i8* (i8*, i8*, %swift.type*)* @__swift_memcpy{{[0-9]+}}_{{[0-9]+}} to i8*), -// CHECK-SAME: i8* bitcast (i32 (%swift.opaque*, i32, %swift.type*)* @"$s4main5ValueVySdSiGwet" to i8*), -// CHECK-SAME: i8* bitcast (void (%swift.opaque*, i32, i32, %swift.type*)* @"$s4main5ValueVySdSiGwst" to i8*), +// CHECK-SAME: i8* bitcast ({{(%swift.opaque\* \(\[[0-9]+ x i8\]\*, \[[0-9]+ x i8\]\*, %swift.type\*\)\* @"\$[a-zA-Z0-9_]+" to i8\*|[^@]+@__swift_memcpy[^[:space:]]* to i8\*)}}), +// CHECK-SAME: i8* bitcast ({{[^@]*}}@__swift_noop_void_return{{[^[:space:]]* to i8\*}}), +// CHECK-SAME: i8* bitcast ({{[^@]+}}@__swift_memcpy{{[^[:space:]]* to i8\*}}), +// CHECK-SAME: i8* bitcast ({{[^@]+}}@__swift_memcpy{{[^[:space:]]* to i8\*}}), +// CHECK-SAME: i8* bitcast ({{[^@]+}}@__swift_memcpy{{[^[:space:]]* to i8\*}}), +// CHECK-SAME: i8* bitcast ({{[^@]+}}@__swift_memcpy{{[^[:space:]]* to i8\*}}), +// CHECK-SAME: i8* bitcast ({{[^@]+}}@"$s4main5ValueVySdSiGwet{{[^@]+}} to i8*), +// CHECK-SAME: i8* bitcast ({{[^@]+}}@"$s4main5ValueVySdSiGwst{{[^@]+}} to i8*), // CHECK-SAME: [[INT]] {{[0-9]+}}, // CHECK-SAME: [[INT]] {{[0-9]+}}, // CHECK-SAME: i32 {{[0-9]+}}, @@ -60,17 +60,17 @@ // NOTE: ignore COMDAT on PE/COFF targets // CHECK-SAME: align [[ALIGNMENT]] -// CHECK: @"$s4main5ValueVySdSiGMf" = linkonce_odr hidden constant <{ i8**, [[INT]], %swift.type_descriptor*, %swift.type*, %swift.type*, i32, i32, i64 }> <{ i8** getelementptr inbounds (%swift.vwtable, %swift.vwtable* @"$s4main5ValueVySdSiGWV", i32 0, i32 0), [[INT]] 512, %swift.type_descriptor* bitcast (<{ i32, i32, i32, i32, i32, i32, i32, i32, i32, i16, i16, i16, i16, i8, i8, i8, i8 }>* @"$s4main5ValueVMn" to %swift.type_descriptor*), %swift.type* @"$sSdN", %swift.type* @"$sSiN", i32 0, i32 8, i64 3 }>, align [[ALIGNMENT]] +// CHECK: @"$s4main5ValueVySdSiGMf" = linkonce_odr hidden constant {{.+}}$s4main5ValueVMn{{.+}} to %swift.type_descriptor*), %swift.type* @"$sSdN", %swift.type* @"$sSiN", i32 0, i32 8, i64 3 }>, align [[ALIGNMENT]] // CHECK: @"$s4main5ValueVyS2iGWV" = linkonce_odr hidden constant %swift.vwtable { -// CHECK-SAME: i8* bitcast ({{(%swift.opaque\* \(\[[0-9]+ x i8\]\*, \[[0-9]+ x i8\]\*, %swift.type\*\)\* @"\$[a-zA-Z0-9_]+" to i8\*|i8\* \(i8\*, i8\*, %swift.type\*\)\* @__swift_memcpy[0-9]+_[0-9]+ to i8\*)}}), -// CHECK-SAME: i8* bitcast (void (i8*, %swift.type*)* @__swift_noop_void_return to i8*), -// CHECK-SAME: i8* bitcast (i8* (i8*, i8*, %swift.type*)* @__swift_memcpy{{[0-9]+}}_{{[0-9]+}} to i8*), -// CHECK-SAME: i8* bitcast (i8* (i8*, i8*, %swift.type*)* @__swift_memcpy{{[0-9]+}}_{{[0-9]+}} to i8*), -// CHECK-SAME: i8* bitcast (i8* (i8*, i8*, %swift.type*)* @__swift_memcpy{{[0-9]+}}_{{[0-9]+}} to i8*), -// CHECK-SAME: i8* bitcast (i8* (i8*, i8*, %swift.type*)* @__swift_memcpy{{[0-9]+}}_{{[0-9]+}} to i8*), -// CHECK-SAME: i8* bitcast (i32 (%swift.opaque*, i32, %swift.type*)* @"$s4main5ValueVyS2iGwet" to i8*), -// CHECK-SAME: i8* bitcast (void (%swift.opaque*, i32, i32, %swift.type*)* @"$s4main5ValueVyS2iGwst" to i8*), +// CHECK-SAME: i8* bitcast ({{(%swift.opaque\* \(\[[0-9]+ x i8\]\*, \[[0-9]+ x i8\]\*, %swift.type\*\)\* @"\$[a-zA-Z0-9_]+" to i8\*|[^@]+@__swift_memcpy[^[:space:]]* to i8\*)}}), +// CHECK-SAME: i8* bitcast ({{[^@]*}}@__swift_noop_void_return{{[^[:space:]]* to i8\*}}), +// CHECK-SAME: i8* bitcast ({{[^@]+}}@__swift_memcpy{{[^[:space:]]* to i8\*}}), +// CHECK-SAME: i8* bitcast ({{[^@]+}}@__swift_memcpy{{[^[:space:]]* to i8\*}}), +// CHECK-SAME: i8* bitcast ({{[^@]+}}@__swift_memcpy{{[^[:space:]]* to i8\*}}), +// CHECK-SAME: i8* bitcast ({{[^@]+}}@__swift_memcpy{{[^[:space:]]* to i8\*}}), +// CHECK-SAME: i8* bitcast ({{[^@]+}}@"$s4main5ValueVyS2iGwet{{[^@]+}} to i8*), +// CHECK-SAME: i8* bitcast ({{[^@]+}}@"$s4main5ValueVyS2iGwst{{[^@]+}} to i8*), // CHECK-SAME: [[INT]] {{[0-9]+}}, // CHECK-SAME: [[INT]] {{[0-9]+}}, // CHECK-SAME: i32 {{[0-9]+}}, @@ -79,7 +79,7 @@ // NOTE: ignore COMDAT on PE/COFF targets // CHECK-SAME: align [[ALIGNMENT]] -// CHECK: @"$s4main5ValueVyS2iGMf" = linkonce_odr hidden constant <{ i8**, [[INT]], %swift.type_descriptor*, %swift.type*, %swift.type*, i32, i32, i64 }> <{ i8** getelementptr inbounds (%swift.vwtable, %swift.vwtable* @"$s4main5ValueVyS2iGWV", i32 0, i32 0), [[INT]] 512, %swift.type_descriptor* bitcast (<{ i32, i32, i32, i32, i32, i32, i32, i32, i32, i16, i16, i16, i16, i8, i8, i8, i8 }>* @"$s4main5ValueVMn" to %swift.type_descriptor*), %swift.type* @"$sSiN", %swift.type* @"$sSiN", i32 0, i32 [[ALIGNMENT]], i64 3 }>, align [[ALIGNMENT]] +// CHECK: @"$s4main5ValueVyS2iGMf" = linkonce_odr hidden constant {{.+}}$s4main5ValueVMn{{.+}} to %swift.type_descriptor*), %swift.type* @"$sSiN", %swift.type* @"$sSiN", i32 0, i32 [[ALIGNMENT]], i64 3 }>, align [[ALIGNMENT]] struct Value { let first: First let second: Second @@ -144,6 +144,6 @@ doit() // CHECK: [[EXIT_PRESPECIALIZED_4]]: // CHECK: ret %swift.metadata_response { %swift.type* getelementptr inbounds (%swift.full_type, %swift.full_type* bitcast (<{ i8**, [[INT]], %swift.type_descriptor*, %swift.type*, %swift.type*, i32, i32, i64 }>* @"$s4main5ValueVys5UInt8VSSGMf" to %swift.full_type*), i32 0, i32 1), [[INT]] 0 } // CHECK: [[EXIT_NORMAL]]: -// CHECK: {{%[0-9]+}} = call swiftcc %swift.metadata_response @__swift_instantiateGenericMetadata([[INT]] %0, i8* [[ERASED_TYPE_1]], i8* [[ERASED_TYPE_2]], i8* undef, %swift.type_descriptor* bitcast (<{ i32, i32, i32, i32, i32, i32, i32, i32, i32, i16, i16, i16, i16, i8, i8, i8, i8 }>* @"$s4main5ValueVMn" to %swift.type_descriptor*)) #{{[0-9]+}} +// CHECK: {{%[0-9]+}} = call swiftcc %swift.metadata_response @__swift_instantiateGenericMetadata([[INT]] %0, i8* [[ERASED_TYPE_1]], i8* [[ERASED_TYPE_2]], i8* undef, %swift.type_descriptor* bitcast ({{.+}}$s4main5ValueVMn{{.+}} to %swift.type_descriptor*)) #{{[0-9]+}} // CHECK: ret %swift.metadata_response {{%[0-9]+}} // CHECK: } diff --git a/test/IRGen/prespecialized-metadata/struct-inmodule-2argument-5distinct_use.swift b/test/IRGen/prespecialized-metadata/struct-inmodule-2argument-5distinct_use.swift index 156b7e43c0771..90e8cc77ac434 100644 --- a/test/IRGen/prespecialized-metadata/struct-inmodule-2argument-5distinct_use.swift +++ b/test/IRGen/prespecialized-metadata/struct-inmodule-2argument-5distinct_use.swift @@ -6,14 +6,14 @@ // UNSUPPORTED: CPU=armv7s && OS=ios // CHECK: @"$s4main5ValueVys5UInt8VSSGWV" = linkonce_odr hidden constant %swift.vwtable { -// CHECK-SAME: i8* bitcast (%swift.opaque* ([{{[0-9]+}} x i8]*, [{{[0-9]+}} x i8]*, %swift.type*)* @"$s4main5ValueVys5UInt8VSSGwCP" to i8*), -// CHECK-SAME: i8* bitcast (void (%swift.opaque*, %swift.type*)* @"$s4main5ValueVys5UInt8VSSGwxx" to i8*), -// CHECK-SAME: i8* bitcast (%swift.opaque* (%swift.opaque*, %swift.opaque*, %swift.type*)* @"$s4main5ValueVys5UInt8VSSGwcp" to i8*), -// CHECK-SAME: i8* bitcast (%swift.opaque* (%swift.opaque*, %swift.opaque*, %swift.type*)* @"$s4main5ValueVys5UInt8VSSGwca" to i8*), -// CHECK-SAME: i8* bitcast (i8* (i8*, i8*, %swift.type*)* @__swift_memcpy{{[0-9]+}}_{{[0-9]+}} to i8*), -// CHECK-SAME: i8* bitcast (%swift.opaque* (%swift.opaque*, %swift.opaque*, %swift.type*)* @"$s4main5ValueVys5UInt8VSSGwta" to i8*), -// CHECK-SAME: i8* bitcast (i32 (%swift.opaque*, i32, %swift.type*)* @"$s4main5ValueVys5UInt8VSSGwet" to i8*), -// CHECK-SAME: i8* bitcast (void (%swift.opaque*, i32, i32, %swift.type*)* @"$s4main5ValueVys5UInt8VSSGwst" to i8*), +// CHECK-SAME: i8* bitcast ({{[^@]*}}@"$s4main5ValueVys5UInt8VSSGwCP{{[^[:space:]]* to i8\*}}), +// CHECK-SAME: i8* bitcast ({{[^@]*}}@"$s4main5ValueVys5UInt8VSSGwxx{{[^[:space:]]* to i8\*}}), +// CHECK-SAME: i8* bitcast ({{[^@]*}}@"$s4main5ValueVys5UInt8VSSGwcp{{[^[:space:]]* to i8\*}}), +// CHECK-SAME: i8* bitcast ({{[^@]*}}@"$s4main5ValueVys5UInt8VSSGwca{{[^[:space:]]* to i8\*}}), +// CHECK-SAME: i8* bitcast ({{[^@]*}}@__swift_memcpy{{[^[:space:]]* to i8\*}}), +// CHECK-SAME: i8* bitcast ({{[^@]*}}@"$s4main5ValueVys5UInt8VSSGwta{{[^[:space:]]* to i8\*}}), +// CHECK-SAME: i8* bitcast ({{[^@]*}}@"$s4main5ValueVys5UInt8VSSGwet{{[^[:space:]]* to i8\*}}), +// CHECK-SAME: i8* bitcast ({{[^@]*}}@"$s4main5ValueVys5UInt8VSSGwst{{[^[:space:]]* to i8\*}}), // CHECK-SAME: [[INT]] {{[0-9]+}}, // CHECK-SAME: [[INT]] {{[0-9]+}}, // CHECK-SAME: i32 {{[0-9]+}}, @@ -22,17 +22,35 @@ // NOTE: ignore COMDAT on PE/COFF targets // CHECK-SAME: align [[ALIGNMENT]] -// CHECK: @"$s4main5ValueVys5UInt8VSSGMf" = linkonce_odr hidden constant <{ i8**, [[INT]], %swift.type_descriptor*, %swift.type*, %swift.type*, i32, i32, i64 }> <{ i8** getelementptr inbounds (%swift.vwtable, %swift.vwtable* @"$s4main5ValueVys5UInt8VSSGWV", i32 0, i32 0), [[INT]] 512, %swift.type_descriptor* bitcast (<{ i32, i32, i32, i32, i32, i32, i32, i32, i32, i16, i16, i16, i16, i8, i8, i8, i8 }>* @"$s4main5ValueVMn" to %swift.type_descriptor*), %swift.type* @"$ss5UInt8VN", %swift.type* @"$sSSN", i32 0, i32 [[ALIGNMENT]], i64 3 }>, align [[ALIGNMENT]] +// CHECK: @"$s4main5ValueVys5UInt8VSSGMf" = linkonce_odr hidden constant <{ +// CHECK-SAME: i8**, +// CHECK-SAME: [[INT]], +// CHECK-SAME: %swift.type_descriptor*, +// CHECK-SAME: %swift.type*, +// CHECK-SAME: %swift.type*, +// CHECK-SAME: i32, +// CHECK-SAME: i32, +// CHECK-SAME: i64 +// CHECK-SAME:}> <{ +// CHECK-SAME: i8** getelementptr inbounds (%swift.vwtable, %swift.vwtable* @"$s4main5ValueVys5UInt8VSSGWV", i32 0, i32 0), +// CHECK-SAME: [[INT]] 512, +// CHECK-SAME: %swift.type_descriptor* bitcast ({{.+}}$s4main5ValueVMn{{.+}} to %swift.type_descriptor*), +// CHECK-SAME: %swift.type* @"$ss5UInt8VN", +// CHECK-SAME: %swift.type* @"$sSSN", +// CHECK-SAME: i32 0, +// CHECK-SAME: i32 [[ALIGNMENT]], +// CHECK-SAME: i64 3 +// CHECK-SAME:}>, align [[ALIGNMENT]] // CHECK: @"$s4main5ValueVySSSdGWV" = linkonce_odr hidden constant %swift.vwtable { -// CHECK-SAME: i8* bitcast (%swift.opaque* ([{{[0-9]+}} x i8]*, [{{[0-9]+}} x i8]*, %swift.type*)* @"$s4main5ValueVySSSdGwCP" to i8*), -// CHECK-SAME: i8* bitcast (void (%swift.opaque*, %swift.type*)* @"$s4main5ValueVySSSdGwxx" to i8*), -// CHECK-SAME: i8* bitcast (%swift.opaque* (%swift.opaque*, %swift.opaque*, %swift.type*)* @"$s4main5ValueVySSSdGwcp" to i8*), -// CHECK-SAME: i8* bitcast (%swift.opaque* (%swift.opaque*, %swift.opaque*, %swift.type*)* @"$s4main5ValueVySSSdGwca" to i8*), -// CHECK-SAME: i8* bitcast (i8* (i8*, i8*, %swift.type*)* @__swift_memcpy{{[0-9]+}}_{{[0-9]+}} to i8*), -// CHECK-SAME: i8* bitcast (%swift.opaque* (%swift.opaque*, %swift.opaque*, %swift.type*)* @"$s4main5ValueVySSSdGwta" to i8*), -// CHECK-SAME: i8* bitcast (i32 (%swift.opaque*, i32, %swift.type*)* @"$s4main5ValueVySSSdGwet" to i8*), -// CHECK-SAME: i8* bitcast (void (%swift.opaque*, i32, i32, %swift.type*)* @"$s4main5ValueVySSSdGwst" to i8*), +// CHECK-SAME: i8* bitcast ({{[^@]*}}@"$s4main5ValueVySSSdGwCP{{[^[:space:]]* to i8\*}}), +// CHECK-SAME: i8* bitcast ({{[^@]*}}@"$s4main5ValueVySSSdGwxx{{[^[:space:]]* to i8\*}}), +// CHECK-SAME: i8* bitcast ({{[^@]*}}@"$s4main5ValueVySSSdGwcp{{[^[:space:]]* to i8\*}}), +// CHECK-SAME: i8* bitcast ({{[^@]*}}@"$s4main5ValueVySSSdGwca{{[^[:space:]]* to i8\*}}), +// CHECK-SAME: i8* bitcast ({{[^@]*}}@__swift_memcpy{{[^[:space:]]* to i8\*}}), +// CHECK-SAME: i8* bitcast ({{[^@]*}}@"$s4main5ValueVySSSdGwta{{[^[:space:]]* to i8\*}}), +// CHECK-SAME: i8* bitcast ({{[^@]*}}@"$s4main5ValueVySSSdGwet{{[^[:space:]]* to i8\*}}), +// CHECK-SAME: i8* bitcast ({{[^@]*}}@"$s4main5ValueVySSSdGwst{{[^[:space:]]* to i8\*}}), // CHECK-SAME: [[INT]] {{[0-9]+}}, // CHECK-SAME: [[INT]] {{[0-9]+}}, // CHECK-SAME: i32 {{[0-9]+}}, @@ -41,17 +59,35 @@ // NOTE: ignore COMDAT on PE/COFF targets // CHECK-SAME: align [[ALIGNMENT]] -// CHECK: @"$s4main5ValueVySSSdGMf" = linkonce_odr hidden constant <{ i8**, [[INT]], %swift.type_descriptor*, %swift.type*, %swift.type*, i32, i32, i64 }> <{ i8** getelementptr inbounds (%swift.vwtable, %swift.vwtable* @"$s4main5ValueVySSSdGWV", i32 0, i32 0), [[INT]] 512, %swift.type_descriptor* bitcast (<{ i32, i32, i32, i32, i32, i32, i32, i32, i32, i16, i16, i16, i16, i8, i8, i8, i8 }>* @"$s4main5ValueVMn" to %swift.type_descriptor*), %swift.type* @"$sSSN", %swift.type* @"$sSdN", i32 0, i32 16, i64 3 }>, align [[ALIGNMENT]] +// CHECK: @"$s4main5ValueVySSSdGMf" = linkonce_odr hidden constant <{ +// CHECK-SAME: i8**, +// CHECK-SAME: [[INT]], +// CHECK-SAME: %swift.type_descriptor*, +// CHECK-SAME: %swift.type*, +// CHECK-SAME: %swift.type*, +// CHECK-SAME: i32, +// CHECK-SAME: i32, +// CHECK-SAME: i64 +// CHECK-SAME:}> <{ +// CHECK-SAME: i8** getelementptr inbounds (%swift.vwtable, %swift.vwtable* @"$s4main5ValueVySSSdGWV", i32 0, i32 0), +// CHECK-SAME: [[INT]] 512, +// CHECK-SAME: %swift.type_descriptor* bitcast ({{.+}}$s4main5ValueVMn{{.+}} to %swift.type_descriptor*), +// CHECK-SAME: %swift.type* @"$sSSN", +// CHECK-SAME: %swift.type* @"$sSdN", +// CHECK-SAME: i32 0, +// CHECK-SAME: i32 16, +// CHECK-SAME: i64 3 +// CHECK-SAME:}>, align [[ALIGNMENT]] // CHECK: @"$s4main5ValueVySdSiGWV" = linkonce_odr hidden constant %swift.vwtable { -// CHECK-SAME: i8* bitcast ({{(%swift.opaque\* \(\[[0-9]+ x i8\]\*, \[[0-9]+ x i8\]\*, %swift.type\*\)\* @"\$[a-zA-Z0-9_]+" to i8\*|i8\* \(i8\*, i8\*, %swift.type\*\)\* @__swift_memcpy[0-9]+_[0-9]+ to i8\*)}}), -// CHECK-SAME: i8* bitcast (void (i8*, %swift.type*)* @__swift_noop_void_return to i8*), -// CHECK_SAME: i8* bitcast (i8* (i8*, i8*, %swift.type*)* @__swift_memcpy{{[0-9]+}}_{{[0-9]+}} to i8*), -// CHECK-SAME: i8* bitcast (i8* (i8*, i8*, %swift.type*)* @__swift_memcpy{{[0-9]+}}_{{[0-9]+}} to i8*), -// CHECK-SAME: i8* bitcast (i8* (i8*, i8*, %swift.type*)* @__swift_memcpy{{[0-9]+}}_{{[0-9]+}} to i8*), -// CHECK-SAME: i8* bitcast (i8* (i8*, i8*, %swift.type*)* @__swift_memcpy{{[0-9]+}}_{{[0-9]+}} to i8*), -// CHECK-SAME: i8* bitcast (i32 (%swift.opaque*, i32, %swift.type*)* @"$s4main5ValueVySdSiGwet" to i8*), -// CHECK-SAME: i8* bitcast (void (%swift.opaque*, i32, i32, %swift.type*)* @"$s4main5ValueVySdSiGwst" to i8*), +// CHECK-SAME: i8* bitcast ({{(%swift.opaque\* \(\[[0-9]+ x i8\]\*, \[[0-9]+ x i8\]\*, %swift.type\*\)\* @"\$[a-zA-Z0-9_]+" to i8\*|[^@]*@__swift_memcpy[^@]* to i8\*)}}), +// CHECK-SAME: i8* bitcast ({{[^@]*}}@__swift_noop_void_return{{[^[:space:]]* to i8\*}}), +// CHECK_SAME: i8* bitcast ({{[^@]*}}@__swift_memcpy{{[^[:space:]]* to i8\*}}), +// CHECK-SAME: i8* bitcast ({{[^@]*}}@__swift_memcpy{{[^[:space:]]* to i8\*}}), +// CHECK-SAME: i8* bitcast ({{[^@]*}}@__swift_memcpy{{[^[:space:]]* to i8\*}}), +// CHECK-SAME: i8* bitcast ({{[^@]*}}@__swift_memcpy{{[^[:space:]]* to i8\*}}), +// CHECK-SAME: i8* bitcast ({{[^@]*}}@"$s4main5ValueVySdSiGwet{{[^[:space:]]* to i8\*}}), +// CHECK-SAME: i8* bitcast ({{[^@]*}}@"$s4main5ValueVySdSiGwst{{[^[:space:]]* to i8\*}}), // CHECK-SAME: [[INT]] {{[0-9]+}}, // CHECK-SAME: [[INT]] {{[0-9]+}}, // CHECK-SAME: i32 {{[0-9]+}}, @@ -60,17 +96,35 @@ // NOTE: ignore COMDAT on PE/COFF targets // CHECK-SAME: align [[ALIGNMENT]] -// CHECK: @"$s4main5ValueVySdSiGMf" = linkonce_odr hidden constant <{ i8**, [[INT]], %swift.type_descriptor*, %swift.type*, %swift.type*, i32, i32, i64 }> <{ i8** getelementptr inbounds (%swift.vwtable, %swift.vwtable* @"$s4main5ValueVySdSiGWV", i32 0, i32 0), [[INT]] 512, %swift.type_descriptor* bitcast (<{ i32, i32, i32, i32, i32, i32, i32, i32, i32, i16, i16, i16, i16, i8, i8, i8, i8 }>* @"$s4main5ValueVMn" to %swift.type_descriptor*), %swift.type* @"$sSdN", %swift.type* @"$sSiN", i32 0, i32 8, i64 3 }>, align [[ALIGNMENT]] +// CHECK: @"$s4main5ValueVySdSiGMf" = linkonce_odr hidden constant <{ +// CHECK-SAME: i8**, +// CHECK-SAME: [[INT]], +// CHECK-SAME: %swift.type_descriptor*, +// CHECK-SAME: %swift.type*, +// CHECK-SAME: %swift.type*, +// CHECK-SAME: i32, +// CHECK-SAME: i32, +// CHECK-SAME: i64 +// CHECK-SAME:}> <{ +// CHECK-SAME: i8** getelementptr inbounds (%swift.vwtable, %swift.vwtable* @"$s4main5ValueVySdSiGWV", i32 0, i32 0), +// CHECK-SAME: [[INT]] 512, +// CHECK-SAME: %swift.type_descriptor* bitcast ({{.+}}$s4main5ValueVMn{{.+}} to %swift.type_descriptor*), +// CHECK-SAME: %swift.type* @"$sSdN", +// CHECK-SAME: %swift.type* @"$sSiN", +// CHECK-SAME: i32 0, +// CHECK-SAME: i32 8, +// CHECK-SAME: i64 3 +// CHECK-SAME:}>, align [[ALIGNMENT]] // CHECK: @"$s4main5ValueVyS2iGWV" = linkonce_odr hidden constant %swift.vwtable { -// CHECK-SAME: i8* bitcast ({{(%swift.opaque\* \(\[[0-9]+ x i8\]\*, \[[0-9]+ x i8\]\*, %swift.type\*\)\* @"\$[a-zA-Z0-9_]+" to i8\*|i8\* \(i8\*, i8\*, %swift.type\*\)\* @__swift_memcpy[0-9]+_[0-9]+ to i8\*)}}), -// CHECK-SAME: i8* bitcast (void (i8*, %swift.type*)* @__swift_noop_void_return to i8*), -// CHECK-SAME: i8* bitcast (i8* (i8*, i8*, %swift.type*)* @__swift_memcpy{{[0-9]+}}_{{[0-9]+}} to i8*), -// CHECK-SAME: i8* bitcast (i8* (i8*, i8*, %swift.type*)* @__swift_memcpy{{[0-9]+}}_{{[0-9]+}} to i8*), -// CHECK-SAME: i8* bitcast (i8* (i8*, i8*, %swift.type*)* @__swift_memcpy{{[0-9]+}}_{{[0-9]+}} to i8*), -// CHECK-SAME: i8* bitcast (i8* (i8*, i8*, %swift.type*)* @__swift_memcpy{{[0-9]+}}_{{[0-9]+}} to i8*), -// CHECK-SAME: i8* bitcast (i32 (%swift.opaque*, i32, %swift.type*)* @"$s4main5ValueVyS2iGwet" to i8*), -// CHECK-SAME: i8* bitcast (void (%swift.opaque*, i32, i32, %swift.type*)* @"$s4main5ValueVyS2iGwst" to i8*), +// CHECK-SAME: i8* bitcast ({{(%swift.opaque\* \(\[[0-9]+ x i8\]\*, \[[0-9]+ x i8\]\*, %swift.type\*\)\* @"\$[a-zA-Z0-9_]+" to i8\*|[^@]*@__swift_memcpy[^@]* to i8\*)}}), +// CHECK-SAME: i8* bitcast ({{[^@]*}}@__swift_noop_void_return{{[^[:space:]]* to i8\*}}), +// CHECK-SAME: i8* bitcast ({{[^@]*}}@__swift_memcpy{{[^[:space:]]* to i8\*}}), +// CHECK-SAME: i8* bitcast ({{[^@]*}}@__swift_memcpy{{[^[:space:]]* to i8\*}}), +// CHECK-SAME: i8* bitcast ({{[^@]*}}@__swift_memcpy{{[^[:space:]]* to i8\*}}), +// CHECK-SAME: i8* bitcast ({{[^@]*}}@__swift_memcpy{{[^[:space:]]* to i8\*}}), +// CHECK-SAME: i8* bitcast ({{[^@]*}}@"$s4main5ValueVyS2iGwet{{[^[:space:]]* to i8\*}}), +// CHECK-SAME: i8* bitcast ({{[^@]*}}@"$s4main5ValueVyS2iGwst{{[^[:space:]]* to i8\*}}), // CHECK-SAME: [[INT]] {{[0-9]+}}, // CHECK-SAME: [[INT]] {{[0-9]+}}, // CHECK-SAME: i32 {{[0-9]+}}, @@ -79,7 +133,25 @@ // NOTE: ignore COMDAT on PE/COFF targets // CHECK-SAME: align [[ALIGNMENT]] -// CHECK: @"$s4main5ValueVyS2iGMf" = linkonce_odr hidden constant <{ i8**, [[INT]], %swift.type_descriptor*, %swift.type*, %swift.type*, i32, i32, i64 }> <{ i8** getelementptr inbounds (%swift.vwtable, %swift.vwtable* @"$s4main5ValueVyS2iGWV", i32 0, i32 0), [[INT]] 512, %swift.type_descriptor* bitcast (<{ i32, i32, i32, i32, i32, i32, i32, i32, i32, i16, i16, i16, i16, i8, i8, i8, i8 }>* @"$s4main5ValueVMn" to %swift.type_descriptor*), %swift.type* @"$sSiN", %swift.type* @"$sSiN", i32 0, i32 [[ALIGNMENT]], i64 3 }>, align [[ALIGNMENT]] +// CHECK: @"$s4main5ValueVyS2iGMf" = linkonce_odr hidden constant <{ +// CHECK-SAME: i8**, +// CHECK-SAME: [[INT]], +// CHECK-SAME: %swift.type_descriptor*, +// CHECK-SAME: %swift.type*, +// CHECK-SAME: %swift.type*, +// CHECK-SAME: i32, +// CHECK-SAME: i32, +// CHECK-SAME: i64 +// CHECK-SAME:}> <{ +// CHECK-SAME: i8** getelementptr inbounds (%swift.vwtable, %swift.vwtable* @"$s4main5ValueVyS2iGWV", i32 0, i32 0), +// CHECK-SAME: [[INT]] 512, +// CHECK-SAME: %swift.type_descriptor* bitcast ({{.+}}$s4main5ValueVMn{{.+}} to %swift.type_descriptor*), +// CHECK-SAME: %swift.type* @"$sSiN", +// CHECK-SAME: %swift.type* @"$sSiN", +// CHECK-SAME: i32 0, +// CHECK-SAME: i32 [[ALIGNMENT]], +// CHECK-SAME: i64 3 +// CHECK-SAME:}>, align [[ALIGNMENT]] struct Value { let first: First let second: Second @@ -154,6 +226,6 @@ doit() // CHECK: [[EXIT_PRESPECIALIZED_5]]: // CHECK: ret %swift.metadata_response { %swift.type* getelementptr inbounds (%swift.full_type, %swift.full_type* bitcast (<{ i8**, [[INT]], %swift.type_descriptor*, %swift.type*, %swift.type*, i32, i32, i64 }>* @"$s4main5ValueVys4Int8Vs5UInt8VGMf" to %swift.full_type*), i32 0, i32 1), [[INT]] 0 } // CHECK: [[EXIT_NORMAL]]: -// CHECK: {{%[0-9]+}} = call swiftcc %swift.metadata_response @__swift_instantiateGenericMetadata([[INT]] %0, i8* [[ERASED_TYPE_1]], i8* [[ERASED_TYPE_2]], i8* undef, %swift.type_descriptor* bitcast (<{ i32, i32, i32, i32, i32, i32, i32, i32, i32, i16, i16, i16, i16, i8, i8, i8, i8 }>* @"$s4main5ValueVMn" to %swift.type_descriptor*)) #{{[0-9]+}} +// CHECK: {{%[0-9]+}} = call swiftcc %swift.metadata_response @__swift_instantiateGenericMetadata([[INT]] %0, i8* [[ERASED_TYPE_1]], i8* [[ERASED_TYPE_2]], i8* undef, %swift.type_descriptor* bitcast ({{.+}}$s4main5ValueVMn{{.+}} to %swift.type_descriptor*)) #{{[0-9]+}} // CHECK: ret %swift.metadata_response {{%[0-9]+}} // CHECK: } diff --git a/test/IRGen/prespecialized-metadata/struct-inmodule-2argument-within-class-1argument-1distinct_use.swift b/test/IRGen/prespecialized-metadata/struct-inmodule-2argument-within-class-1argument-1distinct_use.swift index 81920fe4ff816..7701e761a485f 100644 --- a/test/IRGen/prespecialized-metadata/struct-inmodule-2argument-within-class-1argument-1distinct_use.swift +++ b/test/IRGen/prespecialized-metadata/struct-inmodule-2argument-within-class-1argument-1distinct_use.swift @@ -6,14 +6,14 @@ // UNSUPPORTED: CPU=armv7s && OS=ios // CHECK: @"$s4main9NamespaceC5ValueVySS_SiSdGWV" = linkonce_odr hidden constant %swift.vwtable { -// CHECK-SAME: i8* bitcast ({{(%swift.opaque\* \(\[[0-9]+ x i8\]\*, \[[0-9]+ x i8\]\*, %swift.type\*\)\* @"\$[a-zA-Z0-9_]+" to i8\*|i8\* \(i8\*, i8\*, %swift.type\*\)\* @__swift_memcpy[0-9]+_[0-9]+ to i8\*)}}), -// CHECK-SAME: i8* bitcast (void (i8*, %swift.type*)* @__swift_noop_void_return to i8*), -// CHECK-SAME: i8* bitcast (i8* (i8*, i8*, %swift.type*)* @__swift_memcpy{{[0-9]+}}_{{[0-9]+}} to i8*), -// CHECK-SAME: i8* bitcast (i8* (i8*, i8*, %swift.type*)* @__swift_memcpy{{[0-9]+}}_{{[0-9]+}} to i8*), -// CHECK-SAME: i8* bitcast (i8* (i8*, i8*, %swift.type*)* @__swift_memcpy{{[0-9]+}}_{{[0-9]+}} to i8*), -// CHECK-SAME: i8* bitcast (i8* (i8*, i8*, %swift.type*)* @__swift_memcpy{{[0-9]+}}_{{[0-9]+}} to i8*), -// CHECK-SAME: i8* bitcast (i32 (%swift.opaque*, i32, %swift.type*)* @"$s4main9NamespaceC5ValueVySS_SiSdGwet" to i8*), -// CHECK-SAME: i8* bitcast (void (%swift.opaque*, i32, i32, %swift.type*)* @"$s4main9NamespaceC5ValueVySS_SiSdGwst" to i8*), +// CHECK-SAME: i8* bitcast ({{(%swift.opaque\* \(\[[0-9]+ x i8\]\*, \[[0-9]+ x i8\]\*, %swift.type\*\)\* @"\$[a-zA-Z0-9_]+" to i8\*|[^@]+@__swift_memcpy[^[:space:]]+ to i8\*)}}), +// CHECK-SAME: i8* bitcast ({{[^@]*}}@__swift_noop_void_return{{[^[:space:]]* to i8\*}}), +// CHECK-SAME: i8* bitcast ({{[^@]+}}@__swift_memcpy{{[^[:space:]]+ to i8\*}}), +// CHECK-SAME: i8* bitcast ({{[^@]+}}@__swift_memcpy{{[^[:space:]]+ to i8\*}}), +// CHECK-SAME: i8* bitcast ({{[^@]+}}@__swift_memcpy{{[^[:space:]]+ to i8\*}}), +// CHECK-SAME: i8* bitcast ({{[^@]+}}@__swift_memcpy{{[^[:space:]]+ to i8\*}}), +// CHECK-SAME: i8* bitcast ({{[^@]+}}@"$s4main9NamespaceC5ValueVySS_SiSdGwet{{[^@]+}} to i8*), +// CHECK-SAME: i8* bitcast ({{[^@]+}}@"$s4main9NamespaceC5ValueVySS_SiSdGwst{{[^@]+}} to i8*), // CHECK-SAME: [[INT]] {{[0-9]+}}, // CHECK-SAME: [[INT]] {{[0-9]+}}, // CHECK-SAME: i32 {{[0-9]+}}, @@ -22,7 +22,7 @@ // NOTE: ignore the COMDAT on PE/COFF platforms // CHECK-SAME: align [[ALIGNMENT]] -// CHECK: @"$s4main9NamespaceC5ValueVySS_SiSdGMf" = linkonce_odr hidden constant <{ i8**, [[INT]], %swift.type_descriptor*, %swift.type*, %swift.type*, %swift.type*, i32, i32, i64 }> <{ i8** getelementptr inbounds (%swift.vwtable, %swift.vwtable* @"$s4main9NamespaceC5ValueVySS_SiSdGWV", i32 0, i32 0), [[INT]] 512, %swift.type_descriptor* bitcast (<{ i32, i32, i32, i32, i32, i32, i32, i32, i32, i16, i16, i16, i16, i8, i8, i8, i8 }>* @"$s4main9NamespaceC5ValueVMn" to %swift.type_descriptor*), %swift.type* @"$sSSN", %swift.type* @"$sSiN", %swift.type* @"$sSdN", i32 0, i32 8, i64 3 }>, align [[ALIGNMENT]] +// CHECK: @"$s4main9NamespaceC5ValueVySS_SiSdGMf" = linkonce_odr hidden constant {{.+}}$s4main9NamespaceC5ValueVMn{{.+}} to %swift.type_descriptor*), %swift.type* @"$sSSN", %swift.type* @"$sSiN", %swift.type* @"$sSdN", i32 0, i32 8, i64 3 }>, align [[ALIGNMENT]] final class Namespace { struct Value { let first: First @@ -62,6 +62,6 @@ doit() // CHECK: [[EXIT_PRESPECIALIZED_1]]: // CHECK: ret %swift.metadata_response { %swift.type* getelementptr inbounds (%swift.full_type, %swift.full_type* bitcast (<{ i8**, [[INT]], %swift.type_descriptor*, %swift.type*, %swift.type*, %swift.type*, i32, i32, i64 }>* @"$s4main9NamespaceC5ValueVySS_SiSdGMf" to %swift.full_type*), i32 0, i32 1), [[INT]] 0 } // CHECK: [[EXIT_NORMAL]]: -// CHECK: {{%[0-9]+}} = call swiftcc %swift.metadata_response @__swift_instantiateGenericMetadata([[INT]] %0, i8* [[ERASED_TYPE_1]], i8* [[ERASED_TYPE_2]], i8* [[ERASED_TYPE_3]], %swift.type_descriptor* bitcast (<{ i32, i32, i32, i32, i32, i32, i32, i32, i32, i16, i16, i16, i16, i8, i8, i8, i8 }>* @"$s4main9NamespaceC5ValueVMn" to %swift.type_descriptor*)) #{{[0-9]+}} +// CHECK: {{%[0-9]+}} = call swiftcc %swift.metadata_response @__swift_instantiateGenericMetadata([[INT]] %0, i8* [[ERASED_TYPE_1]], i8* [[ERASED_TYPE_2]], i8* [[ERASED_TYPE_3]], %swift.type_descriptor* bitcast ({{.+}}$s4main9NamespaceC5ValueVMn{{.+}} to %swift.type_descriptor*)) #{{[0-9]+}} // CHECK: ret %swift.metadata_response {{%[0-9]+}} // CHECK: } diff --git a/test/IRGen/prespecialized-metadata/struct-public-inmodule-1argument-1distinct_use.swift b/test/IRGen/prespecialized-metadata/struct-public-inmodule-1argument-1distinct_use.swift index b588a226ba6cb..38549082d4bac 100644 --- a/test/IRGen/prespecialized-metadata/struct-public-inmodule-1argument-1distinct_use.swift +++ b/test/IRGen/prespecialized-metadata/struct-public-inmodule-1argument-1distinct_use.swift @@ -16,7 +16,7 @@ // i8** @"$sB[[INT]]_WV", // i8** getelementptr inbounds (%swift.vwtable, %swift.vwtable* @"$s4main5ValueVySiGWV", i32 0, i32 0), // CHECK-SAME: [[INT]] 512, -// CHECK-SAME: %swift.type_descriptor* bitcast (<{ i32, i32, i32, i32, i32, i32, i32, i32, i32, i16, i16, i16, i16, i8, i8, i8, i8 }>* @"$s4main5ValueVMn" to %swift.type_descriptor*), +// CHECK-SAME: %swift.type_descriptor* bitcast ({{.+}}$s4main5ValueVMn{{.+}} to %swift.type_descriptor*), // CHECK-SAME: %swift.type* @"$sSiN", // CHECK-SAME: i32 0{{(, \[4 x i8\] zeroinitializer)?}}, // CHECK-SAME: i64 3 @@ -53,6 +53,6 @@ doit() // CHECK: [[EXIT_PRESPECIALIZED]]: // CHECK: ret %swift.metadata_response { %swift.type* getelementptr inbounds (%swift.full_type, %swift.full_type* bitcast (<{ i8**, [[INT]], %swift.type_descriptor*, %swift.type*, i32{{(, \[4 x i8\])?}}, i64 }>* @"$s4main5ValueVySiGMf" to %swift.full_type*), i32 0, i32 1), [[INT]] 0 } // CHECK: [[EXIT_NORMAL]]: -// CHECK: {{%[0-9]+}} = call swiftcc %swift.metadata_response @__swift_instantiateGenericMetadata([[INT]] %0, i8* [[ERASED_TYPE]], i8* undef, i8* undef, %swift.type_descriptor* bitcast (<{ i32, i32, i32, i32, i32, i32, i32, i32, i32, i16, i16, i16, i16, i8, i8, i8, i8 }>* @"$s4main5ValueVMn" to %swift.type_descriptor*)) #{{[0-9]+}} +// CHECK: {{%[0-9]+}} = call swiftcc %swift.metadata_response @__swift_instantiateGenericMetadata([[INT]] %0, i8* [[ERASED_TYPE]], i8* undef, i8* undef, %swift.type_descriptor* bitcast ({{.+}}$s4main5ValueVMn{{.+}} to %swift.type_descriptor*)) #{{[0-9]+}} // CHECK: ret %swift.metadata_response {{%[0-9]+}} // CHECK: } diff --git a/test/IRGen/property_descriptor.sil b/test/IRGen/property_descriptor.sil index 375f2bb3bba4c..db78e7ee2494c 100644 --- a/test/IRGen/property_descriptor.sil +++ b/test/IRGen/property_descriptor.sil @@ -55,11 +55,11 @@ sil_property #ExternalGeneric.rw ( // -- 0x0108_0000 - computed, readonly, has arguments, identified by indirect // CHECK-SAME: <{ , // CHECK-SAME: @{{got.|__imp_}}id_computed -// CHECK-SAME: [[GET_COMPUTEDRO:@keypath_get[.0-9]*]] -// CHECK-SAME: [[GET_ARG_LAYOUT_COMPUTEDRO:@keypath_get_arg_layout[.0-9]*]] +// CHECK-SAME: [[GET_COMPUTEDRO:@keypath_get[.0-9]*]]{{(\.ptrauth)?}} +// CHECK-SAME: [[GET_ARG_LAYOUT_COMPUTEDRO:@keypath_get_arg_layout[.0-9]*]]{{(\.ptrauth)?}} // -- default witness table // CHECK-SAME: i32 0 -// CHECK-SAME: [[ARG_INIT_COMPUTEDRO:@keypath_arg_init[.0-9]*]] +// CHECK-SAME: [[ARG_INIT_COMPUTEDRO:@keypath_arg_init[.0-9]*]]{{(\.ptrauth.*)?}} sil_property #ExternalGeneric.computedRO ( gettable_property $T, id @id_computed : $@convention(thin) () -> (), @@ -69,11 +69,11 @@ sil_property #ExternalGeneric.computedRO ( // -- 0x01c8_0000 - computed, settable, mutating, has arguments, indirect id // CHECK-SAME: <{ , // CHECK-SAME: @{{got.|__imp_}}id_computed -// CHECK-SAME: [[GET_COMPUTEDRW:@keypath_get[.0-9]*]] -// CHECK-SAME: [[SET_COMPUTEDRW:@keypath_set[.0-9]*]] -// CHECK-SAME: [[GET_ARG_LAYOUT_COMPUTEDRW:@keypath_get_arg_layout[.0-9]*]] +// CHECK-SAME: [[GET_COMPUTEDRW:@keypath_get[.0-9]*]]{{(\.ptrauth)?}} +// CHECK-SAME: [[SET_COMPUTEDRW:@keypath_set[.0-9]*]]{{(\.ptrauth)?}} +// CHECK-SAME: [[GET_ARG_LAYOUT_COMPUTEDRW:@keypath_get_arg_layout[.0-9]*]]{{(\.ptrauth)?}} // CHECK-SAME: i32 0 -// CHECK-SAME: [[ARG_INIT_COMPUTEDRW:@keypath_arg_init[.0-9]*]] +// CHECK-SAME: [[ARG_INIT_COMPUTEDRW:@keypath_arg_init[.0-9]*]]{{(\.ptrauth.*)?}} sil_property #ExternalGeneric.computedRW ( settable_property $T, id @id_computed : $@convention(thin) () -> (), @@ -84,11 +84,11 @@ sil_property #ExternalGeneric.computedRW ( // -- 0x01c8_0000 - computed, settable, mutating, has arguments, indirect id // CHECK-SAME: <{ , // CHECK-SAME: @{{got.|__imp_}}id_computed -// CHECK-SAME: [[GET_SUBSCRIPT:@keypath_get[.0-9]*]] -// CHECK-SAME: [[SET_SUBSCRIPT:@keypath_set[.0-9]*]] -// CHECK-SAME: [[GET_ARG_LAYOUT_SUBSCRIPT:@keypath_get_arg_layout[.0-9]*]] +// CHECK-SAME: [[GET_SUBSCRIPT:@keypath_get[.0-9]*]]{{(\.ptrauth)?}} +// CHECK-SAME: [[SET_SUBSCRIPT:@keypath_set[.0-9]*]]{{(\.ptrauth)?}} +// CHECK-SAME: [[GET_ARG_LAYOUT_SUBSCRIPT:@keypath_get_arg_layout[.0-9]*]]{{(\.ptrauth)?}} // CHECK-SAME: i32 0 -// CHECK-SAME: [[ARG_INIT_SUBSCRIPT:@keypath_arg_init[.0-9]*]] +// CHECK-SAME: [[ARG_INIT_SUBSCRIPT:@keypath_arg_init[.0-9]*]]{{(\.ptrauth.*)?}} sil_property #ExternalGeneric.subscript ( settable_property $T, id @id_computed : $@convention(thin) () -> (), diff --git a/test/IRGen/protocol_resilience.sil b/test/IRGen/protocol_resilience.sil index d0499378b2f2e..27b682b7b98b0 100644 --- a/test/IRGen/protocol_resilience.sil +++ b/test/IRGen/protocol_resilience.sil @@ -29,26 +29,26 @@ import resilient_protocol // CHECK-SAME: @"$s19protocol_resilience17ResilientProtocolMp" // Protocol requirements -// CHECK-SAME: %swift.protocol_requirement { i32 8, i32 0 }, -// CHECK-SAME: %swift.protocol_requirement { i32 7, i32 0 }, +// CHECK-SAME: %swift.protocol_requirement { i32 {{(1797193736)|(8)}}, i32 0 }, +// CHECK-SAME: %swift.protocol_requirement { i32 {{(-1947336697)|(7)}}, i32 0 }, -// CHECK-SAME: %swift.protocol_requirement { i32 17, i32 0 }, +// CHECK-SAME: %swift.protocol_requirement { i32 {{(-48627695)|(17)}}, i32 0 }, -// CHECK-SAME: %swift.protocol_requirement { i32 17, i32 0 }, +// CHECK-SAME: %swift.protocol_requirement { i32 {{(-1745420271)|(17)}}, i32 0 }, -// CHECK-SAME: %swift.protocol_requirement { i32 17, +// CHECK-SAME: %swift.protocol_requirement { i32 {{(-544407535)|(17)}}, // CHECK-SAME: i32{{ | trunc \(i64 }}sub ([[INT]] ptrtoint (void (%swift.opaque*, %swift.type*, i8**)* @defaultC to [[INT]]), // CHECK-SAME: }, -// CHECK-SAME: %swift.protocol_requirement { i32 17, +// CHECK-SAME: %swift.protocol_requirement { i32 {{(1717370897)|(17)}}, // CHECK-SAME: i32{{ | trunc \(i64 }}sub ([[INT]] ptrtoint (void (%swift.opaque*, %swift.type*, i8**)* @defaultD to [[INT]]), // CHECK-SAME: }, -// CHECK-SAME: %swift.protocol_requirement { i32 1, +// CHECK-SAME: %swift.protocol_requirement { i32 {{(297926657)|(1)}}, // CHECK-SAME: i32{{ | trunc \(i64 }}sub ([[INT]] ptrtoint (void (%swift.type*, %swift.type*, i8**)* @defaultE to [[INT]]), // CHECK-SAME: }, -// CHECK-SAME: %swift.protocol_requirement { i32 1, +// CHECK-SAME: %swift.protocol_requirement { i32 {{(351797249)|(1)}}, // CHECK-SAME: i32{{ | trunc \(i64 }}sub ([[INT]] ptrtoint (void (%swift.type*, %swift.type*, i8**)* @defaultF to [[INT]]), // CHECK-SAME: } // CHECK-SAME: } @@ -165,7 +165,7 @@ bb0(%0 : $*Self): // CHECK-NEXT: [[WITNESS_ADDR:%.*]] = getelementptr inbounds i8*, i8** %SelfWitnessTable, i32 5 // CHECK-NEXT: [[WITNESS_FN:%.*]] = load i8*, i8** [[WITNESS_ADDR]] // CHECK-NEXT: [[WITNESS:%.*]] = bitcast i8* [[WITNESS_FN]] to void (%swift.opaque*, %swift.type*, i8**)* - // CHECK-NEXT: call swiftcc void [[WITNESS]](%swift.opaque* noalias nocapture swiftself %0, %swift.type* %Self, i8** %SelfWitnessTable) + // CHECK: call swiftcc void [[WITNESS]](%swift.opaque* noalias nocapture swiftself %0, %swift.type* %Self, i8** %SelfWitnessTable) %fn2 = witness_method $Self, #ResilientProtocol.defaultC!1 : $@convention(witness_method: ResilientProtocol) (@in_guaranteed Self) -> () %ignore2 = apply %fn2(%0) : $@convention(witness_method: ResilientProtocol) (@in_guaranteed Self) -> () @@ -206,7 +206,7 @@ bb0(%0 : $@thick Self.Type): // CHECK-NEXT: [[WITNESS_ADDR:%.*]] = getelementptr inbounds i8*, i8** %SelfWitnessTable, i32 8 // CHECK-NEXT: [[WITNESS_FN:%.*]] = load i8*, i8** [[WITNESS_ADDR]] // CHECK-NEXT: [[WITNESS:%.*]] = bitcast i8* [[WITNESS_FN]] to void (%swift.type*, %swift.type*, i8**)* - // CHECK-NEXT: call swiftcc void [[WITNESS]](%swift.type* swiftself %0, %swift.type* %Self, i8** %SelfWitnessTable) + // CHECK: call swiftcc void [[WITNESS]](%swift.type* swiftself %0, %swift.type* %Self, i8** %SelfWitnessTable) %fn2 = witness_method $Self, #ResilientProtocol.defaultF!1 : $@convention(witness_method: ResilientProtocol) (@thick Self.Type) -> () %ignore2 = apply %fn2(%0) : $@convention(witness_method: ResilientProtocol) (@thick Self.Type) -> () diff --git a/test/IRGen/protocol_resilience_descriptors.swift b/test/IRGen/protocol_resilience_descriptors.swift index 3662ff601f9a4..cc652d276ef26 100644 --- a/test/IRGen/protocol_resilience_descriptors.swift +++ b/test/IRGen/protocol_resilience_descriptors.swift @@ -22,7 +22,7 @@ // CHECK-DEFINITION-SAME: @"default associated conformance2T218resilient_protocol29ProtocolWithAssocTypeDefaultsP_AB014OtherResilientD0" // Associated type default + flags -// CHECK-DEFINITION-SAME: [[INT]] add +// CHECK-DEFINITION-SAME: getelementptr // CHECK-DEFINITION-SAME: @"default assoc type _____y2T1_____QzG 18resilient_protocol7WrapperV AA29ProtocolWithAssocTypeDefaultsP" // CHECK-DEFINITION-SAME: [[INT]] 1 diff --git a/test/IRGen/protocol_resilience_thunks.swift b/test/IRGen/protocol_resilience_thunks.swift index dd0005a38bb6e..33054356a39cf 100644 --- a/test/IRGen/protocol_resilience_thunks.swift +++ b/test/IRGen/protocol_resilience_thunks.swift @@ -1,6 +1,6 @@ // RUN: %empty-directory(%t) // RUN: %target-swift-frontend -emit-module -enable-library-evolution -emit-module-path=%t/resilient_protocol.swiftmodule -module-name=resilient_protocol %S/../Inputs/resilient_protocol.swift -// RUN: %target-swift-frontend -I %t -emit-ir -enable-library-evolution %s | %FileCheck %s +// RUN: %target-swift-frontend -I %t -emit-ir -enable-library-evolution %s | %FileCheck --check-prefix=CHECK --check-prefix=CHECK-%target-cpu %s // RUN: %target-swift-frontend -I %t -emit-ir -enable-library-evolution -O %s // CHECK: %swift.type = type { [[INT:i32|i64]] } @@ -42,6 +42,8 @@ public protocol MyResilientProtocol { // CHECK: [[WITNESS_GEP:%.*]] = getelementptr inbounds i8*, i8** %3, i32 1 // CHECK: [[WITNESS:%.*]] = load i8*, i8** [[WITNESS_GEP]] // CHECK-NEXT: [[FN:%.*]] = bitcast i8* [[WITNESS]] to void (i1, %swift.opaque*, %swift.type*, i8**)* +// CHECK-arm64e-NEXT: ptrtoint i8** [[WITNESS_GEP]] to i64 +// CHECK-arm64e-NEXT: call i64 @llvm.ptrauth.blend.i64 // CHECK-NEXT: call swiftcc void [[FN]](i1 %0, %swift.opaque* noalias nocapture swiftself %1, %swift.type* %2, i8** %3) // CHECK-NEXT: ret void @@ -49,6 +51,8 @@ public protocol MyResilientProtocol { // CHECK: [[WITNESS_ADDR:%.*]] = getelementptr inbounds i8*, i8** %2, i32 2 // CHECK-NEXT: [[WITNESS:%.*]] = load i8*, i8** [[WITNESS_ADDR]] // CHECK-NEXT: [[FN:%.*]] = bitcast i8* [[WITNESS]] to i1 (%swift.opaque*, %swift.type*, i8**)* +// CHECK-arm64e-NEXT: ptrtoint i8** [[WITNESS_ADDR]] to i64 +// CHECK-arm64e-NEXT: call i64 @llvm.ptrauth.blend.i64 // CHECK-NEXT: [[RESULT:%.*]] = call swiftcc i1 [[FN]](%swift.opaque* noalias nocapture swiftself %0, %swift.type* %1, i8** %2) // CHECK-NEXT: ret i1 [[RESULT]] @@ -56,6 +60,8 @@ public protocol MyResilientProtocol { // CHECK: [[WITNESS_ADDR:%.*]] = getelementptr inbounds i8*, i8** %3, i32 3 // CHECK-NEXT: [[WITNESS:%.*]] = load i8*, i8** [[WITNESS_ADDR]] // CHECK-NEXT: [[FN:%.*]] = bitcast i8* [[WITNESS]] to void (%Any*, %swift.opaque*, %swift.type*, i8**)* +// CHECK-arm64e-NEXT: ptrtoint i8** [[WITNESS_ADDR]] to i64 +// CHECK-arm64e-NEXT: call i64 @llvm.ptrauth.blend.i64 // CHECK-NEXT: call swiftcc void [[FN]](%Any* noalias nocapture sret %0, %swift.opaque* noalias nocapture swiftself %1, %swift.type* %2, i8** %3) // CHECK-NEXT: ret void @@ -63,6 +69,8 @@ public protocol MyResilientProtocol { // CHECK: [[WITNESS_ADDR:%.*]] = getelementptr inbounds i8*, i8** %3, i32 4 // CHECK-NEXT: [[WITNESS:%.*]] = load i8*, i8** [[WITNESS_ADDR]] // CHECK-NEXT: [[FN:%.*]] = bitcast i8* [[WITNESS]] to void (%swift.opaque*, %swift.error**, %swift.type*, i8**)* +// CHECK-arm64e-NEXT: ptrtoint i8** [[WITNESS_ADDR]] to i64 +// CHECK-arm64e-NEXT: call i64 @llvm.ptrauth.blend.i64 // CHECK-NEXT: call swiftcc void [[FN]](%swift.opaque* noalias nocapture swiftself %0, %swift.error**{{( noalias nocapture( swifterror)? dereferenceable\(.\))?}} %1, %swift.type* %2, i8** %3) // CHECK-NEXT: ret void @@ -70,6 +78,8 @@ public protocol MyResilientProtocol { // CHECK: [[WITNESS_ADDR:%.*]] = getelementptr inbounds i8*, i8** %5, i32 5 // CHECK-NEXT: [[WITNESS:%.*]] = load i8*, i8** [[WITNESS_ADDR]] // CHECK-NEXT: [[FN:%.*]] = bitcast i8* [[WITNESS]] to void (%swift.opaque*, %swift.opaque*, %swift.type*, %swift.opaque*, %swift.type*, i8**)* +// CHECK-arm64e-NEXT: ptrtoint i8** [[WITNESS_ADDR]] to i64 +// CHECK-arm64e-NEXT: call i64 @llvm.ptrauth.blend.i64 // CHECK-NEXT: call swiftcc void [[FN]](%swift.opaque* noalias nocapture sret %0, %swift.opaque* noalias nocapture %1, %swift.type* %2, %swift.opaque* noalias nocapture swiftself %3, %swift.type* %4, i8** %5) // CHECK-NEXT: ret void @@ -77,6 +87,8 @@ public protocol MyResilientProtocol { // CHECK: [[WITNESS_ADDR:%.*]] = getelementptr inbounds i8*, i8** %2, i32 6 // CHECK-NEXT: [[WITNESS:%.*]] = load i8*, i8** [[WITNESS_ADDR]] // CHECK-NEXT: [[FN:%.*]] = bitcast i8* [[WITNESS]] to i1 (%swift.opaque*, %swift.type*, i8**)* +// CHECK-arm64e-NEXT: ptrtoint i8** [[WITNESS_ADDR]] to i64 +// CHECK-arm64e-NEXT: call i64 @llvm.ptrauth.blend.i64 // CHECK-NEXT: [[RESULT:%.*]] = call swiftcc i1 %5(%swift.opaque* noalias nocapture swiftself %0, %swift.type* %1, i8** %2) // CHECK-NEXT: ret i1 [[RESULT]] @@ -84,6 +96,8 @@ public protocol MyResilientProtocol { // CHECK: [[WITNESS_ADDR:%.*]] = getelementptr inbounds i8*, i8** %3, i32 7 // CHECK-NEXT: [[WITNESS:%.*]] = load i8*, i8** [[WITNESS_ADDR]] // CHECK-NEXT: [[FN:%.*]] = bitcast i8* [[WITNESS]] to void (i1, %swift.opaque*, %swift.type*, i8**)* +// CHECK-arm64e-NEXT: ptrtoint i8** [[WITNESS_ADDR]] to i64 +// CHECK-arm64e-NEXT: call i64 @llvm.ptrauth.blend.i64 // CHECK-NEXT: call swiftcc void [[FN]](i1 %0, %swift.opaque* nocapture swiftself %1, %swift.type* %2, i8** %3) // CHECK-NEXT: ret void @@ -91,5 +105,7 @@ public protocol MyResilientProtocol { // CHECK: [[WITNESS_ADDR:%.*]] = getelementptr inbounds i8*, i8** %3, i32 8 // CHECK-NEXT: [[WITNESS:%.*]] = load i8*, i8** [[WITNESS_ADDR]] // CHECK-NEXT: [[FN:%.*]] = bitcast i8* [[WITNESS]] to { i8*, %TSb* } (i8*, %swift.opaque*, %swift.type*, i8**)* +// CHECK-arm64e-NEXT: ptrtoint i8** [[WITNESS_ADDR]] to i64 +// CHECK-arm64e-NEXT: call i64 @llvm.ptrauth.blend.i64 // CHECK-NEXT: [[RESULT:%.*]] = call swiftcc { i8*, %TSb* } [[FN]](i8* noalias dereferenceable({{16|32}}) %0, %swift.opaque* nocapture swiftself %1, %swift.type* %2, i8** %3) // CHECK-NEXT: ret { i8*, %TSb* } [[RESULT]] diff --git a/test/IRGen/ptrauth-blocks.sil b/test/IRGen/ptrauth-blocks.sil new file mode 100644 index 0000000000000..fa2ce0b38aeef --- /dev/null +++ b/test/IRGen/ptrauth-blocks.sil @@ -0,0 +1,70 @@ +// 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 + +// REQUIRES: CPU=arm64e +// REQUIRES: OS=ios + +import Builtin + +// CHECK: [[VOID_BLOCK_SIGNATURE:@.*]] = private unnamed_addr constant {{.*}} c"v8@?0\00" + +// CHECK: [[TRIVIAL_BLOCK_DESCRIPTOR:@.*]] = internal constant { {{.*}} } { i64 0, i64 40, i8* getelementptr inbounds ({{.*}} [[VOID_BLOCK_SIGNATURE]], i64 0, i64 0) } + +// CHECK: @block_copy_helper.ptrauth = private constant { i8*, i32, i64, i64 } { i8* bitcast ({{.*}}* @block_copy_helper to i8*), i32 0, i64 ptrtoint ({{.*}} getelementptr inbounds ({{.*}} [[NONTRIVIAL_BLOCK_DESCRIPTOR:@.*]], i32 0, i32 2) to i64), i64 0 }, section "llvm.ptrauth" +// CHECK: @block_destroy_helper.ptrauth = private constant { i8*, i32, i64, i64 } { i8* bitcast ({{.*}}* @block_destroy_helper to i8*), i32 0, i64 ptrtoint ({{.*}} getelementptr inbounds ({{.*}} [[NONTRIVIAL_BLOCK_DESCRIPTOR:@.*]], i32 0, i32 3) to i64), i64 0 }, section "llvm.ptrauth" +// CHECK: [[NONTRIVIAL_BLOCK_DESCRIPTOR]] = internal constant { {{.*}} } { i64 0, i64 40, void ({ %objc_block, %swift.refcounted* }*, {{.*}} bitcast ({{.*}} @block_copy_helper.ptrauth to {{.*}}), {{.*}} bitcast ({{.*}} @block_destroy_helper.ptrauth to {{.*}}), i8* getelementptr inbounds ({{.*}} [[VOID_BLOCK_SIGNATURE]], i64 0, i64 0) } + +sil @init_header_trivial : $@convention(thin) (@inout_aliasable @block_storage Builtin.RawPointer) -> @convention(block) () -> () { +entry(%0 : $*@block_storage Builtin.RawPointer): + %i = function_ref @invoke_trivial : $@convention(c) (@inout_aliasable @block_storage Builtin.RawPointer) -> () + %b = init_block_storage_header %0 : $*@block_storage Builtin.RawPointer, invoke %i : $@convention(c) (@inout_aliasable @block_storage Builtin.RawPointer) -> (), type $@convention(block) () -> () + return %b : $@convention(block) () -> () +} +// CHECK-LABEL: define swiftcc %objc_block* @init_header_trivial({ %objc_block, i8* }* +// CHECK: [[HEADER:%.*]] = getelementptr inbounds { %objc_block, i8* }, { %objc_block, i8* }* %0, i32 0, i32 0 +// CHECK: [[SLOT:%.*]] = getelementptr inbounds %objc_block, %objc_block* [[HEADER]], i32 0, i32 3 +// CHECK: [[T0:%.*]] = ptrtoint i8** [[SLOT]] to i64 +// CHECK: [[SIGNED:%.*]] = call i64 @llvm.ptrauth.sign.i64(i64 ptrtoint (void (void (...)*)* @invoke_trivial to i64), i32 0, i64 [[T0]]) +// CHECK: [[T0:%.*]] = inttoptr i64 [[SIGNED]] to i8* +// CHECK: store i8* [[T0]], i8** [[SLOT]], +// CHECK: [[SLOT:%.*]] = getelementptr inbounds %objc_block, %objc_block* [[HEADER]], i32 0, i32 4 +// CHECK: store i8* bitcast ({{.*}} [[TRIVIAL_BLOCK_DESCRIPTOR]] to i8*), i8** [[SLOT]] + +sil @invoke_trivial : $@convention(c) (@inout_aliasable @block_storage Builtin.RawPointer) -> () { +entry(%0 : $*@block_storage Builtin.RawPointer): + %c = project_block_storage %0 : $*@block_storage Builtin.RawPointer + return undef : $() +} + +sil @init_header_nontrivial : $@convention(thin) (@inout_aliasable @block_storage Builtin.NativeObject) -> @convention(block) () -> () { +entry(%0 : $*@block_storage Builtin.NativeObject): + %i = function_ref @invoke_nontrivial : $@convention(c) (@inout_aliasable @block_storage Builtin.NativeObject) -> () + %b = init_block_storage_header %0 : $*@block_storage Builtin.NativeObject, invoke %i : $@convention(c) (@inout_aliasable @block_storage Builtin.NativeObject) -> (), type $@convention(block) () -> () + return %b : $@convention(block) () -> () +} +// CHECK-LABEL: define swiftcc %objc_block* @init_header_nontrivial({ %objc_block, %swift.refcounted* }* +// CHECK: [[HEADER:%.*]] = getelementptr inbounds { %objc_block, %swift.refcounted* }, { %objc_block, %swift.refcounted* }* %0, i32 0, i32 0 +// CHECK: [[SLOT:%.*]] = getelementptr inbounds %objc_block, %objc_block* [[HEADER]], i32 0, i32 3 +// CHECK: [[T0:%.*]] = ptrtoint i8** [[SLOT]] to i64 +// CHECK: [[SIGNED:%.*]] = call i64 @llvm.ptrauth.sign.i64(i64 ptrtoint (void (void (...)*)* @invoke_nontrivial to i64), i32 0, i64 [[T0]]) +// CHECK: [[T0:%.*]] = inttoptr i64 [[SIGNED]] to i8* +// CHECK: store i8* [[T0]], i8** [[SLOT]], +// CHECK: [[SLOT:%.*]] = getelementptr inbounds %objc_block, %objc_block* [[HEADER]], i32 0, i32 4 +// CHECK: store i8* bitcast ({{.*}} [[NONTRIVIAL_BLOCK_DESCRIPTOR]] to i8*), i8** [[SLOT]] + +sil @invoke_nontrivial : $@convention(c) (@inout_aliasable @block_storage Builtin.NativeObject) -> () { +entry(%0 : $*@block_storage Builtin.NativeObject): + %c = project_block_storage %0 : $*@block_storage Builtin.NativeObject + return undef : $() +} + +sil @invoke_block : $@convention(thin) (@convention(block) () -> ()) -> () { +entry(%0 : $@convention(block) () -> ()): + apply %0() : $@convention(block) () -> () + return undef : $() +} +// CHECK-LABEL: define swiftcc void @invoke_block(%objc_block* %0) +// CHECK: [[SLOT:%.*]] = getelementptr inbounds %objc_block, %objc_block* %0, i32 0, i32 3 +// CHECK-NEXT: [[T0:%.*]] = load i8*, i8** [[SLOT]], align +// CHECK-NEXT: [[INVOKE:%.*]] = bitcast i8* [[T0]] to void (%objc_block*)* +// CHECK-NEXT: [[DISC:%.*]] = ptrtoint i8** [[SLOT]] to i64 +// CHECK-NEXT: call void [[INVOKE]](%objc_block* %0) [ "ptrauth"(i32 0, i64 [[DISC]]) ] diff --git a/test/IRGen/ptrauth-class-methods.sil b/test/IRGen/ptrauth-class-methods.sil new file mode 100644 index 0000000000000..f74dca135ea92 --- /dev/null +++ b/test/IRGen/ptrauth-class-methods.sil @@ -0,0 +1,103 @@ +// 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 + +// REQUIRES: CPU=arm64e +// REQUIRES: OS=ios + +import Builtin + +// CHECK: @"$s4test1ACfD.ptrauth" = private constant { i8*, i32, i64, i64 } { i8* bitcast (void (%T4test1AC*)* @"$s4test1ACfD" to i8*), i32 0, i64 ptrtoint ({{.*}} @"$s4test1ACMf" to i64), i64 48063 }, section "llvm.ptrauth", align 8 +// CHECK: @A_foo.ptrauth = private constant { i8*, i32, i64, i64 } { i8* bitcast (void (%T4test1AC*)* @A_foo to i8*), i32 0, i64 ptrtoint ({{.*}} getelementptr inbounds ({{.*}} @"$s4test1ACMf", i32 0, i32 {{.*}}) to i64), i64 23008 }, section "llvm.ptrauth", align 8 +// CHECK: @"$s4test1BCfD.ptrauth" = private constant { i8*, i32, i64, i64 } { i8* bitcast (void (%T4test1BC*)* @"$s4test1BCfD" to i8*), i32 0, i64 ptrtoint ({{.*}} @"$s4test1BCMf" to i64), i64 48063 }, section "llvm.ptrauth", align 8 +// CHECK: @B_foo.ptrauth = private constant { i8*, i32, i64, i64 } { i8* bitcast (void (%T4test1BC*)* @B_foo to i8*), i32 0, i64 ptrtoint ({{.*}} getelementptr inbounds ({{.*}} @"$s4test1BCMf", i32 0, i32 {{.*}}) to i64), i64 23008 }, section "llvm.ptrauth", align 8 + +// CHECK: @"$s4test1GCMn" = +// -1212481520 == 0xb7bb0010. 0xb7bb == 47035. +// CHECK-SAME: i32 -1212481520, {{.*}} @G_bar + +open class A { + deinit {} + open func foo() +} + +open class B : A { + deinit {} + override open func foo() +} + +open class G { + open func bar() +} + +sil @A_foo : $@convention(method) (@guaranteed A) -> () +sil @B_foo : $@convention(method) (@guaranteed B) -> () +sil @G_bar : $@convention(method) (@guaranteed G) -> () + +sil @$s4test1ACfD : $@convention(method) (@owned A) -> () +sil @$s4test1BCfD : $@convention(method) (@owned B) -> () + +sil_vtable A { + #A.deinit!deallocator.1: (A) -> () -> () : @$s4test1ACfD + #A.foo!1: (A) -> () -> () : @A_foo +} +sil_vtable B { + #B.deinit!deallocator.1: (B) -> () -> () : @$s4test1BCfD + #A.foo!1: (A) -> () -> () : @B_foo [override] +} +sil_vtable G { + #G.bar!1: @G_bar +} + +sil @test_call_a : $@convention(thin) (@guaranteed A) -> () { +bb0(%0 : $A): + %1 = class_method %0 : $A, #A.foo!1 : (A) -> () -> (), $@convention(method) (@guaranteed A) -> () + %2 = apply %1(%0) : $@convention(method) (@guaranteed A) -> () + return %2 : $() +} +// CHECK-LABEL: define swiftcc void @test_call_a(%T4test1AC* %0) +// CHECK: [[T0:%.*]] = bitcast %T4test1AC* %0 to %swift.type** +// CHECK-NEXT: [[META:%.*]] = load %swift.type*, %swift.type** [[T0]], align +// CHECK-NEXT: [[T0:%.*]] = bitcast %swift.type* [[META]] to void (%T4test1AC*)** +// CHECK-NEXT: [[SLOT:%.*]] = getelementptr inbounds void (%T4test1AC*)*, void (%T4test1AC*)** [[T0]], i64 {{.*}} +// CHECK-NEXT: [[FN:%.*]] = load void (%T4test1AC*)*, void (%T4test1AC*)** [[SLOT]] +// CHECK-NEXT: [[T0:%.*]] = ptrtoint void (%T4test1AC*)** [[SLOT]] to i64 +// Discriminator value is arbitrary, but must be the same as the next test. +// CHECK-NEXT: [[DISCRIMINATOR:%.*]] = call i64 @llvm.ptrauth.blend.i64(i64 [[T0]], i64 23008) +// CHECK-NEXT: call swiftcc void [[FN]](%T4test1AC* swiftself %0) [ "ptrauth"(i32 0, i64 [[DISCRIMINATOR]]) ] +// CHECK-NEXT: ret void + +sil @test_call_b : $@convention(thin) (@guaranteed B) -> () { +bb0(%0 : $B): + %1 = class_method %0 : $B, #B.foo!1 : (B) -> () -> (), $@convention(method) (@guaranteed B) -> () + %2 = apply %1(%0) : $@convention(method) (@guaranteed B) -> () + return %2 : $() +} +// CHECK-LABEL: define swiftcc void @test_call_b(%T4test1BC* %0) +// CHECK: [[T0:%.*]] = bitcast %T4test1BC* %0 to %swift.type** +// CHECK-NEXT: [[META:%.*]] = load %swift.type*, %swift.type** [[T0]], align +// CHECK-NEXT: [[T0:%.*]] = bitcast %swift.type* [[META]] to void (%T4test1BC*)** +// CHECK-NEXT: [[SLOT:%.*]] = getelementptr inbounds void (%T4test1BC*)*, void (%T4test1BC*)** [[T0]], i64 {{.*}} +// CHECK-NEXT: [[FN:%.*]] = load void (%T4test1BC*)*, void (%T4test1BC*)** [[SLOT]] +// CHECK-NEXT: [[T0:%.*]] = ptrtoint void (%T4test1BC*)** [[SLOT]] to i64 +// Discriminator value is arbitrary, but must be the same as the previous test. +// CHECK-NEXT: [[DISCRIMINATOR:%.*]] = call i64 @llvm.ptrauth.blend.i64(i64 [[T0]], i64 23008) +// CHECK-NEXT: call swiftcc void [[FN]](%T4test1BC* swiftself %0) [ "ptrauth"(i32 0, i64 [[DISCRIMINATOR]]) ] +// CHECK-NEXT: ret void + +sil @test_call_g : $@convention(thin) (@guaranteed G) -> () { +bb0(%0 : $G): + %1 = class_method %0 : $G, #G.bar!1 : (G) -> () -> (), $@convention(method) (@guaranteed G) -> () + %2 = apply %1(%0) : $@convention(method) (@guaranteed G) -> () + return %2 : $() +} +// CHECK-LABEL: define swiftcc void @test_call_g(%T4test1GC* %0) +// CHECK: [[T0:%.*]] = bitcast %T4test1GC* %0 to %swift.type** +// CHECK: [[T0:%.*]] = bitcast %T4test1GC* %0 to %swift.type** +// CHECK-NEXT: [[META:%.*]] = load %swift.type*, %swift.type** [[T0]], align +// CHECK-NEXT: [[T0:%.*]] = bitcast %swift.type* [[META]] to void (%T4test1GC*)** +// CHECK-NEXT: [[SLOT:%.*]] = getelementptr inbounds void (%T4test1GC*)*, void (%T4test1GC*)** [[T0]], i64 {{.*}} +// CHECK-NEXT: [[FN:%.*]] = load void (%T4test1GC*)*, void (%T4test1GC*)** [[SLOT]] +// CHECK-NEXT: [[T0:%.*]] = ptrtoint void (%T4test1GC*)** [[SLOT]] to i64 +// Discriminator value is arbitrary, but must be the same as the previous test. +// CHECK-NEXT: [[DISCRIMINATOR:%.*]] = call i64 @llvm.ptrauth.blend.i64(i64 [[T0]], i64 47035) +// CHECK-NEXT: call swiftcc void [[FN]](%T4test1GC* swiftself %0) [ "ptrauth"(i32 0, i64 [[DISCRIMINATOR]]) ] +// CHECK-NEXT: ret void diff --git a/test/IRGen/ptrauth-classes.sil b/test/IRGen/ptrauth-classes.sil new file mode 100644 index 0000000000000..e97f71f290e71 --- /dev/null +++ b/test/IRGen/ptrauth-classes.sil @@ -0,0 +1,21 @@ +// 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 + +// REQUIRES: CPU=arm64e +// REQUIRES: OS=ios + +import Builtin + +class A {} +sil_vtable A {} + +// rdar://35018215 +struct S {} +class B : A {} +sil_vtable B {} + +// CHECK-LABEL: define internal %swift.type* @"$s4test1ACMi"(%swift.type_descriptor* %0, i8** %1, i8* %2) +// CHECK: [[INT:%.*]] = ptrtoint %swift.type_descriptor* %0 to i64 +// CHECK: [[SIGNED:%.*]] = call i64 @llvm.ptrauth.sign.i64(i64 [[INT]], i32 2, i64 44678) +// CHECK: [[PTR:%.*]] = inttoptr i64 [[SIGNED]] to %swift.type_descriptor* +// CHECK: [[METADATA:%.*]] = call %swift.type* @swift_allocateGenericClassMetadata(%swift.type_descriptor* [[PTR]], i8** %1, i8* %2) +// CHECK: ret %swift.type* [[METADATA]] diff --git a/test/IRGen/ptrauth-dynamic_replaceable.sil b/test/IRGen/ptrauth-dynamic_replaceable.sil new file mode 100644 index 0000000000000..c588977888bb8 --- /dev/null +++ b/test/IRGen/ptrauth-dynamic_replaceable.sil @@ -0,0 +1,100 @@ +// RUN: %target-swift-frontend %s -emit-ir -disable-objc-interop -module-name A | %FileCheck %s + +// REQUIRES: objc_interop +// REQUIRES: CPU=arm64e + +// CHECK: @test_dynamically_replaceableTX = global %swift.dyn_repl_link_entry { i8*{{.*}} @test_dynamically_replaceable.ptrauth to i8*), %swift.dyn_repl_link_entry* null } +// CHECK: @test_dynamically_replaceable.ptrauth = private constant { i8*, i32, i64, i64 } { i8* bitcast (void ()* @test_dynamically_replaceable to i8*), i32 0, i64 ptrtoint (%swift.dyn_repl_link_entry* @test_dynamically_replaceableTX to i64), i64 679 }, section "llvm.ptrauth" +// CHECK: @test_dynamically_replaceableTx = constant %swift.dyn_repl_key { i32 trunc ([[INTPTR:i[0-9]+]] sub ([[INTPTR]] ptrtoint (%swift.dyn_repl_link_entry* @test_dynamically_replaceableTX to [[INTPTR]]), [[INTPTR]] ptrtoint (%swift.dyn_repl_key* @test_dynamically_replaceableTx to [[INTPTR]])) to i32), i32 679 }, section "__TEXT,__const" +// CHECK: @test_replacementTX = global %swift.dyn_repl_link_entry zeroinitializer +// CHECK: @test_replacement_for_externalTX = global %swift.dyn_repl_link_entry zeroinitializer +// CHECK: @external_test_dynamically_replaceableTx = external global %swift.dyn_repl_key +// CHECK: @got.external_test_dynamically_replaceableTx = private unnamed_addr constant %swift.dyn_repl_key* bitcast ({ i8*, i32, i64, i64 }* @external_test_dynamically_replaceableTx.ptrauth to %swift.dyn_repl_key*) +// CHECK: @external_test_dynamically_replaceableTx.ptrauth = private constant { i8*, i32, i64, i64 } { i8* bitcast (%swift.dyn_repl_key* @external_test_dynamically_replaceableTx to i8*), i32 2, i64 ptrtoint (%swift.dyn_repl_key** @got.external_test_dynamically_replaceableTx to i64), i64 11389 }, section "llvm.ptrauth" + +// CHECK: @"\01l_unnamed_dynamic_replacements" = private constant { i32, i32, [2 x { i32, i32, i32, i32 }] } +// CHECK: { i32 0, +// CHECK: i32 2, +// CHECK: [2 x { i32, i32, i32, i32 }] +// CHECK: [{ i32, i32, i32, i32 } +// CHECK: %swift.dyn_repl_key* @test_dynamically_replaceableTx +// CHECK: @test_replacement +// CHECK: %swift.dyn_repl_link_entry* @test_replacementTX +// CHECK: i32 0 }, +// CHECK: { i32, i32, i32, i32 } +// CHECK: %swift.dyn_repl_key** @got.external_test_dynamically_replaceableTx +// CHECK: @test_replacement_for_external +// CHECK: %swift.dyn_repl_link_entry* @test_replacement_for_externalTX +// CHECK: i32 0 }] }, section "__TEXT,__const" + +// CHECK: @"\01l_auto_dynamic_replacements" = private constant { i32, i32, [2 x i32] } +// CHECK: { i32 0, i32 1, +// CHECK: [2 x i32] [{{.*}}@"\01l_unnamed_dynamic_replacements"{{.*}}, i32 0] +// CHECK: }, section "__TEXT, __swift5_replace, regular, no_dead_strip" + +// CHECK-LABEL: define swiftcc void @test_dynamically_replaceable() +// CHECK-NEXT: entry: +// CHECK-NEXT: [[FUN_PTR:%.*]] = call i8* @swift_getFunctionReplacement{{.*}}({{.*}} getelementptr {{.*}} @test_dynamically_replaceableTX, i32 0, i32 0 +// CHECK-NEXT: [[CMP:%.*]] = icmp eq i8* [[FUN_PTR]], null +// CHECK-NEXT: br i1 [[CMP]], label %original_entry, label %forward_to_replaced +// CHECK: forward_to_replaced: +// CHECK-NEXT: [[TYPED_PTR:%.*]] = bitcast i8* [[FUN_PTR]] to void ()* +// CHECK-NEXT: [[BLEND:%.*]] = call i64 @llvm.ptrauth.blend.i64(i64 ptrtoint (%swift.dyn_repl_link_entry* @test_dynamically_replaceableTX to i64), i64 679) +// CHECK-NEXT: tail call swiftcc void [[TYPED_PTR]]() [ "ptrauth"(i32 0, i64 [[BLEND]]) ] +// CHECK-NEXT: ret void +// CHECK: original_entry: +// CHECK-NEXT: ret void +// CHECK-NEXT: } + +sil [dynamically_replacable] @test_dynamically_replaceable : $@convention(thin) () -> () { +bb0: + %0 = tuple () + return %0 : $() +} + +// CHECK-LABEL: define swiftcc void @test_replacement() +// CHECK: entry: +// CHECK: call swiftcc void @test_replacementTI() +// CHECK: ret void +// CHECK: } + +// The thunk that implement the prev_dynamic_function_ref lookup. +// CHECK-LABEL: define swiftcc void @test_replacementTI() +// CHECK: entry: +// CHECK: [[FUN_PTR:%.*]] = call i8* @swift_getOrigOfReplaceable{{.*}}({{.*}} getelementptr {{.*}} @test_replacementTX, i32 0, i32 0 +// CHECK: [[TYPED_PTR:%.*]] = bitcast i8* [[FUN_PTR]] to void ()* +// CHECK-NEXT: [[BLEND:%.*]] = call i64 @llvm.ptrauth.blend.i64(i64 ptrtoint (%swift.dyn_repl_link_entry* @test_replacementTX to i64), i64 679) +// CHECK-NEXT: call swiftcc void [[TYPED_PTR]]() [ "ptrauth"(i32 0, i64 [[BLEND]]) ] +// CHECK: ret void +// CHECK: } +sil [dynamic_replacement_for "test_dynamically_replaceable"] @test_replacement : $@convention(thin) () -> () { +bb0: + %0 = prev_dynamic_function_ref @test_replacement : $@convention(thin) () -> () + %1 = apply %0() : $@convention(thin) () -> () + %2 = tuple () + return %2 : $() +} + +// CHECK-LABEL: define swiftcc void @test_dynamic_call() +// CHECK: entry: +// CHECK: call swiftcc void @test_dynamically_replaceable() +// CHECK: ret void +// CHECK: } +sil @test_dynamic_call : $@convention(thin) () -> () { +bb0: + %0 = dynamic_function_ref @test_dynamically_replaceable : $@convention(thin) () -> () + %1 = apply %0() : $@convention(thin) () -> () + %2 = tuple () + return %2 : $() +} + + +sil [dynamically_replacable] @external_test_dynamically_replaceable : $@convention(thin) () -> () + +sil [dynamic_replacement_for "external_test_dynamically_replaceable"] @test_replacement_for_external : $@convention(thin) () -> () { +bb0: + %0 = prev_dynamic_function_ref @test_replacement : $@convention(thin) () -> () + %1 = apply %0() : $@convention(thin) () -> () + %2 = tuple () + return %2 : $() +} diff --git a/test/IRGen/ptrauth-dynamic_replaceable_opaque_return.swift b/test/IRGen/ptrauth-dynamic_replaceable_opaque_return.swift new file mode 100644 index 0000000000000..7001e34dd9d3b --- /dev/null +++ b/test/IRGen/ptrauth-dynamic_replaceable_opaque_return.swift @@ -0,0 +1,59 @@ +// RUN: %target-swift-frontend -disable-availability-checking -module-name A -swift-version 5 -primary-file %s -emit-ir | %FileCheck %s + +// REQUIRES: CPU=arm64e + +// CHECK: @"$s1A3baryQrSiFQOMk" = global %swift.dyn_repl_link_entry { {{.*}}@"$s1A3baryQrSiFQOMh.ptrauth" to i8*), %swift.dyn_repl_link_entry* null } +// CHECK: @"$s1A3baryQrSiFQOMh.ptrauth" = private constant { i8*, i32, i64, i64 } { {{.*}}@"$s1A3baryQrSiFQOMh" to i8*), i32 0, i64 ptrtoint (%swift.dyn_repl_link_entry* @"$s1A3baryQrSiFQOMk" to i64), i64 44678 }, section "llvm.ptrauth" +// CHECK: @"$s1A3baryQrSiFQOMj" = constant %swift.dyn_repl_key { {{.*}}%swift.dyn_repl_link_entry* @"$s1A3baryQrSiFQOMk"{{.*}}, i32 44678 }, section "__TEXT,__const" +// CHECK: @"$s1A16_replacement_bar1yQrSi_tFQOMk" = global %swift.dyn_repl_link_entry zeroinitializer +// CHECK: @"\01l_unnamed_dynamic_replacements" = +// CHECK: private constant { i32, i32, [2 x { i32, i32, i32, i32 }] } +// CHECK: { i32 0, i32 2, [2 x { i32, i32, i32, i32 }] [ +// CHECK: { i32, i32, i32, i32 } { {{.*}}%swift.dyn_repl_key* @"$s1A3baryQrSiFTx"{{.*}}@"$s1A16_replacement_bar1yQrSi_tF"{{.*}}%swift.dyn_repl_link_entry* @"$s1A16_replacement_bar1yQrSi_tFTX"{{.*}}, i32 0 }, +// CHECK: { i32, i32, i32, i32 } { {{.*}}%swift.dyn_repl_key* @"$s1A3baryQrSiFQOMj"{{.*}},{{.*}}@"$s1A16_replacement_bar1yQrSi_tFQOMg"{{.*}},{{.*}}@"$s1A16_replacement_bar1yQrSi_tFQOMk"{{.*}}, i32 0 }] }, section "__TEXT,__const", align 8 + +public protocol P { + func myValue() -> Int +} + +extension Int: P { + public func myValue() -> Int { + return self + } +} +// Opaque result type descriptor accessor for bar. +// CHECK-LABEL: define swiftcc %swift.type_descriptor* @"$s1A3baryQrSiFQOMg"() +// CHECK: entry: +// CHECK: %0 = load i8*, i8** getelementptr inbounds (%swift.dyn_repl_link_entry, %swift.dyn_repl_link_entry* @"$s1A3baryQrSiFQOMk", i32 0, i32 0) +// CHECK: %1 = bitcast i8* %0 to %swift.type_descriptor* ()* +// CHECK: %2 = call i64 @llvm.ptrauth.blend.i64(i64 ptrtoint (%swift.dyn_repl_link_entry* @"$s1A3baryQrSiFQOMk" to i64), i64 44678) +// CHECK: %3 = tail call swiftcc %swift.type_descriptor* %1() [ "ptrauth"(i32 0, i64 %2) ] +// CHECK: ret %swift.type_descriptor* %3 +// CHECK: } + +// Opaque result type descriptor accessor impl. +// CHECK-LABEL: define swiftcc %swift.type_descriptor* @"$s1A3baryQrSiFQOMh"() +// CHECK: entry: +// CHECK: ret %swift.type_descriptor* bitcast ({{.*}}* @"$s1A3baryQrSiFQOMQ" to %swift.type_descriptor*) +// CHECK: } + +public dynamic func bar(_ x: Int) -> some P { + return x +} + +struct Pair : P { + var x = 0 + var y = 1 + func myValue() -> Int{ + return y + } +} +// Opaque result type descriptor accessor for _replacement_bar. +// CHECK: define swiftcc %swift.type_descriptor* @"$s1A16_replacement_bar1yQrSi_tFQOMg"() +// CHECK: entry: +// CHECK: ret %swift.type_descriptor* bitcast ({{.*}} @"$s1A16_replacement_bar1yQrSi_tFQOMQ" to %swift.type_descriptor*) +// CHECK: } +@_dynamicReplacement(for:bar(_:)) +public func _replacement_bar(y x: Int) -> some P { + return Pair() +} diff --git a/test/IRGen/ptrauth-foreign.sil b/test/IRGen/ptrauth-foreign.sil new file mode 100644 index 0000000000000..17a3d6b2b90e4 --- /dev/null +++ b/test/IRGen/ptrauth-foreign.sil @@ -0,0 +1,29 @@ +// RUN: %swift -module-name test -import-objc-header %S/Inputs/ptrauth-foreign.h %s -parse-stdlib -parse-as-library -emit-ir -target arm64e-apple-ios12.0 | %FileCheck %s --check-prefix=CHECK + +// REQUIRES: CPU=arm64e +// REQUIRES: OS=ios + +sil @test0 : $() -> () { +bb0: + %0 = metatype $@thick IntPair.Type + +// CHECK: @"$sSo9WidgetRefaMn.ptrauth" = +// CHECK-SAME: @"$sSo9WidgetRefaMn" +// CHECK-SAME: @"$sSo9WidgetRefaMf", i32 0, i32 2 +// CHECK-SAME: i64 44678 +// CHECK-SAME: section "llvm.ptrauth" +// CHECK: @"$sSo9WidgetRefaMf" = linkonce_odr hidden constant +// CHECK-SAME: @"$sSo9WidgetRefaMn.ptrauth" + %1 = metatype $@thick Widget.Type + +// CHECK: @"$sSo7IntPairVMn.ptrauth" = +// CHECK-SAME: @"$sSo7IntPairVMn" +// CHECK-SAME: @"$sSo7IntPairVMf", i32 0, i32 2 +// CHECK-SAME: i64 44678 +// CHECK-SAME: section "llvm.ptrauth" +// CHECK: @"$sSo7IntPairVMf" = linkonce_odr hidden constant +// CHECK-SAME: @"$sSo7IntPairVMn.ptrauth" + + %ret = tuple () + return %ret : $() +} diff --git a/test/IRGen/ptrauth-functions.sil b/test/IRGen/ptrauth-functions.sil new file mode 100644 index 0000000000000..9606671228345 --- /dev/null +++ b/test/IRGen/ptrauth-functions.sil @@ -0,0 +1,90 @@ +// 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 + +// REQUIRES: CPU=arm64e +// REQUIRES: OS=ios + +import Builtin + +// CHECK: @global_function.ptrauth = private constant { i8*, i32, i64, i64 } { i8* bitcast (void ()* @global_function to i8*), i32 0, i64 0, i64 {{.*}} }, section "llvm.ptrauth", align 8 + +sil @global_function : $@convention(thin) () -> () + +sil @test_sign : $@convention(thin) () -> @convention(thin) () -> () { +bb0: + %0 = function_ref @global_function : $@convention(thin) () -> () + return %0 : $@convention(thin) () -> () +} +// CHECK-LABEL: define swiftcc i8* @test_sign() +// CHECK: ret i8* bitcast ({ i8*, i32, i64, i64 }* @global_function.ptrauth to i8*) + +sil @test_direct_call : $@convention(thin) () -> () { +bb0: + %0 = function_ref @global_function : $@convention(thin) () -> () + %1 = apply %0() : $@convention(thin) () -> () + return %1 : $() +} +// CHECK-LABEL: define swiftcc void @test_direct_call() +// CHECK: call swiftcc void @global_function(){{$}} + +sil @test_indirect_call_thin : $@convention(thin) (@convention(thin) () -> ()) -> () { +bb0(%0 : $@convention(thin) () -> ()): + %1 = apply %0() : $@convention(thin) () -> () + return %1 : $() +} +// CHECK-LABEL: define swiftcc void @test_indirect_call_thin(i8* %0) +// CHECK: [[CAST:%.*]] = bitcast i8* %0 to void ()* +// CHECK-NEXT: call swiftcc void [[CAST]]() [ "ptrauth"(i32 0, i64 {{.*}}) ] + +sil @test_indirect_call_thick : $@convention(thin) (@guaranteed @callee_guaranteed () -> ()) -> () { +bb0(%0 : $@callee_guaranteed () -> ()): + %1 = apply %0() : $@callee_guaranteed () -> () + return %1 : $() +} +// CHECK-LABEL: define swiftcc void @test_indirect_call_thick(i8* %0, %swift.refcounted* %1) +// CHECK: [[CAST:%.*]] = bitcast i8* %0 to void (%swift.refcounted*)* +// CHECK-NEXT: call swiftcc void [[CAST]](%swift.refcounted* swiftself %1) [ "ptrauth"(i32 0, i64 {{.*}}) ] + +sil @test_indirect_call_c : $@convention(thin) (@convention(c) () -> ()) -> () { +bb0(%0 : $@convention(c) () -> ()): + %1 = apply %0() : $@convention(c) () -> () + return %1 : $() +} +// CHECK-LABEL: define swiftcc void @test_indirect_call_c(i8* %0) +// CHECK: [[CAST:%.*]] = bitcast i8* %0 to void ()* +// CHECK-NEXT: call void [[CAST]]() [ "ptrauth"(i32 0, i64 {{.*}}) ] + +sil @test_thin_to_thick : $@convention(thin) (@convention(thin) () -> ()) -> (@callee_guaranteed () -> ()) { +bb0(%0 : $@convention(thin) () -> ()): + %1 = thin_to_thick_function %0 : $@convention(thin) () -> () to $@callee_guaranteed () -> () + return %1 : $@callee_guaranteed () -> () +} + +// CHECK-LABEL: define swiftcc { i8*, %swift.refcounted* } @test_thin_to_thick(i8* %0) +// CHECK: [[T0:%.*]] = insertvalue { i8*, %swift.refcounted* } undef, i8* %0, 0 +// CHECK-NEXT: [[T1:%.*]] = insertvalue { i8*, %swift.refcounted* } [[T0]], %swift.refcounted* null, 1 +// CHECK-NEXT: ret { i8*, %swift.refcounted* } [[T1]] + +sil @test_sign_thin_to_thick : $@convention(thin) () -> (@callee_guaranteed () -> ()) { +bb0: + %0 = function_ref @global_function : $@convention(thin) () -> () + %1 = thin_to_thick_function %0 : $@convention(thin) () -> () to $@callee_guaranteed () -> () + return %1 : $@callee_guaranteed () -> () +} +// CHECK: define swiftcc { i8*, %swift.refcounted* } @test_sign_thin_to_thick() #[[ATTRS:[0-9]+]] { +// CHECK: ret { i8*, %swift.refcounted* } { i8* bitcast ({ i8*, i32, i64, i64 }* @global_function.ptrauth to i8*), %swift.refcounted* null } + +class F {} +sil @generic_return : $@convention(thin) @yield_once (@guaranteed T) -> @yields @guaranteed T + +sil @test_generic_return : $@convention(thin) (@guaranteed T) -> () { +bb0(%0 : $T): + %1 = function_ref @generic_return : $@convention(thin) @yield_once (@guaranteed T) -> (@yields @guaranteed T) + (%value, %token) = begin_apply %1(%0) : $@convention(thin) @yield_once (@guaranteed T) -> (@yields @guaranteed T) + end_apply %token + %ret = tuple () + return %ret : $() +} + +sil_vtable F { +} +// CHECK: #[[ATTRS]] = {{{.*}} "ptrauth-calls" "ptrauth-returns" diff --git a/test/IRGen/ptrauth-objc-partial-apply.sil b/test/IRGen/ptrauth-objc-partial-apply.sil new file mode 100644 index 0000000000000..4b82d971fc564 --- /dev/null +++ b/test/IRGen/ptrauth-objc-partial-apply.sil @@ -0,0 +1,34 @@ +// 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 +// REQUIRES: objc_interop + +// REQUIRES: CPU=arm64e +// REQUIRES: OS=ios + +// CHECK: @"$sTa.ptrauth" = private constant { i8*, i32, i64, i64 } { i8* bitcast (void (%swift.refcounted*)* @"$sTa" to i8*), i32 0, i64 0, i64 {{.*}} }, section "llvm.ptrauth" + +@objc class A { + @objc func foo() {} +} + +sil_vtable A {} + +sil hidden @$s4test1AC3fooyyF : $@convention(method) (@guaranteed A) -> () { +bb0(%0 : $A): + unreachable +} +sil hidden [thunk] @$s4test1AC3fooyyFTo : $@convention(objc_method) (A) -> () { +bb0(%0 : $A): + unreachable +} + +// It would also be reasonable to not apply ptrauth here, but as long as we're partial_apply +// CHECK-LABEL: define swiftcc void @test0( +// CHECK: call swiftcc void bitcast ({ i8*, i32, i64, i64 }* @"$sTa.ptrauth" to void (%swift.refcounted*)*)(%swift.refcounted* swiftself {{%.*}}) [ "ptrauth"(i32 0, i64 {{.*}}) ] +sil @test0 : $@convention(thin) (@guaranteed A) -> () { +bb0(%0: $A): + %method = objc_method %0 : $A, #A.foo!1.foreign, $@convention(objc_method) (A) -> () + %partial = partial_apply [callee_guaranteed] %method(%0) : $@convention(objc_method) (A) -> () + apply %partial() : $ @callee_guaranteed () -> () + %result = tuple () + return %result : $() +} diff --git a/test/IRGen/ptrauth-objc.swift b/test/IRGen/ptrauth-objc.swift new file mode 100644 index 0000000000000..8393be7bd9fb5 --- /dev/null +++ b/test/IRGen/ptrauth-objc.swift @@ -0,0 +1,18 @@ +// 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 + +// REQUIRES: CPU=arm64e +// REQUIRES: OS=ios + +@objc class A { + @objc func foo() {} +} + +// CHECK: @"$s4test1AC3fooyyFTo.ptrauth" = private constant { i8*, i32, i64, i64 } { i8* bitcast (void (%0*, i8*)* @"$s4test1AC3fooyyFTo" to i8*), i32 0, i64 ptrtoint (i8** getelementptr inbounds ({ i32, i32, [1 x { i8*, i8*, i8* }] }, { i32, i32, [1 x { i8*, i8*, i8* }] }* @_INSTANCE_METHODS__TtC4test1A, i32 0, i32 2, i32 0, i32 2) to i64), i64 0 }, section "llvm.ptrauth" + +@objc protocol P { + func bar() +} +@objc class B : P { + func bar() {} +} +// CHECK: @_PROTOCOL_INSTANCE_METHODS__TtP4test1P_ = {{.*}} [{ i8*, i8*, i8* } { i8* getelementptr inbounds ([4 x i8], [4 x i8]* @"\01L_selector_data(bar)", i64 0, i64 0), i8* getelementptr inbounds ([8 x i8], [8 x i8]* {{@.*}}, i64 0, i64 0), i8* null }] diff --git a/test/IRGen/ptrauth-partial-apply.sil b/test/IRGen/ptrauth-partial-apply.sil new file mode 100644 index 0000000000000..52e6a651aa0bb --- /dev/null +++ b/test/IRGen/ptrauth-partial-apply.sil @@ -0,0 +1,64 @@ +// 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 + +// REQUIRES: CPU=arm64e +// REQUIRES: OS=ios + +import Builtin + +// CHECK: @"$sTA.ptrauth" = private constant { i8*, i32, i64, i64 } { i8* bitcast (void (%swift.refcounted*)* @"$sTA" to i8*), i32 0, i64 0, i64 {{.*}} }, section "llvm.ptrauth" + +sil @test_thin_indirect : $@convention(thin) (@convention(thin) (Builtin.Int32, Builtin.Int32) -> (), Builtin.Int32) -> @owned @callee_owned () -> () { +bb0(%0 : $@convention(thin) (Builtin.Int32, Builtin.Int32) -> (), %1 : $Builtin.Int32): + %2 = partial_apply %0(%1, %1) : $@convention(thin) (Builtin.Int32, Builtin.Int32) -> () + return %2 : $@callee_owned () -> () +} +// CHECK-LABEL: define swiftcc { i8*, %swift.refcounted* } @test_thin_indirect(i8* %0, i32 %1) +// CHECK: [[FN:%.*]] = bitcast i8* %0 to void (i32, i32)* +// CHECK: [[ALLOC:%.*]] = call {{.*}}swift_allocObject( +// CHECK: [[CTXT:%.*]] = bitcast %swift.refcounted* [[ALLOC]] to [[CTXT_TY:<{ %swift.refcounted, i32, i32, i8\* }>]]* +// CHECK: [[SLOT:%.*]] = getelementptr inbounds [[CTXT_TY]], [[CTXT_TY]]* [[CTXT]], i32 0, i32 3 +// CHECK: [[T0:%.*]] = ptrtoint i8** [[SLOT]] to i64 +// CHECK: [[DISC:%.*]] = call i64 @llvm.ptrauth.blend.i64(i64 [[T0]], i64 7185) +// CHECK: [[T0:%.*]] = ptrtoint void (i32, i32)* [[FN]] to i64 +// CHECK: [[T1:%.*]] = call i64 @llvm.ptrauth.resign.i64(i64 [[T0]], i32 0, i64 {{.*}}, i32 1, i64 [[DISC]]) +// CHECK: [[T2:%.*]] = inttoptr i64 [[T1]] to void (i32, i32)* +// CHECK: [[T3:%.*]] = bitcast void (i32, i32)* [[T2]] to i8* +// CHECK: store i8* [[T3]], i8** [[SLOT]], align 8 +// CHECK: insertvalue { i8*, %swift.refcounted* } { i8* bitcast ({ i8*, i32, i64, i64 }* @"$sTA.ptrauth" to i8*), %swift.refcounted* undef }, %swift.refcounted* {{.*}}, 1 + +// CHECK-LABEL: define internal swiftcc void @"$sTA"(%swift.refcounted* swiftself %0) +// CHECK: [[T0:%.*]] = bitcast %swift.refcounted* %0 to [[CTXT_TY:<{ %swift.refcounted, i32, i32, i8\* }>]]* +// CHECK: [[SLOT:%.*]] = getelementptr inbounds [[CTXT_TY]], [[CTXT_TY]]* [[T0]], i32 0, i32 3 +// CHECK: [[T0:%.*]] = load i8*, i8** [[SLOT]], align 8 +// CHECK: [[FN:%.*]] = bitcast i8* [[T0]] to void (i32, i32)* +// CHECK: [[T0:%.*]] = ptrtoint i8** [[SLOT]] to i64 +// CHECK: [[DISC:%.*]] = call i64 @llvm.ptrauth.blend.i64(i64 [[T0]], i64 7185) +// CHECK: call swiftcc void [[FN]](i32 {{.*}}, i32 {{.*}}) [ "ptrauth"(i32 1, i64 [[DISC]]) ] + +sil @test_thick_indirect : $@convention(thin) (@callee_owned (Builtin.Int32, Builtin.Int32) -> (), Builtin.Int32) -> @owned @callee_owned () -> () { +bb0(%0 : $@callee_owned (Builtin.Int32, Builtin.Int32) -> (), %1 : $Builtin.Int32): + %2 = partial_apply %0(%1, %1) : $@callee_owned (Builtin.Int32, Builtin.Int32) -> () + return %2 : $@callee_owned () -> () +} +// CHECK-LABEL: define swiftcc { i8*, %swift.refcounted* } @test_thick_indirect(i8* %0, %swift.refcounted* %1, i32 %2) +// CHECK: [[FN:%.*]] = bitcast i8* %0 to void (i32, i32, %swift.refcounted*)* +// CHECK: [[ALLOC:%.*]] = call {{.*}}swift_allocObject( +// CHECK: [[CTXT:%.*]] = bitcast %swift.refcounted* [[ALLOC]] to [[CTXT_TY:<{ %swift.refcounted, i32, i32, %swift.refcounted\*, i8\* }>]]* +// CHECK: [[SLOT:%.*]] = getelementptr inbounds [[CTXT_TY]], [[CTXT_TY]]* {{%.*}}, i32 0, i32 4 +// CHECK: [[T0:%.*]] = ptrtoint i8** [[SLOT]] to i64 +// CHECK: [[DISC:%.*]] = call i64 @llvm.ptrauth.blend.i64(i64 [[T0]], i64 7185) +// CHECK: [[T0:%.*]] = ptrtoint void (i32, i32, %swift.refcounted*)* [[FN]] to i64 +// CHECK: [[T1:%.*]] = call i64 @llvm.ptrauth.resign.i64(i64 [[T0]], i32 0, i64 {{.*}}, i32 1, i64 [[DISC]]) +// CHECK: [[T2:%.*]] = inttoptr i64 [[T1]] to void (i32, i32, %swift.refcounted*)* +// CHECK: [[T3:%.*]] = bitcast void (i32, i32, %swift.refcounted*)* [[T2]] to i8* +// CHECK: store i8* [[T3]], i8** [[SLOT]], align 8 +// CHECK: insertvalue { i8*, %swift.refcounted* } { i8* bitcast ({ i8*, i32, i64, i64 }* @"$sTA{{.*}}.ptrauth" to i8*), %swift.refcounted* undef }, %swift.refcounted* {{.*}}, 1 + +// CHECK-LABEL: define internal swiftcc void @"$sTA{{.*}}"(%swift.refcounted* swiftself %0) +// CHECK: [[T0:%.*]] = bitcast %swift.refcounted* %0 to <{ %swift.refcounted, i32, i32, %swift.refcounted*, i8* }>* +// CHECK: [[SLOT:%.*]] = getelementptr inbounds <{ %swift.refcounted, i32, i32, %swift.refcounted*, i8* }>, <{ %swift.refcounted, i32, i32, %swift.refcounted*, i8* }>* [[T0]], i32 0, i32 4 +// CHECK: [[T0:%.*]] = load i8*, i8** [[SLOT]], align 8 +// CHECK: [[FN:%.*]] = bitcast i8* [[T0]] to void (i32, i32, %swift.refcounted*)* +// CHECK: [[T0:%.*]] = ptrtoint i8** [[SLOT]] to i64 +// CHECK: [[DISC:%.*]] = call i64 @llvm.ptrauth.blend.i64(i64 [[T0]], i64 7185) +// CHECK: call swiftcc void [[FN]](i32 {{.*}}, i32 {{.*}}, %swift.refcounted* {{.*}}) [ "ptrauth"(i32 1, i64 [[DISC]]) ] diff --git a/test/IRGen/ptrauth-protocols.sil b/test/IRGen/ptrauth-protocols.sil new file mode 100644 index 0000000000000..692ee75f2c4ef --- /dev/null +++ b/test/IRGen/ptrauth-protocols.sil @@ -0,0 +1,90 @@ +// RUN: %swift -swift-version 5 -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 + +// REQUIRES: CPU=arm64e +// REQUIRES: OS=ios + +import Builtin + +protocol P { + static func foo() +} +protocol Q { + init() + associatedtype Assoc : P +} + +// CHECK: @"$s4test1PMp" = hidden constant +// CHECK-SAME: { i32 -775684095, i32 0 } + +// CHECK: @"$s4test1QMp" = hidden constant +// -687472632 == 0xd7060008. 0x8bb0 == 35760. +// CHECK-SAME: { i32 2053505032, i32 0 }, +// -1951399929 == 0x8bb00007. 0x81b8 == 33208. +// CHECK-SAME: { i32 -1951399929, i32 0 }, +// -2118647806 == 0x81b80002. 0xd706 == 55046. +// CHECK-SAME: { i32 -2118647806, i32 0 } + +struct A : P { + static func foo() {} +} + +struct B : Q { + typealias Assoc = A +} + +sil @A_foo : $@convention(witness_method : P) (@thick A.Type) -> () { +bb0(%0 : $@thick A.Type): + return undef : $() +} + + +sil_witness_table A : P module test { + method #P.foo!1: @A_foo +} +// CHECK: @A_foo.ptrauth = private constant { i8*, i32, i64, i64 } { i8* bitcast (void (%swift.type*, %swift.type*, i8**)* @A_foo to i8*), i32 0, i64 ptrtoint (i8** getelementptr inbounds ([2 x i8*], [2 x i8*]* @"$s4test1AVAA1PAAWP", i32 0, i32 1) to i64), i64 53700 }, section "llvm.ptrauth" + +// CHECK: @"$s4test1AVAA1PAAWP" = hidden constant [2 x i8*] [i8* bitcast (%swift.protocol_conformance_descriptor* @"$s4test1AVAA1PAAMc" to i8*), i8* bitcast ({ i8*, i32, i64, i64 }* @A_foo.ptrauth to i8*)], align 8 + +sil @B_init : $@convention(witness_method : Q) (@thick B.Type) -> (@out B) { +bb0(%0 : $*B, %1 : $@thick B.Type): + return undef : $() +} + +sil_witness_table B : Q module test { + associated_type_protocol (Assoc: P): A: P module main + associated_type Assoc: A + method #Q.init!allocator.1: @B_init +} +// CHECK: @B_init.ptrauth = private constant { i8*, i32, i64, i64 } { i8* bitcast (void (%T4test1BV*, %swift.type*, %swift.type*, i8**)* @B_init to i8*), i32 0, i64 ptrtoint (i8** getelementptr inbounds ([4 x i8*], [4 x i8*]* @"$s4test1BVAA1QAAWP", i32 0, i32 3) to i64), i64 33208 }, section "llvm.ptrauth" +// CHECK: @"$s4test1BVAA1QAAWP" = hidden global [4 x i8*] [ +// CHECK-SAME: i8* bitcast ({{.*}}* @"$s4test1BVAA1QAAMc" to i8*), +// CHECK-SAME: @.ptrauth +// CHECK-SAME: i8* bitcast ({ i8*, i32, i64, i64 }* @B_init.ptrauth to i8*)] + +sil @test_accesses : $@convention(thin) () -> () { +bb0: + %0 = witness_method $T.Assoc, #P.foo!1 : $@convention(witness_method : P) (@thick Self.Type) -> () + %1 = metatype $@thick T.Assoc.Type + apply %0(%1) : $@convention(witness_method : P) <τ_0_0 where τ_0_0 : P> (@thick τ_0_0.Type) -> () + return undef : $() +} +// CHECK-LABEL: define swiftcc void @test_accesses(%swift.type* %T, i8** %T.Q) +// Fetch T.Assoc. +// CHECK: %T.Assoc = extractvalue %swift.metadata_response [[TMP:%.*]], 0 +// Fetch T.Assoc : P. +// CHECK-NEXT: %T.Assoc.P = call swiftcc i8** @swift_getAssociatedConformanceWitness(i8** %T.Q, %swift.type* %T, %swift.type* %T.Assoc +// Fetch T.Assoc.foo +// CHECK-NEXT: [[T0:%.*]] = getelementptr inbounds i8*, i8** %T.Assoc.P, i32 1 +// CHECK-NEXT: [[T1:%.*]] = load i8*, i8** [[T0]], align 8 +// CHECK-NEXT: [[FOO:%.*]] = bitcast i8* [[T1]] to void (%swift.type*, %swift.type*, i8**)* +// CHECK-NEXT: [[T1:%.*]] = ptrtoint i8** [[T0]] to i64 +// CHECK-NEXT: [[DISC:%.*]] = call i64 @llvm.ptrauth.blend.i64(i64 [[T1]], i64 53700) +// CHECK-NEXT: call swiftcc void [[FOO]](%swift.type* swiftself %T.Assoc, %swift.type* %T.Assoc, i8** %T.Assoc.P) [ "ptrauth"(i32 0, i64 [[DISC]]) ] +// CHECK-NEXT: ret void + +sil @use_conformances : $@convention(thin) () -> () { +bb0: + %0 = function_ref @test_accesses : $@convention(thin) () -> () + apply %0() : $@convention(thin) () -> () + return undef : $() +} diff --git a/test/IRGen/ptrauth-resilient-classes.swift b/test/IRGen/ptrauth-resilient-classes.swift new file mode 100644 index 0000000000000..96b057661ec97 --- /dev/null +++ b/test/IRGen/ptrauth-resilient-classes.swift @@ -0,0 +1,22 @@ +// RUN: %empty-directory(%t) +// RUN: %target-swift-frontend -emit-module -enable-library-evolution -emit-module-path=%t/resilient_struct.swiftmodule -module-name=resilient_struct %S/../Inputs/resilient_struct.swift + +// RUN: %target-swift-frontend -I %t -emit-ir -enable-library-evolution %s -read-legacy-type-info-path=%S/Inputs/legacy_type_info/a.yaml | %FileCheck %s --check-prefix=CHECK --check-prefix=CHECK-%target-ptrsize -DINT=i%target-ptrsize + +// We only use fragile class layouts when Objective-C interop is enabled. + +// REQUIRES: objc_interop +// REQUIRES: CPU=arm64e + +import resilient_struct + +public class HasResilientField { + let i: ResilientRef + + init(i: ResilientRef) { + self.i = i + } +} + +// CHECK-LABEL: @_DATA__TtC4main17HasResilientField = private constant +// CHECK-SAME: @"$s4main17HasResilientFieldCMU.ptrauth" diff --git a/test/IRGen/ptrauth-runtime.sil b/test/IRGen/ptrauth-runtime.sil new file mode 100644 index 0000000000000..cb8faa64e5fc4 --- /dev/null +++ b/test/IRGen/ptrauth-runtime.sil @@ -0,0 +1,19 @@ +// RUN: %swift -swift-version 4 -target arm64e-apple-ios12.0 -parse-stdlib -parse-as-library %s -emit-ir -module-name test | %FileCheck %s --check-prefix=CHECK + +// REQUIRES: CPU=arm64e +// REQUIRES: OS=ios + +import Builtin + +sil @global_function : $@convention(thin) () -> () + +sil @test_retain : $@convention(thin) (@guaranteed Builtin.NativeObject) -> (@owned Builtin.NativeObject) { +bb0(%0 : $Builtin.NativeObject): + strong_retain %0 : $Builtin.NativeObject + return %0 : $Builtin.NativeObject +} +// CHECK-LABEL: define swiftcc %swift.refcounted* @test_retain(%swift.refcounted* %0) +// CHECK: call %swift.refcounted* @swift_retain( +// CHECK-NEXT: ret %swift.refcounted* %0 + +// CHECK: declare %swift.refcounted* @swift_retain(%swift.refcounted* returned diff --git a/test/IRGen/ptrauth-value-witnesses.sil b/test/IRGen/ptrauth-value-witnesses.sil new file mode 100644 index 0000000000000..e297ec4d0fc35 --- /dev/null +++ b/test/IRGen/ptrauth-value-witnesses.sil @@ -0,0 +1,115 @@ +// 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 + +// REQUIRES: CPU=arm64e +// REQUIRES: OS=ios + +import Builtin + +struct S { var a, b, c: Builtin.NativeObject } +// 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 + +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: [[VWT:%.*]] = load i8**, +// CHECK-NEXT: [[SLOT:%.*]] = getelementptr inbounds i8*, i8** [[VWT]], i32 +// CHECK-NEXT: [[T0:%.*]] = load i8*, i8** [[SLOT]], align +// CHECK-NEXT: [[WITNESS:%.*]] = bitcast i8* [[T0]] to +// CHECK-NEXT: [[T0:%.*]] = ptrtoint i8** [[SLOT]] to i64 +// CHECK-NEXT: [[DISC:%.*]] = call i64 @llvm.ptrauth.blend.i64(i64 [[T0]], i64 1272) +// CHECK-NEXT: call void [[WITNESS]](%swift.opaque* noalias %0, %swift.type* %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 [initialization] %0 : $*T + %result = tuple () + return %result : $() +} +// CHECK-LABEL: define swiftcc void @test_copy_init( +// CHECK: [[VWT:%.*]] = load i8**, +// CHECK-NEXT: [[SLOT:%.*]] = getelementptr inbounds i8*, i8** [[VWT]], i32 +// CHECK-NEXT: [[T0:%.*]] = load i8*, i8** [[SLOT]], align +// CHECK-NEXT: [[WITNESS:%.*]] = bitcast i8* [[T0]] to +// CHECK-NEXT: [[T0:%.*]] = ptrtoint i8** [[SLOT]] to i64 +// CHECK-NEXT: [[DISC:%.*]] = call i64 @llvm.ptrauth.blend.i64(i64 [[T0]], i64 58298) +// CHECK-NEXT: call %swift.opaque* [[WITNESS]](%swift.opaque* noalias %0, %swift.opaque* noalias %1, %swift.type* %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 [initialization] %0 : $*T + %result = tuple () + return %result : $() +} +// CHECK-LABEL: define swiftcc void @test_take_init( +// CHECK: [[VWT:%.*]] = load i8**, +// CHECK-NEXT: [[SLOT:%.*]] = getelementptr inbounds i8*, i8** [[VWT]], i32 +// CHECK-NEXT: [[T0:%.*]] = load i8*, i8** [[SLOT]], align +// CHECK-NEXT: [[WITNESS:%.*]] = bitcast i8* [[T0]] to +// CHECK-NEXT: [[T0:%.*]] = ptrtoint i8** [[SLOT]] to i64 +// CHECK-NEXT: [[DISC:%.*]] = call i64 @llvm.ptrauth.blend.i64(i64 [[T0]], i64 18648) +// CHECK-NEXT: call %swift.opaque* [[WITNESS]](%swift.opaque* noalias %0, %swift.opaque* noalias %1, %swift.type* %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: [[VWT:%.*]] = load i8**, +// CHECK-NEXT: [[SLOT:%.*]] = getelementptr inbounds i8*, i8** [[VWT]], i32 +// CHECK-NEXT: [[T0:%.*]] = load i8*, i8** [[SLOT]], align +// CHECK-NEXT: [[WITNESS:%.*]] = bitcast i8* [[T0]] to +// CHECK-NEXT: [[T0:%.*]] = ptrtoint i8** [[SLOT]] to i64 +// CHECK-NEXT: [[DISC:%.*]] = call i64 @llvm.ptrauth.blend.i64(i64 [[T0]], i64 34641) +// CHECK-NEXT: call %swift.opaque* [[WITNESS]](%swift.opaque* %0, %swift.opaque* %1, %swift.type* %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: [[VWT:%.*]] = load i8**, +// CHECK-NEXT: [[SLOT:%.*]] = getelementptr inbounds i8*, i8** [[VWT]], i32 +// CHECK-NEXT: [[T0:%.*]] = load i8*, i8** [[SLOT]], align +// CHECK-NEXT: [[WITNESS:%.*]] = bitcast i8* [[T0]] to +// CHECK-NEXT: [[T0:%.*]] = ptrtoint i8** [[SLOT]] to i64 +// CHECK-NEXT: [[DISC:%.*]] = call i64 @llvm.ptrauth.blend.i64(i64 [[T0]], i64 61402) +// CHECK-NEXT: call %swift.opaque* [[WITNESS]](%swift.opaque* noalias %0, %swift.opaque* noalias %1, %swift.type* %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: [[VWT:%.*]] = load i8**, +// CHECK-NEXT: [[SLOT:%.*]] = getelementptr inbounds i8*, i8** [[VWT]], i32 +// CHECK-NEXT: [[T0:%.*]] = load i8*, i8** [[SLOT]], align +// CHECK-NEXT: [[WITNESS:%.*]] = bitcast i8* [[T0]] to +// CHECK-NEXT: [[T0:%.*]] = ptrtoint i8** [[SLOT]] to i64 +// CHECK-NEXT: [[DISC:%.*]] = call i64 @llvm.ptrauth.blend.i64(i64 [[T0]], i64 1272) +// CHECK-NEXT: call void [[WITNESS]](%swift.opaque* noalias %0, %swift.type* %T) {{#[0-9]+}} [ "ptrauth"(i32 0, i64 [[DISC]]) ] +// CHECK-NEXT: call void [[WITNESS]](%swift.opaque* noalias %1, %swift.type* %T) {{#[0-9]+}} [ "ptrauth"(i32 0, i64 [[DISC]]) ] +// CHECK-NEXT: ret void diff --git a/test/IRGen/ptrauth_generalized_accessors.swift b/test/IRGen/ptrauth_generalized_accessors.swift new file mode 100644 index 0000000000000..027b798ae2d49 --- /dev/null +++ b/test/IRGen/ptrauth_generalized_accessors.swift @@ -0,0 +1,175 @@ +// 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 + +// 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() +} diff --git a/test/IRGen/witness_method_default.swift b/test/IRGen/witness_method_default.swift index 4a732e5400a54..683e5bd10bd63 100644 --- a/test/IRGen/witness_method_default.swift +++ b/test/IRGen/witness_method_default.swift @@ -18,6 +18,6 @@ public func callAbs(s: T) -> T { // CHECK: [[ABS_PTR:%[0-9]+]] = getelementptr inbounds i8*, i8** %T.SIMDScalarStub, i32 3 // CHECK-NEXT: [[ABS_VALUE:%[0-9]+]] = load i8*, i8** [[ABS_PTR]] // CHECK-NEXT: [[ABS:%[0-9]+]] = bitcast i8* [[ABS_VALUE]] - // CHECK-NEXT: call swiftcc void [[ABS]] + // CHECK: call swiftcc void [[ABS]] return s.abs() } diff --git a/test/IRGen/witness_method_phi.sil b/test/IRGen/witness_method_phi.sil index 2e1d48b820cd5..ff8a2d10497ab 100644 --- a/test/IRGen/witness_method_phi.sil +++ b/test/IRGen/witness_method_phi.sil @@ -9,7 +9,7 @@ entry: // CHECK: [[T0_GEP:%.*]] = getelementptr inbounds i8*, i8** %T.P, i32 1 // CHECK: [[LOAD:%.*]] = load i8*, i8** [[T0_GEP]], // CHECK: [[T0:%.*]] = bitcast i8* [[LOAD]] to void (%swift.opaque*, %swift.type*, i8**)* - // CHECK: [[FUNC:%.*]] = bitcast void (%swift.opaque*, %swift.type*, i8**)* [[T0]] to i8* + // CHECK: [[FUNC:%.*]] = bitcast void (%swift.opaque*, %swift.type*, i8**)* {{.*}} to i8* %1 = witness_method $T, #P.foo!1 : $@convention(witness_method: P) (@in T) -> () br bb1(%1 : $@convention(witness_method: P) (@in T) -> ()) diff --git a/test/IRGen/witness_table_objc_associated_type.swift b/test/IRGen/witness_table_objc_associated_type.swift index 9888dba964b27..88b1fd83fa312 100644 --- a/test/IRGen/witness_table_objc_associated_type.swift +++ b/test/IRGen/witness_table_objc_associated_type.swift @@ -20,9 +20,8 @@ struct SB: B { func foo() {} } // CHECK-LABEL: @"$s34witness_table_objc_associated_type2SBVAA1BAAWP" = hidden global [4 x i8*] [ -// CHECK: @"associated conformance 34witness_table_objc_associated_type2SBVAA1BAA2AAAaDP_AA1A" -// CHECK: @"symbolic{{.*}}34witness_table_objc_associated_type2SAV" -// CHECK: i8* bitcast {{.*}} @"$s34witness_table_objc_associated_type2SBVAA1BA2aDP3fooyyFTW" +// CHECK: {{(associated conformance 34witness_table_objc_associated_type2SBVAA1BAA2AAAaDP_AA1A|.ptrauth)}} +// CHECK: i8* bitcast {{.*}} @"$s34witness_table_objc_associated_type2SBVAA1BA2aDP3fooyyFTW{{(\.ptrauth)?}}" // CHECK: ] class CO: O {} @@ -31,8 +30,7 @@ struct SO: C { func foo() {} } // CHECK-LABEL: @"$s34witness_table_objc_associated_type2SOVAA1CAAWP" = hidden global [3 x i8*] [ -// CHECK: @"symbolic{{.*}}34witness_table_objc_associated_type2COC" -// CHECK: i8* bitcast {{.*}} @"$s34witness_table_objc_associated_type2SOVAA1CA2aDP3fooyyFTW" +// CHECK: i8* bitcast {{.*}} @"$s34witness_table_objc_associated_type2SOVAA1CA2aDP3fooyyFTW{{(\.ptrauth)?}}" // CHECK: ] // CHECK-LABEL: define hidden swiftcc void @"$s34witness_table_objc_associated_type0A25OffsetAfterAssociatedTypeyyxAA1BRzlF"(%swift.opaque* noalias nocapture %0, %swift.type* %T, i8** %T.B) diff --git a/test/IRGen/yield_once.sil b/test/IRGen/yield_once.sil index 210596979011b..235816155fdb6 100644 --- a/test/IRGen/yield_once.sil +++ b/test/IRGen/yield_once.sil @@ -1,4 +1,4 @@ -// RUN: %target-swift-frontend -emit-ir -disable-llvm-optzns %s | %FileCheck %s --check-prefix=CHECK --check-prefix=CHECK-%target-ptrsize +// RUN: %target-swift-frontend -emit-ir -disable-llvm-optzns %s | %FileCheck %s --check-prefix=CHECK --check-prefix=CHECK-%target-ptrsize --check-prefix=CHECK-%target-ptrsize-%target-ptrauth import Builtin @@ -11,7 +11,8 @@ sil @marker : $(Builtin.Int32) -> () sil @test_simple : $@yield_once () -> () { entry: // CHECK-32: [[ID:%.*]] = call token @llvm.coro.id.retcon.once(i32 [[BUFFER_SIZE]], i32 [[BUFFER_ALIGN:4]], i8* %0, i8* bitcast (void (i8*, i1)* @"$sIetA_TC" to i8*), i8* bitcast (i8* (i32)* @malloc to i8*), i8* bitcast (void (i8*)* @free to i8*)) - // CHECK-64: [[ID:%.*]] = call token @llvm.coro.id.retcon.once(i32 [[BUFFER_SIZE]], i32 [[BUFFER_ALIGN:8]], i8* %0, i8* bitcast (void (i8*, i1)* @"$sIetA_TC" to i8*), i8* bitcast (i8* (i64)* @malloc to i8*), i8* bitcast (void (i8*)* @free to i8*)) + // CHECK-64-noptrauth: [[ID:%.*]] = call token @llvm.coro.id.retcon.once(i32 [[BUFFER_SIZE]], i32 [[BUFFER_ALIGN:8]], i8* %0, i8* bitcast (void (i8*, i1)* @"$sIetA_TC" to i8*), i8* bitcast (i8* (i64)* @malloc to i8*), i8* bitcast (void (i8*)* @free to i8*)) + // CHECK-64-ptrauth: [[ID:%.*]] = call token @llvm.coro.id.retcon.once(i32 [[BUFFER_SIZE]], i32 [[BUFFER_ALIGN:8]], i8* %0, i8* bitcast ({ i8*, i32, i64, i64 }* @"$sIetA_TC.ptrauth" to i8*), i8* bitcast (i8* (i64)* @malloc to i8*), i8* bitcast (void (i8*)* @free to i8*)) // CHECK-NEXT: [[BEGIN:%.*]] = call i8* @llvm.coro.begin(token [[ID]], i8* null) // CHECK-NEXT: call swiftcc void @marker(i32 1000) @@ -68,6 +69,8 @@ entry(%flag : $Builtin.Int1): yes: // CHECK: [[T0:%.*]] = bitcast i8* [[CONTINUATION]] to void (i8*, i1)* + // CHECK-64-ptrauth-NEXT: ptrtoint + // CHECK-64-ptrauth-NEXT: ptrauth.blend // CHECK-NEXT: call swiftcc void [[T0]](i8* noalias dereferenceable([[BUFFER_SIZE]]) [[BUFFER]], i1 false) // CHECK-NEXT: call void @llvm.lifetime.end.p0i8(i64 [[BUFFER_SIZE]], i8* [[BUFFER]]) end_apply %token @@ -77,6 +80,8 @@ yes: no: // CHECK: [[T0:%.*]] = bitcast i8* [[CONTINUATION]] to void (i8*, i1)* + // CHECK-64-ptrauth-NEXT: ptrtoint + // CHECK-64-ptrauth-NEXT: ptrauth.blend // CHECK-NEXT: call swiftcc void [[T0]](i8* noalias dereferenceable([[BUFFER_SIZE]]) [[BUFFER]], i1 true) // CHECK-NEXT: call void @llvm.lifetime.end.p0i8(i64 [[BUFFER_SIZE]], i8* [[BUFFER]]) abort_apply %token @@ -117,6 +122,8 @@ entry: apply %marker(%first) : $@convention(thin) (Builtin.Int32) -> () // CHECK-NEXT: [[T0:%.*]] = bitcast i8* [[CONTINUATION]] to void (i8*, i1)* + // CHECK-64-ptrauth-NEXT: ptrtoint + // CHECK-64-ptrauth-NEXT: ptrauth.blend // CHECK-NEXT: call swiftcc void [[T0]](i8* noalias dereferenceable([[BUFFER_SIZE]]) [[BUFFER]], i1 false) // CHECK-NEXT: call void @llvm.lifetime.end.p0i8(i64 [[BUFFER_SIZE]], i8* [[BUFFER]]) end_apply %token diff --git a/test/IRGen/yield_once_big.sil b/test/IRGen/yield_once_big.sil index 46c8f5ab411a7..53ef7a7f1ca14 100644 --- a/test/IRGen/yield_once_big.sil +++ b/test/IRGen/yield_once_big.sil @@ -1,4 +1,4 @@ -// RUN: %target-swift-frontend -emit-ir -disable-llvm-optzns %s | %FileCheck %s --check-prefix=CHECK --check-prefix=CHECK-%target-ptrsize -DINT=i%target-ptrsize +// RUN: %target-swift-frontend -emit-ir -disable-llvm-optzns %s | %FileCheck %s --check-prefix=CHECK --check-prefix=CHECK-%target-ptrsize --check-prefix=CHECK-%target-ptrsize-%target-ptrauth -DINT=i%target-ptrsize import Builtin import Swift @@ -39,7 +39,8 @@ entry: // Coroutine setup. // CHECK-32-NEXT: [[ID:%.*]] = call token @llvm.coro.id.retcon.once(i32 [[BUFFER_SIZE]], i32 [[BUFFER_ALIGN:4]], i8* %0, i8* bitcast (void (i8*, i1)* @"$s14yield_once_big3BigVyxGAA9SomeClassCRbzlIetAYc_TC" to i8*), i8* bitcast (i8* (i32)* @malloc to i8*), i8* bitcast (void (i8*)* @free to i8*)) - // CHECK-64-NEXT: [[ID:%.*]] = call token @llvm.coro.id.retcon.once(i32 [[BUFFER_SIZE]], i32 [[BUFFER_ALIGN:8]], i8* %0, i8* bitcast (void (i8*, i1)* @"$s14yield_once_big3BigVyxGAA9SomeClassCRbzlIetAYc_TC" to i8*), i8* bitcast (i8* (i64)* @malloc to i8*), i8* bitcast (void (i8*)* @free to i8*)) + // CHECK-64-noptrauth-NEXT: [[ID:%.*]] = call token @llvm.coro.id.retcon.once(i32 [[BUFFER_SIZE]], i32 [[BUFFER_ALIGN:8]], i8* %0, i8* bitcast (void (i8*, i1)* @"$s14yield_once_big3BigVyxGAA9SomeClassCRbzlIetAYc_TC" to i8*), i8* bitcast (i8* (i64)* @malloc to i8*), i8* bitcast (void (i8*)* @free to i8*)) + // CHECK-64-ptrauth-NEXT: [[ID:%.*]] = call token @llvm.coro.id.retcon.once(i32 [[BUFFER_SIZE]], i32 [[BUFFER_ALIGN:8]], i8* %0, i8* bitcast ({ i8*, i32, i64, i64 }* @"$s14yield_once_big3BigVyxGAA9SomeClassCRbzlIetAYc_TC.ptrauth" to i8*), i8* bitcast (i8* (i64)* @malloc to i8*), i8* bitcast (void (i8*)* @free to i8*)) // CHECK-NEXT: [[BEGIN:%.*]] = call i8* @llvm.coro.begin(token [[ID]], i8* null) // CHECK-NEXT: store %swift.type* @@ -135,6 +136,8 @@ entry(%flag : $Builtin.Int1): yes: // CHECK: [[T0:%.*]] = bitcast i8* [[CONTINUATION]] to void (i8*, i1)* + // CHECK-64-ptrauth-NEXT: ptrtoint + // CHECK-64-ptrauth-NEXT: ptrauth.blend // CHECK-NEXT: call swiftcc void [[T0]](i8* noalias dereferenceable([[BUFFER_SIZE]]) [[BUFFER]], i1 false) // CHECK-NEXT: call void @llvm.lifetime.end.p0i8(i64 [[BUFFER_SIZE]], i8* [[BUFFER]]) end_apply %token @@ -144,6 +147,8 @@ yes: no: // CHECK: [[T0:%.*]] = bitcast i8* [[CONTINUATION]] to void (i8*, i1)* + // CHECK-64-ptrauth-NEXT: ptrtoint + // CHECK-64-ptrauth-NEXT: ptrauth.blend // CHECK-NEXT: call swiftcc void [[T0]](i8* noalias dereferenceable([[BUFFER_SIZE]]) [[BUFFER]], i1 true) // CHECK-NEXT: call void @llvm.lifetime.end.p0i8(i64 [[BUFFER_SIZE]], i8* [[BUFFER]]) abort_apply %token diff --git a/test/IRGen/yield_once_biggish.sil b/test/IRGen/yield_once_biggish.sil index b738a574acc9d..26951869ba154 100644 --- a/test/IRGen/yield_once_biggish.sil +++ b/test/IRGen/yield_once_biggish.sil @@ -1,4 +1,4 @@ -// RUN: %target-swift-frontend -emit-ir -disable-llvm-optzns %s | %FileCheck %s --check-prefix=CHECK --check-prefix=CHECK-%target-ptrsize -DINT=i%target-ptrsize +// RUN: %target-swift-frontend -emit-ir -disable-llvm-optzns %s | %FileCheck %s --check-prefix=CHECK --check-prefix=CHECK-%target-ptrsize --check-prefix=CHECK-%target-ptrsize-%target-ptrauth -DINT=i%target-ptrsize // i386 uses a scalar result count of 3 instead of 4, so this test would need // to be substantially different to test the functionality there. It's easier @@ -40,7 +40,8 @@ entry: // Coroutine setup. // CHECK-32-NEXT: [[ID:%.*]] = call token @llvm.coro.id.retcon.once(i32 [[BUFFER_SIZE]], i32 [[BUFFER_ALIGN:4]], i8* %0, i8* bitcast (void (i8*, i1)* @"$s18yield_once_biggish7BiggishVyxGAA9SomeClassCRbzlIetAYx_TC" to i8*), i8* bitcast (i8* (i32)* @malloc to i8*), i8* bitcast (void (i8*)* @free to i8*)) - // CHECK-64-NEXT: [[ID:%.*]] = call token @llvm.coro.id.retcon.once(i32 [[BUFFER_SIZE]], i32 [[BUFFER_ALIGN:8]], i8* %0, i8* bitcast (void (i8*, i1)* @"$s18yield_once_biggish7BiggishVyxGAA9SomeClassCRbzlIetAYx_TC" to i8*), i8* bitcast (i8* (i64)* @malloc to i8*), i8* bitcast (void (i8*)* @free to i8*)) + // CHECK-64-noptrauth-NEXT: [[ID:%.*]] = call token @llvm.coro.id.retcon.once(i32 [[BUFFER_SIZE]], i32 [[BUFFER_ALIGN:8]], i8* %0, i8* bitcast (void (i8*, i1)* @"$s18yield_once_biggish7BiggishVyxGAA9SomeClassCRbzlIetAYx_TC" to i8*), i8* bitcast (i8* (i64)* @malloc to i8*), i8* bitcast (void (i8*)* @free to i8*)) + // CHECK-64-ptrauth-NEXT: [[ID:%.*]] = call token @llvm.coro.id.retcon.once(i32 [[BUFFER_SIZE]], i32 [[BUFFER_ALIGN:8]], i8* %0, i8* bitcast ({ i8*, i32, i64, i64 }* @"$s18yield_once_biggish7BiggishVyxGAA9SomeClassCRbzlIetAYx_TC.ptrauth" to i8*), i8* bitcast (i8* (i64)* @malloc to i8*), i8* bitcast (void (i8*)* @free to i8*)) // CHECK-NEXT: [[BEGIN:%.*]] = call i8* @llvm.coro.begin(token [[ID]], i8* null) // CHECK-NEXT: store %swift.type* // CHECK-NEXT: call swiftcc void @marker(i32 1000) @@ -134,6 +135,8 @@ entry(%flag : $Builtin.Int1): yes: // CHECK: [[T0:%.*]] = bitcast i8* [[CONTINUATION]] to void (i8*, i1)* + // CHECK-64-ptrauth-NEXT: ptrtoint + // CHECK-64-ptrauth-NEXT: ptrauth.blend // CHECK-NEXT: call swiftcc void [[T0]](i8* noalias dereferenceable([[BUFFER_SIZE]]) [[BUFFER]], i1 false) // CHECK-NEXT: call void @llvm.lifetime.end.p0i8(i64 [[BUFFER_SIZE]], i8* [[BUFFER]]) end_apply %token @@ -143,6 +146,8 @@ yes: no: // CHECK: [[T0:%.*]] = bitcast i8* [[CONTINUATION]] to void (i8*, i1)* + // CHECK-64-ptrauth-NEXT: ptrtoint + // CHECK-64-ptrauth-NEXT: ptrauth.blend // CHECK-NEXT: call swiftcc void [[T0]](i8* noalias dereferenceable([[BUFFER_SIZE]]) [[BUFFER]], i1 true) // CHECK-NEXT: call void @llvm.lifetime.end.p0i8(i64 [[BUFFER_SIZE]], i8* [[BUFFER]]) abort_apply %token diff --git a/test/IRGen/yield_once_indirect.sil b/test/IRGen/yield_once_indirect.sil index 067da7239a029..b68f349d6e7b3 100644 --- a/test/IRGen/yield_once_indirect.sil +++ b/test/IRGen/yield_once_indirect.sil @@ -1,4 +1,4 @@ -// RUN: %target-swift-frontend -emit-ir -disable-llvm-optzns %s | %FileCheck %s --check-prefix=CHECK --check-prefix=CHECK-%target-ptrsize -DINT=i%target-ptrsize +// RUN: %target-swift-frontend -emit-ir -disable-llvm-optzns %s | %FileCheck %s --check-prefix=CHECK --check-prefix=CHECK-%target-ptrsize --check-prefix=CHECK-%target-ptrsize-%target-ptrauth -DINT=i%target-ptrsize import Builtin import Swift @@ -31,7 +31,8 @@ entry: // Coroutine setup. // CHECK-32-NEXT: [[ID:%.*]] = call token @llvm.coro.id.retcon.once(i32 [[BUFFER_SIZE]], i32 [[BUFFER_ALIGN:4]], i8* %0, i8* bitcast (void (i8*, i1)* @"$s19yield_once_indirect8IndirectVyxGAA9SomeClassCRbzlIetAYi_TC" to i8*), i8* bitcast (i8* (i32)* @malloc to i8*), i8* bitcast (void (i8*)* @free to i8*)) - // CHECK-64-NEXT: [[ID:%.*]] = call token @llvm.coro.id.retcon.once(i32 [[BUFFER_SIZE]], i32 [[BUFFER_ALIGN:8]], i8* %0, i8* bitcast (void (i8*, i1)* @"$s19yield_once_indirect8IndirectVyxGAA9SomeClassCRbzlIetAYi_TC" to i8*), i8* bitcast (i8* (i64)* @malloc to i8*), i8* bitcast (void (i8*)* @free to i8*)) + // CHECK-64-noptrauth-NEXT: [[ID:%.*]] = call token @llvm.coro.id.retcon.once(i32 [[BUFFER_SIZE]], i32 [[BUFFER_ALIGN:8]], i8* %0, i8* bitcast (void (i8*, i1)* @"$s19yield_once_indirect8IndirectVyxGAA9SomeClassCRbzlIetAYi_TC" to i8*), i8* bitcast (i8* (i64)* @malloc to i8*), i8* bitcast (void (i8*)* @free to i8*)) + // CHECK-64-ptrauth-NEXT: [[ID:%.*]] = call token @llvm.coro.id.retcon.once(i32 [[BUFFER_SIZE]], i32 [[BUFFER_ALIGN:8]], i8* %0, i8* bitcast ({ i8*, i32, i64, i64 }* @"$s19yield_once_indirect8IndirectVyxGAA9SomeClassCRbzlIetAYi_TC.ptrauth" to i8*), i8* bitcast (i8* (i64)* @malloc to i8*), i8* bitcast (void (i8*)* @free to i8*)) // CHECK-NEXT: [[BEGIN:%.*]] = call i8* @llvm.coro.begin(token [[ID]], i8* null) // CHECK-NEXT: store %swift.type* // CHECK-NEXT: call swiftcc void @marker(i32 1000) @@ -118,6 +119,8 @@ entry(%flag : $Builtin.Int1): yes: // CHECK: [[T0:%.*]] = bitcast i8* [[CONTINUATION]] to void (i8*, i1)* + // CHECK-64-ptrauth-NEXT: ptrtoint + // CHECK-64-ptrauth-NEXT: ptrauth.blend // CHECK-NEXT: call swiftcc void [[T0]](i8* noalias dereferenceable([[BUFFER_SIZE]]) [[BUFFER]], i1 false) // CHECK-NEXT: call void @llvm.lifetime.end.p0i8(i64 [[BUFFER_SIZE]], i8* [[BUFFER]]) end_apply %token @@ -127,6 +130,8 @@ yes: no: // CHECK: [[T0:%.*]] = bitcast i8* [[CONTINUATION]] to void (i8*, i1)* + // CHECK-64-ptrauth-NEXT: ptrtoint + // CHECK-64-ptrauth-NEXT: ptrauth.blend // CHECK-NEXT: call swiftcc void [[T0]](i8* noalias dereferenceable([[BUFFER_SIZE]]) [[BUFFER]], i1 true) // CHECK-NEXT: call void @llvm.lifetime.end.p0i8(i64 [[BUFFER_SIZE]], i8* [[BUFFER]]) abort_apply %token diff --git a/test/Interpreter/SDK/dynamic_subclass.swift b/test/Interpreter/SDK/dynamic_subclass.swift new file mode 100644 index 0000000000000..1ef031db6b4de --- /dev/null +++ b/test/Interpreter/SDK/dynamic_subclass.swift @@ -0,0 +1,27 @@ +// RUN: %target-run-simple-swift | %FileCheck %s +// REQUIRES: executable_test + +// REQUIRES: objc_interop + +import Foundation +import ObjectiveC + +func DoSwizzle(_ c: AnyClass) -> AnyClass { + let name = String(utf8String: class_getName(c))! + let subclass: AnyClass = objc_allocateClassPair(c, "\(name)Subclass", 0)! + objc_registerClassPair(subclass); + let subclassSubclass: AnyClass = objc_allocateClassPair(subclass, "\(name)SubclassSubclass", 0)! + objc_registerClassPair(subclassSubclass); + return subclassSubclass +} + +class MySwiftClassToBeSwizzled: NSObject { +} + +_ = DoSwizzle(NSArray.self) +print("Swizzled NSArray") +// CHECK: Swizzled NSArray + +_ = DoSwizzle(MySwiftClassToBeSwizzled.self) +print("Swizzled MySwiftClassToBeSwizzled") +// CHECK: Swizzled MySwiftClassToBeSwizzled diff --git a/test/Interpreter/convenience_init_peer_delegation.swift b/test/Interpreter/convenience_init_peer_delegation.swift index ae369ca717b29..be1cb83e66de3 100644 --- a/test/Interpreter/convenience_init_peer_delegation.swift +++ b/test/Interpreter/convenience_init_peer_delegation.swift @@ -11,6 +11,7 @@ // REQUIRES: executable_test // REQUIRES: objc_interop +// XFAIL: CPU=arm64e import Darwin diff --git a/test/Interpreter/ptrauth-function-pointers.swift b/test/Interpreter/ptrauth-function-pointers.swift new file mode 100644 index 0000000000000..8fb7efd1f0bfa --- /dev/null +++ b/test/Interpreter/ptrauth-function-pointers.swift @@ -0,0 +1,34 @@ +// RUN: %target-run-simple-swift +// REQUIRES: executable_test +// REQUIRES: CPU=arm64e + +import StdlibUnittest + +var PtrAuthFunctionPointersTestSuite = TestSuite("PtrAuthFunctionPointers") + +func foo() {} +func bar() {} + +struct FuncPtrs { + var a: ()->() + var b: ()->() +} + +PtrAuthFunctionPointersTestSuite.test("PointerAreSigned") { + var ptrs = FuncPtrs(a: foo, b: bar) + withUnsafeBytes(of: &ptrs) { bytes in + let p = bytes.load(fromByteOffset: 0, as: UInt.self) + expectEqual(UInt.bitWidth, 64) + let signature = p & 0x00fffff0_00000000 + let actualPointer = p & 0x0000000f_ffffffff + + // The top byte of a signed function pointer actually being zero is only + // guaranteed by ARMv8.3 if TBI is enabled, which it isn't for function + // pointers in new iOS releases + //expectEqual(topByte, 0) + expectNotEqual(signature, 0) + expectNotEqual(actualPointer, 0) + } +} + +runAllTests() diff --git a/test/Interpreter/ptrauth-kvo.swift b/test/Interpreter/ptrauth-kvo.swift new file mode 100644 index 0000000000000..1fbd9e85cc22c --- /dev/null +++ b/test/Interpreter/ptrauth-kvo.swift @@ -0,0 +1,47 @@ +// RUN: %target-run-simple-swift | %FileCheck %s +// REQUIRES: executable_test +// REQUIRES: objc_interop + +import Foundation + +class A : NSObject { + func a1() {} // never overridden + func x() {} // overriden 1x + func y() {} // overriden 2x + func z() {} // overriden 3x +} + +class B : A { + func b1() {} // never overridden + override func x() {} + override func y() {} + override func z() {} +} + +class C : B { + func c1() {} // never overridden + override func y() {} + override func z() {} +} + +class D : C { + @objc let name: String = "" + func d1() {} + override func z() {} +} + + +let o = D() +let observer = NSObject() +o.addObserver(observer, forKeyPath: "name", options: NSKeyValueObservingOptions(), context: nil) + +o.x() +o.y() +o.z() +o.a1() +o.b1() +o.c1() +o.d1() + +print("okay") +// CHECK: okay diff --git a/test/SILOptimizer/eager_specialize.sil b/test/SILOptimizer/eager_specialize.sil index 54f38697eea08..5e618dd026e5c 100644 --- a/test/SILOptimizer/eager_specialize.sil +++ b/test/SILOptimizer/eager_specialize.sil @@ -1,6 +1,6 @@ // RUN: %target-sil-opt -enable-sil-verify-all -eager-specializer %s | %FileCheck %s // RUN: %target-sil-opt -enable-sil-verify-all -eager-specializer -sil-deadfuncelim %s | %FileCheck --check-prefix=CHECK-DEADFUNCELIM %s -// RUN: %target-sil-opt -enable-sil-verify-all -eager-specializer %s -o %t.sil && %target-swift-frontend -module-name=eager_specialize -emit-ir %t.sil | %FileCheck --check-prefix=CHECK-IRGEN %s +// RUN: %target-sil-opt -enable-sil-verify-all -eager-specializer %s -o %t.sil && %target-swift-frontend -module-name=eager_specialize -emit-ir %t.sil | %FileCheck --check-prefix=CHECK-IRGEN --check-prefix=CHECK-IRGEN-%target-cpu %s // RUN: %target-sil-opt -enable-sil-verify-all -eager-specializer -sil-inline-generics=true -inline %s | %FileCheck --check-prefix=CHECK-EAGER-SPECIALIZE-AND-GENERICS-INLINE %s sil_stage canonical @@ -727,7 +727,9 @@ bb0(%0 : $*Self, %1 : $*Self, %2 : $@thick Self.Type): // CHECK-IRGEN-NEXT: %5 = getelementptr inbounds i8*, i8** %S.valueWitnesses // CHECK-IRGEN-NEXT: %6 = load i8*, i8** %5 // CHECK-IRGEN-NEXT: %initializeWithCopy = {{.*}} -// CHECK-IRGEN-NEXT: %7 = call {{.*}} %initializeWithCopy +// CHECK-IRGEN-arm64e-NEXT: ptrtoint i8** %5 to i64 +// CHECK-IRGEN-arm64e-NEXT: call i64 @llvm.ptrauth.blend.i64 +// CHECK-IRGEN-NEXT: call {{.*}} %initializeWithCopy // CHECK-IRGEN-NEXT: ret void // CHECK-IRGEN-NEXT: } diff --git a/test/Serialization/load-arch-fallback-arm64e.swift b/test/Serialization/load-arch-fallback-arm64e.swift new file mode 100644 index 0000000000000..97e8f943de888 --- /dev/null +++ b/test/Serialization/load-arch-fallback-arm64e.swift @@ -0,0 +1,19 @@ +// Test the fallback for arm64e platforms. + +// RUN: %empty-directory(%t) +// RUN: mkdir %t/empty.swiftmodule +// RUN: %target-swift-frontend -emit-module -o %t/empty.swiftmodule/arm64.swiftmodule %S/../Inputs/empty.swift -module-name empty +// RUN: %target-swift-frontend -typecheck %s -I %t + +// RUN: mv %t/empty.swiftmodule/arm64.swiftmodule %t/empty.swiftmodule/%target-swiftmodule-name +// RUN: touch %t/empty.swiftmodule/arm64.swiftmodule +// RUN: %target-swift-frontend -typecheck %s -I %t + +// RUN: rm %t/empty.swiftmodule/%target-swiftmodule-name +// RUN: not %target-swift-frontend -typecheck %s -I %t 2>&1 | %FileCheck %s + +// REQUIRES: CPU=arm64e + +import empty +// CHECK: :[[@LINE-1]]:8: error: malformed compiled module: {{.*}}arm64.swiftmodule + diff --git a/test/Serialization/load-target-normalization.swift b/test/Serialization/load-target-normalization.swift index cdf0899e483d5..21040c0c2aab8 100644 --- a/test/Serialization/load-target-normalization.swift +++ b/test/Serialization/load-target-normalization.swift @@ -65,11 +65,12 @@ import ForeignModule // RUN: not %target-swift-frontend %s -typecheck -I %t -parse-stdlib -Xcc -arch -Xcc i386 -target arm64-apple-ios40.0 2>&1 | %FileCheck -DNORM=arm64-apple-ios %s // RUN: not %target-swift-frontend %s -typecheck -I %t -parse-stdlib -Xcc -arch -Xcc i386 -target aarch64-apple-ios40.0 2>&1 | %FileCheck -DNORM=arm64-apple-ios %s -// armv7s, armv7k, armv7 should be accepted. +// armv7s, armv7k, armv7, arm64e should be accepted. // RUN: not %target-swift-frontend %s -typecheck -I %t -parse-stdlib -Xcc -arch -Xcc i386 -target armv7s-apple-ios40.0 2>&1 | %FileCheck -DNORM=armv7s-apple-ios %s // RUN: not %target-swift-frontend %s -typecheck -I %t -parse-stdlib -Xcc -arch -Xcc i386 -target armv7k-apple-ios40.0 2>&1 | %FileCheck -DNORM=armv7k-apple-ios %s // RUN: not %target-swift-frontend %s -typecheck -I %t -parse-stdlib -Xcc -arch -Xcc i386 -target armv7-apple-ios40.0 2>&1 | %FileCheck -DNORM=armv7-apple-ios %s +// RUN: not %target-swift-frontend %s -typecheck -I %t -parse-stdlib -Xcc -arch -Xcc i386 -target arm64e-apple-ios40.0 2>&1 | %FileCheck -DNORM=arm64e-apple-ios %s // x86_64h should be accepted. diff --git a/test/TBD/arm64e-arch.swift b/test/TBD/arm64e-arch.swift new file mode 100644 index 0000000000000..5f6d2f1987a0e --- /dev/null +++ b/test/TBD/arm64e-arch.swift @@ -0,0 +1,7 @@ +// RUN: %swift -typecheck -target arm64e-apple-ios12.0 -parse-stdlib -parse-as-library %s -module-name TBDTester -emit-tbd -emit-tbd-path - | %FileCheck %s + +public func testSwiftFunc() {} + +// CHECK: --- !tapi-tbd-v3 +// CHECK: archs: [ arm64e ] +// CHECK: symbols: [ '_$s{{.*}}testSwiftFunc{{.*}}' ] diff --git a/test/decl/protocol/conforms/nscoding.swift b/test/decl/protocol/conforms/nscoding.swift index 2ec04609a7367..69f839bc0721c 100644 --- a/test/decl/protocol/conforms/nscoding.swift +++ b/test/decl/protocol/conforms/nscoding.swift @@ -8,6 +8,7 @@ // RUN: %FileCheck --check-prefix=NEGATIVE %s < %t/old.ast // REQUIRES: objc_interop +// UNSUPPORTED: CPU=arm64e // See also nscoding_stable_abi.swift, for the stable ABI deployment // target test. diff --git a/test/lit.cfg b/test/lit.cfg index 6304fab47c001..116e839b031fc 100644 --- a/test/lit.cfg +++ b/test/lit.cfg @@ -328,6 +328,7 @@ if run_os == 'ios' and run_vers.endswith('-macabi'): run_os = 'maccatalyst' run_ptrsize = '64' if ('64' in run_cpu or run_cpu == "s390x") else '32' +run_ptrauth = 'ptrauth' if run_cpu == 'arm64e' else 'noptrauth' run_endian = 'little' if run_cpu != 's390x' else 'big' sdk_overlay_link_path = "" @@ -433,6 +434,7 @@ config.substitutions.append( ('%swift-demangle-yamldump', config.swift_demangle_ config.substitutions.append( ('%Benchmark_O', config.benchmark_o) ) config.substitutions.append( ('%Benchmark_Driver', config.benchmark_driver) ) config.substitutions.append( ('%llvm-strings', config.llvm_strings) ) +config.substitutions.append( ('%target-ptrauth', run_ptrauth ) ) # This must come after all substitutions containing "%swift". config.substitutions.append( @@ -687,6 +689,9 @@ config.substitutions.append(('%target-cpu', run_cpu)) target_os_abi = run_os target_os_is_maccatalyst = "FALSE" +target_mandates_deployment_target_gte_13_0 = "FALSE" +if run_cpu == 'arm64e': + target_mandates_deployment_target_gte_13_0 = "TRUE" if (run_os == 'maccatalyst'): # For purposes of ABI, treat maccatalyst as macosx since the maccatalyst ABI # must match the macosx ABI. @@ -695,6 +700,8 @@ if (run_os == 'maccatalyst'): config.available_features.add("OS=ios") config.substitutions.append(('%target-os-abi', target_os_abi)) config.substitutions.append(('%target-os-is-maccatalyst', target_os_is_maccatalyst)) +config.substitutions.append(('%target-mandates-deployment-target-gte-13.0', + target_mandates_deployment_target_gte_13_0)) config.substitutions.append(('%target-endian', run_endian)) config.substitutions.append(('%target-os', run_os)) config.substitutions.append(('%target-ptrsize', run_ptrsize)) diff --git a/test/multifile/nested_types.swift b/test/multifile/nested_types.swift index 03596a4386535..08a634d1e9562 100644 --- a/test/multifile/nested_types.swift +++ b/test/multifile/nested_types.swift @@ -2,10 +2,10 @@ // Make sure we generate the outer metadata. -// CHECK-DAG: @"$s4test5OuterVMf" = internal constant {{.*}} {{@"\$sytWV"|i8\*\* getelementptr inbounds \(%swift.vwtable, %swift.vwtable\* @"\$s4test5OuterVWV", i32 0, i32 0\)}}, {{.*}} @"$s4test5OuterVMn" -// CHECK-DAG: @"$s4test6Outer2VMf" = internal constant {{.*}} {{@"\$sytWV"|i8\*\* getelementptr inbounds \(%swift.vwtable, %swift.vwtable\* @"\$s4test6Outer2VWV", i32 0, i32 0\)}}, {{.*}} @"$s4test6Outer2VMn" -// CHECK-DAG: @"$s4test6Outer3VMf" = internal constant {{.*}} {{@"\$sytWV"|i8\*\* getelementptr inbounds \(%swift.vwtable, %swift.vwtable\* @"\$s4test6Outer3VWV", i32 0, i32 0\)}}, {{.*}} @"$s4test6Outer3VMn" -// CHECK-DAG: @"$s4test6Outer4VMf" = internal constant {{.*}} {{@"\$sytWV"|i8\*\* getelementptr inbounds \(%swift.vwtable, %swift.vwtable\* @"\$s4test6Outer4VWV", i32 0, i32 0\)}}, {{.*}} @"$s4test6Outer4VMn" +// CHECK-DAG: @"$s4test5OuterVMf" = internal constant {{.*}} {{@"\$sytWV"|i8\*\* getelementptr inbounds \(%swift.vwtable, %swift.vwtable\* @"\$s4test5OuterVWV", i32 0, i32 0\)}}, {{.*}} @"$s4test5OuterVMn{{(\.ptrauth)?}}" +// CHECK-DAG: @"$s4test6Outer2VMf" = internal constant {{.*}} {{@"\$sytWV"|i8\*\* getelementptr inbounds \(%swift.vwtable, %swift.vwtable\* @"\$s4test6Outer2VWV", i32 0, i32 0\)}}, {{.*}} @"$s4test6Outer2VMn{{(\.ptrauth)?}}" +// CHECK-DAG: @"$s4test6Outer3VMf" = internal constant {{.*}} {{@"\$sytWV"|i8\*\* getelementptr inbounds \(%swift.vwtable, %swift.vwtable\* @"\$s4test6Outer3VWV", i32 0, i32 0\)}}, {{.*}} @"$s4test6Outer3VMn{{(\.ptrauth)?}}" +// CHECK-DAG: @"$s4test6Outer4VMf" = internal constant {{.*}} {{@"\$sytWV"|i8\*\* getelementptr inbounds \(%swift.vwtable, %swift.vwtable\* @"\$s4test6Outer4VWV", i32 0, i32 0\)}}, {{.*}} @"$s4test6Outer4VMn{{(\.ptrauth[.0-9]*)?}}" class C { } diff --git a/test/stdlib/FloatingPointIR.swift b/test/stdlib/FloatingPointIR.swift index 9fadab623f92e..ff370af0099ca 100644 --- a/test/stdlib/FloatingPointIR.swift +++ b/test/stdlib/FloatingPointIR.swift @@ -38,6 +38,9 @@ func testConstantFoldFloatLiterals() { // arm64: call swiftcc void @"$s15FloatingPointIR13acceptFloat32yySfF{{.*}}"(float 1.000000e+00) // arm64: call swiftcc void @"$s15FloatingPointIR13acceptFloat64yySdF{{.*}}"(double 1.000000e+00) +// arm64e: call swiftcc void @"$s15FloatingPointIR13acceptFloat32yySfF{{.*}}"(float 1.000000e+00) +// arm64e: call swiftcc void @"$s15FloatingPointIR13acceptFloat64yySdF{{.*}}"(double 1.000000e+00) + // aarch64: call swiftcc void @"$s15FloatingPointIR13acceptFloat32yySfF{{.*}}"(float 1.000000e+00) // aarch64: call swiftcc void @"$s15FloatingPointIR13acceptFloat64yySdF{{.*}}"(double 1.000000e+00) diff --git a/test/stdlib/TestNSNumberBridging.swift b/test/stdlib/TestNSNumberBridging.swift index 208889cd1d52e..10d8f009bf3a2 100644 --- a/test/stdlib/TestNSNumberBridging.swift +++ b/test/stdlib/TestNSNumberBridging.swift @@ -24,6 +24,7 @@ // UNSUPPORTED: CPU=armv7s // UNSUPPORTED: CPU=armv7k // UNSUPPORTED: CPU=arm64 +// UNSUPPORTED: CPU=arm64e import StdlibUnittest import Foundation diff --git a/tools/swift-reflection-dump/swift-reflection-dump.cpp b/tools/swift-reflection-dump/swift-reflection-dump.cpp index 62b10d0e450dc..f84ae1049e9dd 100644 --- a/tools/swift-reflection-dump/swift-reflection-dump.cpp +++ b/tools/swift-reflection-dump/swift-reflection-dump.cpp @@ -286,6 +286,17 @@ class Image { Segments.push_back({HeaderAddress, O->getData()}); } + bool isMachOWithPtrAuth() const { + auto macho = dyn_cast(O); + if (!macho) + return false; + + auto &header = macho->getHeader(); + + return header.cputype == llvm::MachO::CPU_TYPE_ARM64 + && header.cpusubtype == llvm::MachO::CPU_SUBTYPE_ARM64E; + } + public: explicit Image(const ObjectFile *O) : O(O) { // Unfortunately llvm doesn't provide a uniform interface for iterating @@ -301,6 +312,8 @@ class Image { abort(); } } + + const ObjectFile *getObjectFile() const { return O; } unsigned getBytesInAddress() const { return O->getBytesInAddress(); @@ -338,7 +351,15 @@ class Image { auto found = DynamicRelocations.find(Addr); RemoteAbsolutePointer result; if (found == DynamicRelocations.end()) - result = RemoteAbsolutePointer("", pointerValue); + // In Mach-O images with ptrauth, the pointer value has an offset from + // the base address in the low 32 bits, and ptrauth discriminator info + // in the top 32 bits. + if (isMachOWithPtrAuth()) { + result = RemoteAbsolutePointer("", + HeaderAddress + (pointerValue & 0xffffffffull)); + } else { + result = RemoteAbsolutePointer("", pointerValue); + } else result = RemoteAbsolutePointer(found->second.Symbol, found->second.Offset); @@ -454,6 +475,13 @@ class ObjectMemoryReader : public MemoryReader { *result = wordSize; return true; } + case DLQ_GetPtrAuthMask: { + // We don't try to sign pointers at all in our view of the object + // mapping. + auto result = static_cast(outBuffer); + *result = (uintptr_t)~0ull; + return true; + } case DLQ_GetObjCReservedLowBits: { auto result = static_cast(outBuffer); if (applePlatform && !iosDerivedPlatform && wordSize == 8) { diff --git a/utils/build-script-impl b/utils/build-script-impl index 77332eefd1828..febc5d8647805 100755 --- a/utils/build-script-impl +++ b/utils/build-script-impl @@ -420,6 +420,7 @@ function verify_host_is_supported() { | iphoneos-armv7 \ | iphoneos-armv7s \ | iphoneos-arm64 \ + | iphoneos-arm64e \ | appletvsimulator-x86_64 \ | appletvos-arm64 \ | watchsimulator-i386 \ @@ -519,6 +520,13 @@ function set_build_options_for_host() { SWIFT_HOST_TRIPLE="arm64-apple-ios${DARWIN_DEPLOYMENT_VERSION_IOS}" llvm_target_arch="AArch64" + SWIFT_HOST_VARIANT_SDK="IOS" + cmake_osx_deployment_target="" + ;; + iphoneos-arm64e) + SWIFT_HOST_TRIPLE="arm64e-apple-ios${DARWIN_DEPLOYMENT_VERSION_IOS}" + llvm_target_arch="AArch64" + SWIFT_HOST_VARIANT_SDK="IOS" cmake_osx_deployment_target="" ;; diff --git a/utils/swift_build_support/swift_build_support/targets.py b/utils/swift_build_support/swift_build_support/targets.py index 45bb45ca9916a..18721d60eb0dd 100644 --- a/utils/swift_build_support/swift_build_support/targets.py +++ b/utils/swift_build_support/swift_build_support/targets.py @@ -117,7 +117,7 @@ class StdlibDeploymentTarget(object): OSX = DarwinPlatform("macosx", archs=["x86_64"], sdk_name="OSX") - iOS = DarwinPlatform("iphoneos", archs=["armv7", "armv7s", "arm64"], + iOS = DarwinPlatform("iphoneos", archs=["armv7", "armv7s", "arm64", "arm64e"], sdk_name="IOS") iOSSimulator = DarwinPlatform("iphonesimulator", archs=["i386", "x86_64"], sdk_name="IOS_SIMULATOR",