diff --git a/CMakeLists.txt b/CMakeLists.txt index ed7615fbe82d3..966c7bdd9639e 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -458,6 +458,12 @@ if(SWIFT_PATH_TO_CMARK_BUILD) endif() message(STATUS "") +if("${SWIFT_NATIVE_LLVM_TOOLS_PATH}" STREQUAL "") + set(SWIFT_CROSS_COMPILING FALSE) +else() + set(SWIFT_CROSS_COMPILING TRUE) +endif() + include(SwiftSharedCMakeConfig) # NOTE: We include this before SwiftComponents as it relies on some LLVM CMake diff --git a/benchmark/cmake/modules/AddSwiftBenchmarkSuite.cmake b/benchmark/cmake/modules/AddSwiftBenchmarkSuite.cmake index 0f4a776a2ba05..ea36002f8eabe 100644 --- a/benchmark/cmake/modules/AddSwiftBenchmarkSuite.cmake +++ b/benchmark/cmake/modules/AddSwiftBenchmarkSuite.cmake @@ -105,7 +105,7 @@ macro(configure_build) endmacro() macro(configure_sdks_darwin) - set(macosx_arch "x86_64") + set(macosx_arch "x86_64" "arm64") set(iphoneos_arch "arm64" "arm64e" "armv7") set(appletvos_arch "arm64") set(watchos_arch "armv7k") @@ -609,11 +609,7 @@ function (swift_benchmark_compile_archopts) if(is_darwin) # If host == target. - if("${BENCH_COMPILE_ARCHOPTS_PLATFORM}" STREQUAL "macosx") - set(OUTPUT_EXEC "${benchmark-bin-dir}/Benchmark_${BENCH_COMPILE_ARCHOPTS_OPT}") - else() - set(OUTPUT_EXEC "${benchmark-bin-dir}/Benchmark_${BENCH_COMPILE_ARCHOPTS_OPT}-${target}") - endif() + set(OUTPUT_EXEC "${benchmark-bin-dir}/Benchmark_${BENCH_COMPILE_ARCHOPTS_OPT}-${target}") else() # If we are on Linux, we do not support cross compiling. set(OUTPUT_EXEC "${benchmark-bin-dir}/Benchmark_${BENCH_COMPILE_ARCHOPTS_OPT}") diff --git a/cmake/modules/DarwinSDKs.cmake b/cmake/modules/DarwinSDKs.cmake index 23fa42a9bd43e..5ad1e32d1d8a1 100644 --- a/cmake/modules/DarwinSDKs.cmake +++ b/cmake/modules/DarwinSDKs.cmake @@ -4,17 +4,34 @@ option(SWIFT_ENABLE_IOS32 if(SWIFT_ENABLE_IOS32) set(SUPPORTED_IOS_ARCHS "armv7;armv7s;arm64;arm64e") -set(SUPPORTED_IOS_SIMULATOR_ARCHS "i386;x86_64") +set(SUPPORTED_IOS_SIMULATOR_ARCHS "i386;x86_64;arm64") else() set(SUPPORTED_IOS_ARCHS "arm64;arm64e") -set(SUPPORTED_IOS_SIMULATOR_ARCHS "x86_64") +set(SUPPORTED_IOS_SIMULATOR_ARCHS "x86_64;arm64") endif() set(SUPPORTED_TVOS_ARCHS "arm64") -set(SUPPORTED_TVOS_SIMULATOR_ARCHS "x86_64") +set(SUPPORTED_TVOS_SIMULATOR_ARCHS "x86_64;arm64") set(SUPPORTED_WATCHOS_ARCHS "armv7k") -set(SUPPORTED_WATCHOS_SIMULATOR_ARCHS "i386") -set(SUPPORTED_OSX_ARCHS "x86_64") +set(SUPPORTED_WATCHOS_SIMULATOR_ARCHS "i386;arm64") +set(SUPPORTED_OSX_ARCHS "x86_64;arm64;arm64e") + +# Get the SDK version from SDKSettings. +execute_process( + COMMAND "defaults" "read" "${CMAKE_OSX_SYSROOT}/SDKSettings.plist" "Version" + OUTPUT_VARIABLE SWIFT_OSX_SDK_VERSION + OUTPUT_STRIP_TRAILING_WHITESPACE) + +# Remove the last component, if any. e.g. 10.15.26 -> 10.15 +string(REGEX REPLACE "\([0-9]*[.][0-9]*\)[.][0-9]*" "\\1" + SWIFT_OSX_SDK_VERSION "${SWIFT_OSX_SDK_VERSION}") + +if (${SWIFT_OSX_SDK_VERSION} STREQUAL "10.14" OR + ${SWIFT_OSX_SDK_VERSION} STREQUAL "10.15") + set(SUPPORTED_OSX_ARCHS "x86_64") +else() + set(SUPPORTED_OSX_ARCHS "x86_64;arm64e") +endif() is_sdk_requested(OSX swift_build_osx) if(swift_build_osx) diff --git a/cmake/modules/SwiftConfigureSDK.cmake b/cmake/modules/SwiftConfigureSDK.cmake index 09d45cc3a34a3..52c08025e62a0 100644 --- a/cmake/modules/SwiftConfigureSDK.cmake +++ b/cmake/modules/SwiftConfigureSDK.cmake @@ -85,6 +85,38 @@ function(_report_sdk prefix) message(STATUS "") endfunction() +# Remove architectures not supported by the SDK from the given list. +function(remove_sdk_unsupported_archs name os sdk_path architectures_var) + execute_process(COMMAND + /usr/libexec/PlistBuddy -c "Print :SupportedTargets:${os}:Archs" ${sdk_path}/SDKSettings.plist + OUTPUT_VARIABLE sdk_supported_archs + RESULT_VARIABLE plist_error) + + if (NOT plist_error EQUAL 0) + message(STATUS "${os} SDK at ${sdk_path} does not publish its supported architectures") + return() + endif() + + set(architectures) + foreach(arch ${${architectures_var}}) + if(sdk_supported_archs MATCHES "${arch}\n") + list(APPEND architectures ${arch}) + elseif(arch MATCHES "^armv7(s)?$" AND os STREQUAL "iphoneos") + # 32-bit iOS is not listed explicitly in SDK settings. + message(STATUS "Assuming ${name} SDK at ${sdk_path} supports architecture ${arch}") + list(APPEND architectures ${arch}) + elseif(arch STREQUAL "i386" AND os STREQUAL "iphonesimulator") + # 32-bit iOS simulatoris not listed explicitly in SDK settings. + message(STATUS "Assuming ${name} SDK at ${sdk_path} supports architecture ${arch}") + list(APPEND architectures ${arch}) + else() + message(STATUS "${name} SDK at ${sdk_path} does not support architecture ${arch}") + endif() + endforeach() + + set("${architectures_var}" ${architectures} PARENT_SCOPE) +endfunction() + # Configure an SDK # # Usage: @@ -164,6 +196,9 @@ macro(configure_sdk_darwin SWIFT_SDK_${prefix}_ARCHITECTURES) # result endif() + # Remove any architectures not supported by the SDK. + remove_sdk_unsupported_archs(${name} ${xcrun_name} ${SWIFT_SDK_${prefix}_PATH} SWIFT_SDK_${prefix}_ARCHITECTURES) + list_intersect( "${SWIFT_DARWIN_MODULE_ARCHS}" # lhs "${architectures}" # rhs diff --git a/cmake/modules/SwiftSharedCMakeConfig.cmake b/cmake/modules/SwiftSharedCMakeConfig.cmake index 5bddf37d86816..c4c15084fe902 100644 --- a/cmake/modules/SwiftSharedCMakeConfig.cmake +++ b/cmake/modules/SwiftSharedCMakeConfig.cmake @@ -58,7 +58,7 @@ macro(swift_common_standalone_build_config_llvm product) fix_imported_targets_for_xcode("${LLVM_EXPORTED_TARGETS}") endif() - if(NOT CMAKE_CROSSCOMPILING) + if(NOT CMAKE_CROSSCOMPILING AND NOT SWIFT_CROSS_COMPILING) set(${product}_NATIVE_LLVM_TOOLS_PATH "${LLVM_TOOLS_BINARY_DIR}") endif() diff --git a/include/swift/AST/AvailabilitySpec.h b/include/swift/AST/AvailabilitySpec.h index 05c0752bffaab..86b0342419a1a 100644 --- a/include/swift/AST/AvailabilitySpec.h +++ b/include/swift/AST/AvailabilitySpec.h @@ -68,16 +68,33 @@ class PlatformVersionConstraintAvailabilitySpec : public AvailabilitySpec { SourceLoc PlatformLoc; llvm::VersionTuple Version; + + // For macOS Big Sur, we canonicalize 10.16 to 11.0 for compile-time + // checking since clang canonicalizes availability markup. However, to + // support Beta versions of macOS Big Sur where the OS + // reports 10.16 at run time, we need to compare against 10.16, + // + // This means for: + // + // if #available(macOS 10.16, *) { ... } + // + // we need to keep around both a canonical version for use in compile-time + // checks and an uncanonicalized version for the version to actually codegen + // with. + llvm::VersionTuple RuntimeVersion; + SourceRange VersionSrcRange; public: PlatformVersionConstraintAvailabilitySpec(PlatformKind Platform, SourceLoc PlatformLoc, llvm::VersionTuple Version, + llvm::VersionTuple RuntimeVersion, SourceRange VersionSrcRange) : AvailabilitySpec(AvailabilitySpecKind::PlatformVersionConstraint), Platform(Platform), PlatformLoc(PlatformLoc), Version(Version), + RuntimeVersion(RuntimeVersion), VersionSrcRange(VersionSrcRange) {} /// The required platform. @@ -93,6 +110,11 @@ class PlatformVersionConstraintAvailabilitySpec : public AvailabilitySpec { llvm::VersionTuple getVersion() const { return Version; } SourceRange getVersionSrcRange() const { return VersionSrcRange; } + // The version to be used in codegen for version comparisons at run time. + // This is required to support beta versions of macOS Big Sur that + // report 10.16 at run time. + llvm::VersionTuple getRuntimeVersion() const { return RuntimeVersion; } + SourceRange getSourceRange() const; void print(raw_ostream &OS, unsigned Indent) const; diff --git a/include/swift/AST/DiagnosticsSema.def b/include/swift/AST/DiagnosticsSema.def index 2ab5a7a338234..ced5a901f8a1e 100644 --- a/include/swift/AST/DiagnosticsSema.def +++ b/include/swift/AST/DiagnosticsSema.def @@ -3151,6 +3151,8 @@ ERROR(autodiff_attr_original_multiple_semantic_results,none, ERROR(autodiff_attr_result_not_differentiable,none, "can only differentiate functions with results that conform to " "'Differentiable', but %0 does not conform to 'Differentiable'", (Type)) +ERROR(autodiff_attr_opaque_result_type_unsupported,none, + "cannot differentiate functions returning opaque result types", ()) // differentiation `wrt` parameters clause ERROR(diff_function_no_parameters,none, diff --git a/include/swift/AST/PlatformKind.h b/include/swift/AST/PlatformKind.h index f03d5adc8f7bf..be687b449b403 100644 --- a/include/swift/AST/PlatformKind.h +++ b/include/swift/AST/PlatformKind.h @@ -20,6 +20,7 @@ #include "swift/Basic/LLVM.h" #include "swift/Config.h" #include "llvm/ADT/StringRef.h" +#include "llvm/Support/VersionTuple.h" namespace swift { @@ -65,6 +66,9 @@ PlatformKind targetPlatform(const LangOptions &LangOpts); /// an explicit attribute for the child. bool inheritsAvailabilityFromPlatform(PlatformKind Child, PlatformKind Parent); +llvm::VersionTuple canonicalizePlatformVersion( + PlatformKind platform, const llvm::VersionTuple &version); + } // end namespace swift #endif diff --git a/include/swift/AST/SubstitutionMap.h b/include/swift/AST/SubstitutionMap.h index fa883df80b080..2f3549fabf6ba 100644 --- a/include/swift/AST/SubstitutionMap.h +++ b/include/swift/AST/SubstitutionMap.h @@ -286,6 +286,12 @@ class SubstitutionMap { Type lookupSubstitution(CanSubstitutableType type) const; }; +inline llvm::raw_ostream &operator<<(llvm::raw_ostream &OS, + const SubstitutionMap &subs) { + subs.dump(OS); + return OS; +} + /// A function object suitable for use as a \c TypeSubstitutionFn that /// queries an underlying \c SubstitutionMap. struct QuerySubstitutionMap { diff --git a/include/swift/AST/TypeCheckRequests.h b/include/swift/AST/TypeCheckRequests.h index 04fe9c2bc2183..48dd1a5b58301 100644 --- a/include/swift/AST/TypeCheckRequests.h +++ b/include/swift/AST/TypeCheckRequests.h @@ -2192,7 +2192,7 @@ class DerivativeAttrOriginalDeclRequest /// property in a `Differentiable`-conforming type. class TangentStoredPropertyRequest : public SimpleRequest { public: using SimpleRequest::SimpleRequest; @@ -2201,8 +2201,8 @@ class TangentStoredPropertyRequest friend SimpleRequest; // Evaluation. - TangentPropertyInfo evaluate(Evaluator &evaluator, - VarDecl *originalField) const; + TangentPropertyInfo evaluate(Evaluator &evaluator, VarDecl *originalField, + CanType parentType) const; public: // Caching. diff --git a/include/swift/AST/TypeCheckerTypeIDZone.def b/include/swift/AST/TypeCheckerTypeIDZone.def index c77b86bde2ed1..2f5ee6f22796a 100644 --- a/include/swift/AST/TypeCheckerTypeIDZone.def +++ b/include/swift/AST/TypeCheckerTypeIDZone.def @@ -204,7 +204,7 @@ SWIFT_REQUEST(TypeChecker, SynthesizeAccessorRequest, AccessorDecl *(AbstractStorageDecl *, AccessorKind), SeparatelyCached, NoLocationInfo) SWIFT_REQUEST(TypeChecker, TangentStoredPropertyRequest, - llvm::Expected(VarDecl *), Cached, NoLocationInfo) + llvm::Expected(VarDecl *, CanType), Cached, NoLocationInfo) SWIFT_REQUEST(TypeChecker, TypeCheckFunctionBodyRequest, bool(AbstractFunctionDecl *), Cached, NoLocationInfo) SWIFT_REQUEST(TypeChecker, TypeCheckFunctionBodyAtLocRequest, diff --git a/include/swift/Remote/InProcessMemoryReader.h b/include/swift/Remote/InProcessMemoryReader.h index 2f6b5b535a437..c5147e56db9c0 100644 --- a/include/swift/Remote/InProcessMemoryReader.h +++ b/include/swift/Remote/InProcessMemoryReader.h @@ -38,7 +38,7 @@ class InProcessMemoryReader final : public MemoryReader { #else auto applePlatform = false; #endif -#if defined(__APPLE__) && __APPLE__ && ((defined(TARGET_OS_IOS) && TARGET_OS_IOS) || (defined(TARGET_OS_IOS) && TARGET_OS_WATCH) || (defined(TARGET_OS_TV) && TARGET_OS_TV)) +#if defined(__APPLE__) && __APPLE__ && ((defined(TARGET_OS_IOS) && TARGET_OS_IOS) || (defined(TARGET_OS_IOS) && TARGET_OS_WATCH) || (defined(TARGET_OS_TV) && TARGET_OS_TV) || defined(__arm64__)) auto iosDerivedPlatform = true; #else auto iosDerivedPlatform = false; @@ -67,7 +67,7 @@ class InProcessMemoryReader final : public MemoryReader { case DLQ_GetObjCReservedLowBits: { auto result = static_cast(outBuffer); if (applePlatform && !iosDerivedPlatform && (sizeof(void *) == 8)) { - // Obj-C reserves low bit on 64-bit macOS only. + // Obj-C reserves low bit on 64-bit Intel macOS only. // Other Apple platforms don't reserve this bit (even when // running on x86_64-based simulators). *result = 1; diff --git a/include/swift/SIL/ApplySite.h b/include/swift/SIL/ApplySite.h index 6f8b911f46369..de97fef3e9bf0 100644 --- a/include/swift/SIL/ApplySite.h +++ b/include/swift/SIL/ApplySite.h @@ -21,9 +21,11 @@ #ifndef SWIFT_SIL_APPLYSITE_H #define SWIFT_SIL_APPLYSITE_H +#include "swift/SIL/SILArgument.h" #include "swift/SIL/SILBasicBlock.h" -#include "swift/SIL/SILInstruction.h" #include "swift/SIL/SILFunction.h" +#include "swift/SIL/SILInstruction.h" +#include "llvm/ADT/ArrayRef.h" namespace swift { @@ -502,6 +504,34 @@ class FullApplySite : public ApplySite { return getSubstCalleeConv().hasIndirectSILResults(); } + /// If our apply site has a single direct result SILValue, return that + /// SILValue. Return SILValue() otherwise. + /// + /// This means that: + /// + /// 1. If we have an ApplyInst, we just visit the apply. + /// 2. If we have a TryApplyInst, we visit the first argument of the normal + /// block. + /// 3. If we have a BeginApplyInst, we return SILValue() since the begin_apply + /// yields values instead of returning them. A returned value should only + /// be valid after a full apply site has completely finished executing. + SILValue getSingleDirectResult() const { + switch (getKind()) { + case FullApplySiteKind::ApplyInst: + return SILValue(cast(getInstruction())); + case FullApplySiteKind::BeginApplyInst: { + return SILValue(); + } + case FullApplySiteKind::TryApplyInst: { + auto *normalBlock = cast(getInstruction())->getNormalBB(); + assert(normalBlock->getNumArguments() == 1 && + "Expected try apply to have a single result"); + return normalBlock->getArgument(0); + } + } + llvm_unreachable("Covered switch isn't covered?!"); + } + unsigned getNumIndirectSILResults() const { return getSubstCalleeConv().getNumIndirectSILResults(); } diff --git a/include/swift/SIL/SILBuilder.h b/include/swift/SIL/SILBuilder.h index a2b220d06b8b5..10422ec523278 100644 --- a/include/swift/SIL/SILBuilder.h +++ b/include/swift/SIL/SILBuilder.h @@ -726,7 +726,8 @@ class SILBuilder { } LoadBorrowInst *createLoadBorrow(SILLocation Loc, SILValue LV) { - assert(isLoadableOrOpaque(LV->getType())); + assert(isLoadableOrOpaque(LV->getType()) && + !LV->getType().isTrivial(getFunction())); return insert(new (getModule()) LoadBorrowInst(getSILDebugLocation(Loc), LV)); } @@ -737,11 +738,19 @@ class SILBuilder { BeginBorrowInst(getSILDebugLocation(Loc), LV)); } + /// Convenience function for creating a load_borrow on non-trivial values and + /// load [trivial] on trivial values. Becomes load unqualified in non-ossa + /// functions. SILValue emitLoadBorrowOperation(SILLocation loc, SILValue v) { if (!hasOwnership()) { return emitLoadValueOperation(loc, v, LoadOwnershipQualifier::Unqualified); } + + if (v->getType().isTrivial(getFunction())) { + return emitLoadValueOperation(loc, v, LoadOwnershipQualifier::Trivial); + } + return createLoadBorrow(loc, v); } @@ -877,6 +886,33 @@ class SILBuilder { StoreBorrowInst(getSILDebugLocation(Loc), Src, DestAddr)); } + /// A helper function for emitting store_borrow in operations where one must + /// handle both ossa and non-ossa code. + /// + /// In words: + /// + /// * If the function does not have ownership, this just emits an unqualified + /// store. + /// + /// * If the function has ownership, but the type is trivial, use store + /// [trivial]. + /// + /// * Otherwise, emit an actual store_borrow. + void emitStoreBorrowOperation(SILLocation loc, SILValue src, + SILValue destAddr) { + if (!hasOwnership()) { + return emitStoreValueOperation(loc, src, destAddr, + StoreOwnershipQualifier::Unqualified); + } + + if (src->getType().isTrivial(getFunction())) { + return emitStoreValueOperation(loc, src, destAddr, + StoreOwnershipQualifier::Trivial); + } + + createStoreBorrow(loc, src, destAddr); + } + MarkUninitializedInst * createMarkUninitialized(SILLocation Loc, SILValue src, MarkUninitializedInst::Kind k) { diff --git a/include/swift/SILOptimizer/Differentiation/Common.h b/include/swift/SILOptimizer/Differentiation/Common.h index 82bdb4a2a492d..2f996740b08b6 100644 --- a/include/swift/SILOptimizer/Differentiation/Common.h +++ b/include/swift/SILOptimizer/Differentiation/Common.h @@ -157,16 +157,18 @@ SILLocation getValidLocation(SILInstruction *inst); // Tangent property lookup utilities //===----------------------------------------------------------------------===// -/// Returns the tangent stored property of `originalField`. On error, emits -/// diagnostic and returns nullptr. +/// Returns the tangent stored property of the given original stored property +/// and base type. On error, emits diagnostic and returns nullptr. VarDecl *getTangentStoredProperty(ADContext &context, VarDecl *originalField, - SILLocation loc, + CanType baseType, SILLocation loc, DifferentiationInvoker invoker); /// Returns the tangent stored property of the original stored property -/// referenced by `inst`. On error, emits diagnostic and returns nullptr. +/// referenced by the given projection instruction with the given base type. +/// On error, emits diagnostic and returns nullptr. VarDecl *getTangentStoredProperty(ADContext &context, FieldIndexCacheBase *projectionInst, + CanType baseType, DifferentiationInvoker invoker); //===----------------------------------------------------------------------===// diff --git a/include/swift/SwiftRemoteMirror/SwiftRemoteMirrorLegacyInterop.h b/include/swift/SwiftRemoteMirror/SwiftRemoteMirrorLegacyInterop.h index e97d686e45da3..0b07ec7633390 100644 --- a/include/swift/SwiftRemoteMirror/SwiftRemoteMirrorLegacyInterop.h +++ b/include/swift/SwiftRemoteMirror/SwiftRemoteMirrorLegacyInterop.h @@ -585,7 +585,7 @@ swift_reflection_interop_minimalDataLayoutQueryFunction8( #else int applePlatform = 0; #endif -#if defined(__APPLE__) && __APPLE__ && ((defined(TARGET_OS_IOS) && TARGET_OS_IOS) || (defined(TARGET_OS_IOS) && TARGET_OS_WATCH) || (defined(TARGET_OS_TV) && TARGET_OS_TV)) +#if defined(__APPLE__) && __APPLE__ && ((defined(TARGET_OS_IOS) && TARGET_OS_IOS) || (defined(TARGET_OS_IOS) && TARGET_OS_WATCH) || (defined(TARGET_OS_TV) && TARGET_OS_TV) || defined(__arm64__)) int iosDerivedPlatform = 1; #else int iosDerivedPlatform = 0; diff --git a/lib/AST/AutoDiff.cpp b/lib/AST/AutoDiff.cpp index 87c65561dcf6c..83b7d981f08db 100644 --- a/lib/AST/AutoDiff.cpp +++ b/lib/AST/AutoDiff.cpp @@ -475,17 +475,16 @@ void swift::simple_display(llvm::raw_ostream &os, TangentPropertyInfo info) { os << " }"; } -TangentPropertyInfo -TangentStoredPropertyRequest::evaluate(Evaluator &evaluator, - VarDecl *originalField) const { - assert(originalField->hasStorage() && originalField->isInstanceMember() && - "Expected stored property"); +TangentPropertyInfo TangentStoredPropertyRequest::evaluate( + Evaluator &evaluator, VarDecl *originalField, CanType baseType) const { + assert(((originalField->hasStorage() && originalField->isInstanceMember()) || + originalField->hasAttachedPropertyWrapper()) && + "Expected a stored property or a property-wrapped property"); auto *parentDC = originalField->getDeclContext(); assert(parentDC->isTypeContext()); - auto parentType = parentDC->getDeclaredTypeInContext(); auto *moduleDecl = originalField->getModuleContext(); - auto parentTan = parentType->getAutoDiffTangentSpace( - LookUpConformanceInModule(moduleDecl)); + auto parentTan = + baseType->getAutoDiffTangentSpace(LookUpConformanceInModule(moduleDecl)); // Error if parent nominal type does not conform to `Differentiable`. if (!parentTan) { return TangentPropertyInfo( @@ -497,13 +496,18 @@ TangentStoredPropertyRequest::evaluate(Evaluator &evaluator, TangentPropertyInfo::Error::Kind::NoDerivativeOriginalProperty); } // Error if original property's type does not conform to `Differentiable`. - auto originalFieldTan = originalField->getType()->getAutoDiffTangentSpace( + auto originalFieldType = baseType->getTypeOfMember( + originalField->getModuleContext(), originalField); + auto originalFieldTan = originalFieldType->getAutoDiffTangentSpace( LookUpConformanceInModule(moduleDecl)); if (!originalFieldTan) { return TangentPropertyInfo( TangentPropertyInfo::Error::Kind::OriginalPropertyNotDifferentiable); } - auto parentTanType = parentTan->getType(); + // Get the parent `TangentVector` type. + auto parentTanType = + baseType->getAutoDiffTangentSpace(LookUpConformanceInModule(moduleDecl)) + ->getType(); auto *parentTanStruct = parentTanType->getStructOrBoundGenericStruct(); // Error if parent `TangentVector` is not a struct. if (!parentTanStruct) { @@ -533,7 +537,9 @@ TangentStoredPropertyRequest::evaluate(Evaluator &evaluator, // Error if tangent property's type is not equal to the original property's // `TangentVector` type. auto originalFieldTanType = originalFieldTan->getType(); - if (!originalFieldTanType->isEqual(tanField->getType())) { + auto tanFieldType = + parentTanType->getTypeOfMember(tanField->getModuleContext(), tanField); + if (!originalFieldTanType->isEqual(tanFieldType)) { return TangentPropertyInfo( TangentPropertyInfo::Error::Kind::TangentPropertyWrongType, originalFieldTanType); diff --git a/lib/AST/Availability.cpp b/lib/AST/Availability.cpp index ecdbe6451fdf8..48cb3911128e6 100644 --- a/lib/AST/Availability.cpp +++ b/lib/AST/Availability.cpp @@ -246,9 +246,16 @@ AvailabilityContext ASTContext::getSwift50Availability() { return AvailabilityContext::alwaysAvailable(); if (target.isMacOSX()) { + if (target.isAArch64()) + return AvailabilityContext::alwaysAvailable(); + return AvailabilityContext( VersionRange::allGTE(llvm::VersionTuple(10,14,4))); } else if (target.isiOS()) { + if (target.isAArch64() && + (target.isSimulatorEnvironment() || target.isMacCatalystEnvironment())) + return AvailabilityContext::alwaysAvailable(); + return AvailabilityContext( VersionRange::allGTE(llvm::VersionTuple(12,2))); } else if (target.isWatchOS()) { @@ -274,9 +281,16 @@ AvailabilityContext ASTContext::getSwift51Availability() { return AvailabilityContext::alwaysAvailable(); if (target.isMacOSX()) { + if (target.isAArch64()) + return AvailabilityContext::alwaysAvailable(); + return AvailabilityContext( VersionRange::allGTE(llvm::VersionTuple(10,15,0))); } else if (target.isiOS()) { + if (target.isAArch64() && + (target.isSimulatorEnvironment() || target.isMacCatalystEnvironment())) + return AvailabilityContext::alwaysAvailable(); + return AvailabilityContext( VersionRange::allGTE(llvm::VersionTuple(13,0,0))); } else if (target.isWatchOS()) { @@ -310,18 +324,27 @@ AvailabilityContext ASTContext::getSwift52Availability() { if (target.getArchName() == "arm64e") return AvailabilityContext::alwaysAvailable(); - if (target.isMacOSX() ) { + if (target.isMacOSX()) { + if (target.isAArch64()) + return AvailabilityContext::alwaysAvailable(); + return AvailabilityContext( - VersionRange::allGTE(llvm::VersionTuple(10, 99, 0))); + VersionRange::allGTE(llvm::VersionTuple(10, 15, 4))); } else if (target.isiOS()) { + if (target.isAArch64() && + (target.isSimulatorEnvironment() || target.isMacCatalystEnvironment())) + return AvailabilityContext::alwaysAvailable(); + return AvailabilityContext( - VersionRange::allGTE(llvm::VersionTuple(99, 0, 0))); + VersionRange::allGTE(llvm::VersionTuple(13, 4, 0))); } else if (target.isWatchOS()) { + if (target.isArch64Bit()) + return AvailabilityContext::alwaysAvailable(); + return AvailabilityContext( - VersionRange::allGTE(llvm::VersionTuple(9, 99, 0))); - } else { - return AvailabilityContext::alwaysAvailable(); + VersionRange::allGTE(llvm::VersionTuple(6, 2, 0))); } + return AvailabilityContext::alwaysAvailable(); } AvailabilityContext ASTContext::getSwift53Availability() { @@ -331,14 +354,26 @@ AvailabilityContext ASTContext::getSwift53Availability() { return AvailabilityContext::alwaysAvailable(); if (target.isMacOSX() ) { + if (target.isAArch64()) + return AvailabilityContext::alwaysAvailable(); + + llvm::VersionTuple macOVersion53(10, 16, 0); + macOVersion53 = canonicalizePlatformVersion(PlatformKind::OSX, macOVersion53); return AvailabilityContext( - VersionRange::allGTE(llvm::VersionTuple(10, 99, 0))); + VersionRange::allGTE(macOVersion53)); } else if (target.isiOS()) { + if (target.isAArch64() && + (target.isSimulatorEnvironment() || target.isMacCatalystEnvironment())) + return AvailabilityContext::alwaysAvailable(); + return AvailabilityContext( - VersionRange::allGTE(llvm::VersionTuple(99, 0, 0))); + VersionRange::allGTE(llvm::VersionTuple(14, 0, 0))); } else if (target.isWatchOS()) { + if (target.isArch64Bit()) + return AvailabilityContext::alwaysAvailable(); + return AvailabilityContext( - VersionRange::allGTE(llvm::VersionTuple(9, 99, 0))); + VersionRange::allGTE(llvm::VersionTuple(7, 0, 0))); } else { return AvailabilityContext::alwaysAvailable(); } @@ -349,7 +384,7 @@ AvailabilityContext ASTContext::getSwiftFutureAvailability() { if (target.isMacOSX() ) { return AvailabilityContext( - VersionRange::allGTE(llvm::VersionTuple(10, 99, 0))); + VersionRange::allGTE(llvm::VersionTuple(99, 99, 0))); } else if (target.isiOS()) { return AvailabilityContext( VersionRange::allGTE(llvm::VersionTuple(99, 0, 0))); diff --git a/lib/AST/PlatformKind.cpp b/lib/AST/PlatformKind.cpp index 707ba4473b5fe..2d283c951b654 100644 --- a/lib/AST/PlatformKind.cpp +++ b/lib/AST/PlatformKind.cpp @@ -20,6 +20,7 @@ #include "llvm/ADT/StringSwitch.h" #include "llvm/Support/ErrorHandling.h" + using namespace swift; StringRef swift::platformString(PlatformKind platform) { @@ -155,3 +156,17 @@ bool swift::inheritsAvailabilityFromPlatform(PlatformKind Child, return false; } + +llvm::VersionTuple swift::canonicalizePlatformVersion( + PlatformKind platform, const llvm::VersionTuple &version) { + + // Canonicalize macOS version for macOS Big Sur to treat + // 10.16 as 11.0. + if (platform == PlatformKind::OSX || + platform == PlatformKind::OSXApplicationExtension) { + return llvm::Triple::getCanonicalVersionForOS(llvm::Triple::MacOSX, + version); + } + + return version; +} diff --git a/lib/Basic/Platform.cpp b/lib/Basic/Platform.cpp index 3722a88062d41..6761891b8dcce 100644 --- a/lib/Basic/Platform.cpp +++ b/lib/Basic/Platform.cpp @@ -403,6 +403,9 @@ swift::getSwiftRuntimeCompatibilityVersionForTarget( if (Triple.isMacOSX()) { Triple.getMacOSXVersion(Major, Minor, Micro); if (Major == 10) { + if (Triple.isAArch64() && Minor <= 16) + return llvm::VersionTuple(5, 3); + if (Minor <= 14) { return llvm::VersionTuple(5, 0); } else if (Minor <= 15) { @@ -412,9 +415,18 @@ swift::getSwiftRuntimeCompatibilityVersionForTarget( return llvm::VersionTuple(5, 2); } } + } else if (Major == 11) { + return llvm::VersionTuple(5, 3); } } else if (Triple.isiOS()) { // includes tvOS Triple.getiOSVersion(Major, Minor, Micro); + + // arm64 simulators and macCatalyst are introduced in iOS 14.0/tvOS 14.0 + // with Swift 5.3 + if (Triple.isAArch64() && Major <= 14 && + (Triple.isSimulatorEnvironment() || Triple.isMacCatalystEnvironment())) + return llvm::VersionTuple(5, 3); + if (Major <= 12) { return llvm::VersionTuple(5, 0); } else if (Major <= 13) { diff --git a/lib/ClangImporter/ClangImporter.cpp b/lib/ClangImporter/ClangImporter.cpp index 53575b567fe8d..9fbde794820ff 100644 --- a/lib/ClangImporter/ClangImporter.cpp +++ b/lib/ClangImporter/ClangImporter.cpp @@ -732,11 +732,20 @@ importer::addCommonInvocationArguments( invocationArgStrs.push_back("-mcpu=" + importerOpts.TargetCPU); } 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. + // Special case CPU based on known deployments: + // - arm64 deploys to cyclone + // - arm64 on macOS + // - arm64 for iOS/tvOS/watchOS simulators + // - arm64e deploys to vortex + // and arm64e (everywhere) and arm64e macOS defaults to the "vortex" CPU + // for Darwin, but Clang only detects this if we use -arch. if (triple.getArchName() == "arm64e") invocationArgStrs.push_back("-mcpu=vortex"); + else if (triple.isAArch64() && triple.isMacOSX()) + invocationArgStrs.push_back("-mcpu=vortex"); + else if (triple.isAArch64() && triple.isSimulatorEnvironment() && + (triple.isiOS() || triple.isWatchOS())) + invocationArgStrs.push_back("-mcpu=vortex"); else if (triple.getArch() == llvm::Triple::aarch64 || triple.getArch() == llvm::Triple::aarch64_be) { invocationArgStrs.push_back("-mcpu=cyclone"); diff --git a/lib/Driver/DarwinToolChains.cpp b/lib/Driver/DarwinToolChains.cpp index 7bf80dd5748af..d2db59dced916 100644 --- a/lib/Driver/DarwinToolChains.cpp +++ b/lib/Driver/DarwinToolChains.cpp @@ -13,6 +13,7 @@ #include "ToolChains.h" #include "swift/AST/DiagnosticsDriver.h" +#include "swift/AST/PlatformKind.h" #include "swift/Basic/Dwarf.h" #include "swift/Basic/LLVM.h" #include "swift/Basic/Platform.h" @@ -591,6 +592,14 @@ toolchains::Darwin::addDeploymentTargetArgs(ArgStringList &Arguments, if (tripleIsMacCatalystEnvironment(triple)) { triple.getiOSVersion(major, minor, micro); + // Mac Catalyst on arm was introduced with an iOS deployment target of + // 14.0; the linker doesn't want to see a deployment target before that. + if (major < 14 && triple.isAArch64()) { + major = 14; + minor = 0; + micro = 0; + } + // Mac Catalyst was introduced with an iOS deployment target of 13.0; // the linker doesn't want to see a deployment target before that. if (major < 13) { @@ -602,12 +611,41 @@ toolchains::Darwin::addDeploymentTargetArgs(ArgStringList &Arguments, switch (getDarwinPlatformKind((triple))) { case DarwinPlatformKind::MacOS: triple.getMacOSXVersion(major, minor, micro); + + // The first deployment of arm64 for macOS is version 10.16; + if (triple.isAArch64() && major <= 10 && minor < 16) { + llvm::VersionTuple firstMacARM64e(10, 16, 0); + firstMacARM64e = canonicalizePlatformVersion(PlatformKind::OSX, + firstMacARM64e); + major = firstMacARM64e.getMajor(); + minor = firstMacARM64e.getMinor().getValueOr(0); + micro = firstMacARM64e.getSubminor().getValueOr(0); + } + + // Temporary hack: adjust macOS version passed to the linker from + // 11 down to 10.16, but only for x86. + if (triple.isX86() && major == 11) { + major = 10; + minor = 16; + micro = 0; + } + break; case DarwinPlatformKind::IPhoneOS: case DarwinPlatformKind::IPhoneOSSimulator: case DarwinPlatformKind::TvOS: case DarwinPlatformKind::TvOSSimulator: triple.getiOSVersion(major, minor, micro); + + // The first deployment of arm64 simulators is iOS/tvOS 14.0; + // the linker doesn't want to see a deployment target before that. + if (triple.isSimulatorEnvironment() && triple.isAArch64() && + major < 14) { + major = 14; + minor = 0; + micro = 0; + } + break; case DarwinPlatformKind::WatchOS: case DarwinPlatformKind::WatchOSSimulator: diff --git a/lib/Parse/ParseDecl.cpp b/lib/Parse/ParseDecl.cpp index 9f63a62c304b4..8c2b0a42e0cd3 100644 --- a/lib/Parse/ParseDecl.cpp +++ b/lib/Parse/ParseDecl.cpp @@ -578,6 +578,20 @@ ParserResult Parser::parseExtendedAvailabilitySpecList( return nullptr; } + if (PlatformKind) { + if (!Introduced.empty()) + Introduced.Version = + canonicalizePlatformVersion(*PlatformKind, Introduced.Version); + + if (!Deprecated.empty()) + Deprecated.Version = + canonicalizePlatformVersion(*PlatformKind, Deprecated.Version); + + if (!Obsoleted.empty()) + Obsoleted.Version = + canonicalizePlatformVersion(*PlatformKind, Obsoleted.Version); + } + auto Attr = new (Context) AvailableAttr(AtLoc, SourceRange(AttrLoc, Tok.getLoc()), PlatformKind.getValue(), @@ -2034,6 +2048,8 @@ bool Parser::parseNewDeclAttribute(DeclAttributes &Attributes, SourceLoc AtLoc, continue; } + Version = canonicalizePlatformVersion(Platform, Version); + Attributes.add(new (Context) AvailableAttr(AtLoc, AttrRange, Platform, diff --git a/lib/Parse/ParseExpr.cpp b/lib/Parse/ParseExpr.cpp index 76139ad8debfa..a1fbbd7e24bf3 100644 --- a/lib/Parse/ParseExpr.cpp +++ b/lib/Parse/ParseExpr.cpp @@ -3812,6 +3812,11 @@ Parser::parsePlatformVersionConstraintSpec() { // Register the platform name as a keyword token. TokReceiver->registerTokenKindChange(PlatformLoc, tok::contextual_keyword); + // Keep the original version around for run-time checks to support + // macOS Big Sur betas that report 10.16 at + // run time. + llvm::VersionTuple RuntimeVersion = Version; + Version = canonicalizePlatformVersion(*Platform, Version); return makeParserResult(new (Context) PlatformVersionConstraintAvailabilitySpec( - Platform.getValue(), PlatformLoc, Version, VersionRange)); + Platform.getValue(), PlatformLoc, Version, RuntimeVersion, VersionRange)); } diff --git a/lib/SILOptimizer/Differentiation/Common.cpp b/lib/SILOptimizer/Differentiation/Common.cpp index bd917dfbcd15f..5b507a765bc7d 100644 --- a/lib/SILOptimizer/Differentiation/Common.cpp +++ b/lib/SILOptimizer/Differentiation/Common.cpp @@ -271,11 +271,11 @@ SILLocation getValidLocation(SILInstruction *inst) { //===----------------------------------------------------------------------===// VarDecl *getTangentStoredProperty(ADContext &context, VarDecl *originalField, - SILLocation loc, + CanType baseType, SILLocation loc, DifferentiationInvoker invoker) { auto &astCtx = context.getASTContext(); auto tanFieldInfo = evaluateOrDefault( - astCtx.evaluator, TangentStoredPropertyRequest{originalField}, + astCtx.evaluator, TangentStoredPropertyRequest{originalField, baseType}, TangentPropertyInfo(nullptr)); // If no error, return the tangent property. if (tanFieldInfo) @@ -330,13 +330,14 @@ VarDecl *getTangentStoredProperty(ADContext &context, VarDecl *originalField, VarDecl *getTangentStoredProperty(ADContext &context, FieldIndexCacheBase *projectionInst, + CanType baseType, DifferentiationInvoker invoker) { assert(isa(projectionInst) || isa(projectionInst) || isa(projectionInst)); auto loc = getValidLocation(projectionInst); - return getTangentStoredProperty(context, projectionInst->getField(), loc, - invoker); + return getTangentStoredProperty(context, projectionInst->getField(), baseType, + loc, invoker); } //===----------------------------------------------------------------------===// diff --git a/lib/SILOptimizer/Differentiation/JVPEmitter.cpp b/lib/SILOptimizer/Differentiation/JVPEmitter.cpp index 3f29d876529d3..0855d2d57a988 100644 --- a/lib/SILOptimizer/Differentiation/JVPEmitter.cpp +++ b/lib/SILOptimizer/Differentiation/JVPEmitter.cpp @@ -550,17 +550,18 @@ CLONE_AND_EMIT_TANGENT(StructExtract, sei) { "`struct_extract` with `@noDerivative` field should not be " "differentiated; activity analysis should not marked as varied."); auto diffBuilder = getDifferentialBuilder(); + auto loc = getValidLocation(sei); // Find the corresponding field in the tangent space. - auto *tanField = getTangentStoredProperty(context, sei, invoker); + auto structType = + remapSILTypeInDifferential(sei->getOperand()->getType()).getASTType(); + auto *tanField = getTangentStoredProperty(context, sei, structType, invoker); if (!tanField) { errorOccurred = true; return; } // Emit tangent `struct_extract`. - auto tanStruct = - materializeTangent(getTangentValue(sei->getOperand()), sei->getLoc()); - auto tangentInst = - diffBuilder.createStructExtract(sei->getLoc(), tanStruct, tanField); + auto tanStruct = materializeTangent(getTangentValue(sei->getOperand()), loc); + auto tangentInst = diffBuilder.createStructExtract(loc, tanStruct, tanField); // Update tangent value mapping for `struct_extract` result. auto tangentResult = makeConcreteTangentValue(tangentInst); setTangentValue(sei->getParent(), sei, tangentResult); @@ -577,8 +578,11 @@ CLONE_AND_EMIT_TANGENT(StructElementAddr, seai) { "differentiated; activity analysis should not marked as varied."); auto diffBuilder = getDifferentialBuilder(); auto *bb = seai->getParent(); + auto loc = getValidLocation(seai); // Find the corresponding field in the tangent space. - auto *tanField = getTangentStoredProperty(context, seai, invoker); + auto structType = + remapSILTypeInDifferential(seai->getOperand()->getType()).getASTType(); + auto *tanField = getTangentStoredProperty(context, seai, structType, invoker); if (!tanField) { errorOccurred = true; return; @@ -586,7 +590,7 @@ CLONE_AND_EMIT_TANGENT(StructElementAddr, seai) { // Emit tangent `struct_element_addr`. auto tanOperand = getTangentBuffer(bb, seai->getOperand()); auto tangentInst = - diffBuilder.createStructElementAddr(seai->getLoc(), tanOperand, tanField); + diffBuilder.createStructElementAddr(loc, tanOperand, tanField); // Update tangent buffer map for `struct_element_addr`. setTangentBuffer(bb, seai, tangentInst); } diff --git a/lib/SILOptimizer/Differentiation/PullbackEmitter.cpp b/lib/SILOptimizer/Differentiation/PullbackEmitter.cpp index 182c8862d2352..da0da45b261c9 100644 --- a/lib/SILOptimizer/Differentiation/PullbackEmitter.cpp +++ b/lib/SILOptimizer/Differentiation/PullbackEmitter.cpp @@ -371,7 +371,9 @@ SILValue PullbackEmitter::getAdjointProjection(SILBasicBlock *origBB, assert(!seai->getField()->getAttrs().hasAttribute() && "`@noDerivative` struct projections should never be active"); auto adjSource = getAdjointBuffer(origBB, seai->getOperand()); - auto *tanField = getTangentStoredProperty(getContext(), seai, getInvoker()); + auto structType = remapType(seai->getOperand()->getType()).getASTType(); + auto *tanField = + getTangentStoredProperty(getContext(), seai, structType, getInvoker()); assert(tanField && "Invalid projections should have been diagnosed"); return builder.createStructElementAddr(seai->getLoc(), adjSource, tanField); } @@ -400,7 +402,10 @@ SILValue PullbackEmitter::getAdjointProjection(SILBasicBlock *origBB, auto loc = reai->getLoc(); // Get the class operand, stripping `begin_borrow`. auto classOperand = stripBorrow(reai->getOperand()); - auto *tanField = getTangentStoredProperty(getContext(), reai, getInvoker()); + auto classType = remapType(reai->getOperand()->getType()).getASTType(); + auto *tanField = + getTangentStoredProperty(getContext(), reai->getField(), classType, + reai->getLoc(), getInvoker()); assert(tanField && "Invalid projections should have been diagnosed"); // Create a local allocation for the element adjoint buffer. auto eltTanType = tanField->getValueInterfaceType()->getCanonicalType(); @@ -666,8 +671,9 @@ bool PullbackEmitter::runForSemanticMemberGetter() { // Look up the corresponding field in the tangent space. auto *origField = cast(accessor->getStorage()); - auto *tanField = - getTangentStoredProperty(getContext(), origField, pbLoc, getInvoker()); + auto baseType = remapType(origSelf->getType()).getASTType(); + auto *tanField = getTangentStoredProperty(getContext(), origField, baseType, + pbLoc, getInvoker()); if (!tanField) { errorOccurred = true; return true; @@ -772,8 +778,9 @@ bool PullbackEmitter::runForSemanticMemberSetter() { // Look up the corresponding field in the tangent space. auto *origField = cast(accessor->getStorage()); - auto *tanField = - getTangentStoredProperty(getContext(), origField, pbLoc, getInvoker()); + auto baseType = remapType(origSelf->getType()).getASTType(); + auto *tanField = getTangentStoredProperty(getContext(), origField, baseType, + pbLoc, getInvoker()); if (!tanField) { errorOccurred = true; return true; @@ -882,7 +889,10 @@ bool PullbackEmitter::run() { } // Diagnose unsupported stored property projections. if (auto *inst = dyn_cast(v)) { - if (!getTangentStoredProperty(getContext(), inst, getInvoker())) { + assert(inst->getNumOperands() == 1); + auto baseType = remapType(inst->getOperand(0)->getType()).getASTType(); + if (!getTangentStoredProperty(getContext(), inst, baseType, + getInvoker())) { errorOccurred = true; return true; } @@ -1699,8 +1709,8 @@ void PullbackEmitter::visitStructInst(StructInst *si) { if (field->getAttrs().hasAttribute()) continue; // Find the corresponding field in the tangent space. - auto *tanField = - getTangentStoredProperty(getContext(), field, loc, getInvoker()); + auto *tanField = getTangentStoredProperty(getContext(), field, structTy, + loc, getInvoker()); if (!tanField) { errorOccurred = true; return; @@ -1732,6 +1742,7 @@ void PullbackEmitter::visitBeginApplyInst(BeginApplyInst *bai) { void PullbackEmitter::visitStructExtractInst(StructExtractInst *sei) { auto *bb = sei->getParent(); + auto loc = getValidLocation(sei); auto structTy = remapType(sei->getOperand()->getType()).getASTType(); auto tangentVectorTy = getTangentSpace(structTy)->getCanonicalType(); assert(!getTypeLowering(tangentVectorTy).isAddressOnly()); @@ -1739,14 +1750,15 @@ void PullbackEmitter::visitStructExtractInst(StructExtractInst *sei) { auto *tangentVectorDecl = tangentVectorTy->getStructOrBoundGenericStruct(); assert(tangentVectorDecl); // Find the corresponding field in the tangent space. - auto *tanField = getTangentStoredProperty(getContext(), sei, getInvoker()); + auto *tanField = + getTangentStoredProperty(getContext(), sei, structTy, getInvoker()); assert(tanField && "Invalid projections should have been diagnosed"); // Accumulate adjoint for the `struct_extract` operand. auto av = getAdjointValue(bb, sei); switch (av.getKind()) { case AdjointValueKind::Zero: addAdjointValue(bb, sei->getOperand(), - makeZeroAdjointValue(tangentVectorSILTy), sei->getLoc()); + makeZeroAdjointValue(tangentVectorSILTy), loc); break; case AdjointValueKind::Concrete: case AdjointValueKind::Aggregate: { @@ -1765,7 +1777,7 @@ void PullbackEmitter::visitStructExtractInst(StructExtractInst *sei) { } addAdjointValue(bb, sei->getOperand(), makeAggregateAdjointValue(tangentVectorSILTy, eltVals), - sei->getLoc()); + loc); } } } @@ -1775,7 +1787,9 @@ void PullbackEmitter::visitRefElementAddrInst(RefElementAddrInst *reai) { auto loc = reai->getLoc(); auto adjBuf = getAdjointBuffer(bb, reai); auto classOperand = reai->getOperand(); - auto *tanField = getTangentStoredProperty(getContext(), reai, getInvoker()); + auto classType = remapType(reai->getOperand()->getType()).getASTType(); + auto *tanField = + getTangentStoredProperty(getContext(), reai, classType, getInvoker()); assert(tanField && "Invalid projections should have been diagnosed"); switch (getTangentValueCategory(classOperand)) { case SILValueCategory::Object: { diff --git a/lib/SILOptimizer/Transforms/GenericSpecializer.cpp b/lib/SILOptimizer/Transforms/GenericSpecializer.cpp index 60bb6377fe69c..cd54f6a7e5efb 100644 --- a/lib/SILOptimizer/Transforms/GenericSpecializer.cpp +++ b/lib/SILOptimizer/Transforms/GenericSpecializer.cpp @@ -28,6 +28,10 @@ using namespace swift; +// For testing during bring up. +static llvm::cl::opt EnableGenericSpecializerWithOwnership( + "sil-generic-specializer-enable-ownership", llvm::cl::init(false)); + namespace { class GenericSpecializer : public SILFunctionTransform { @@ -39,7 +43,7 @@ class GenericSpecializer : public SILFunctionTransform { SILFunction &F = *getFunction(); // TODO: We should be able to handle ownership. - if (F.hasOwnership()) + if (F.hasOwnership() && !EnableGenericSpecializerWithOwnership) return; LLVM_DEBUG(llvm::dbgs() << "***** GenericSpecializer on function:" diff --git a/lib/SILOptimizer/Utils/GenericCloner.cpp b/lib/SILOptimizer/Utils/GenericCloner.cpp index 438a47ca78e81..e027cdfb3927f 100644 --- a/lib/SILOptimizer/Utils/GenericCloner.cpp +++ b/lib/SILOptimizer/Utils/GenericCloner.cpp @@ -79,8 +79,9 @@ void GenericCloner::populateCloned() { auto createAllocStack = [&]() { // We need an alloc_stack as a replacement for the indirect parameter. - assert(mappedType.isAddress()); - mappedType = mappedType.getObjectType(); + if (mappedType.isAddress()) { + mappedType = mappedType.getObjectType(); + } auto AllocStackLoc = RegularLocation::getAutoGeneratedLocation(); ASI = getBuilder().createAllocStack(AllocStackLoc, mappedType); AllocStacks.push_back(ASI); @@ -106,24 +107,36 @@ void GenericCloner::populateCloned() { // Handle arguments for formal parameters. unsigned paramIdx = ArgIdx - origConv.getSILArgIndexOfFirstParam(); if (ReInfo.isParamConverted(paramIdx)) { - // Store the new direct parameter to the alloc_stack. - createAllocStack(); + assert(mappedType.isAddress()); + mappedType = mappedType.getObjectType(); auto *NewArg = ClonedEntryBB->createFunctionArgument( mappedType, OrigArg->getDecl()); - getBuilder().createStore(Loc, NewArg, ASI, - StoreOwnershipQualifier::Unqualified); - // Try to create a new debug_value from an existing debug_value_addr. + // Try to create a new debug_value from an existing debug_value_addr + // for the argument. We do this before storing to ensure that when we + // are cloning code in ossa the argument has not been consumed by the + // store below. for (Operand *ArgUse : OrigArg->getUses()) { if (auto *DVAI = dyn_cast(ArgUse->getUser())) { + auto *oldScope = getBuilder().getCurrentDebugScope(); getBuilder().setCurrentDebugScope( remapScope(DVAI->getDebugScope())); getBuilder().createDebugValue(DVAI->getLoc(), NewArg, *DVAI->getVarInfo()); - getBuilder().setCurrentDebugScope(nullptr); + getBuilder().setCurrentDebugScope(oldScope); break; } } + + // Store the new direct parameter to an alloc_stack. + createAllocStack(); + if (!NewArg->getArgumentConvention().isGuaranteedConvention()) { + getBuilder().emitStoreValueOperation(Loc, NewArg, ASI, + StoreOwnershipQualifier::Init); + } else { + getBuilder().emitStoreBorrowOperation(Loc, NewArg, ASI); + } + entryArgs.push_back(ASI); return true; } @@ -150,9 +163,9 @@ void GenericCloner::visitTerminator(SILBasicBlock *BB) { if (ReturnValueAddr) { // The result is converted from indirect to direct. We have to load the // returned value from the alloc_stack. - ReturnValue = - getBuilder().createLoad(ReturnValueAddr->getLoc(), ReturnValueAddr, - LoadOwnershipQualifier::Unqualified); + ReturnValue = getBuilder().emitLoadValueOperation( + ReturnValueAddr->getLoc(), ReturnValueAddr, + LoadOwnershipQualifier::Take); } for (AllocStackInst *ASI : reverse(AllocStacks)) { getBuilder().createDeallocStack(ASI->getLoc(), ASI); diff --git a/lib/SILOptimizer/Utils/Generics.cpp b/lib/SILOptimizer/Utils/Generics.cpp index fab8829dc56c0..1cfe889d04301 100644 --- a/lib/SILOptimizer/Utils/Generics.cpp +++ b/lib/SILOptimizer/Utils/Generics.cpp @@ -1870,7 +1870,6 @@ SILFunction *GenericFuncSpecializer::tryCreateSpecialization() { SpecializedF->getGenericEnvironment()) || (!SpecializedF->getLoweredFunctionType()->isPolymorphic() && !SpecializedF->getGenericEnvironment())); - assert(!SpecializedF->hasOwnership()); // Store the meta-information about how this specialization was created. auto *Caller = ReInfo.getApply() ? ReInfo.getApply().getFunction() : nullptr; SubstitutionMap Subs = Caller ? ReInfo.getApply().getSubstitutionMap() @@ -1907,10 +1906,18 @@ static void fixUsedVoidType(SILValue VoidVal, SILLocation Loc, } /// Prepare call arguments. Perform re-abstraction if required. -static void prepareCallArguments(ApplySite AI, SILBuilder &Builder, - const ReabstractionInfo &ReInfo, - SmallVectorImpl &Arguments, - SILValue &StoreResultTo) { +/// +/// \p ArgAtIndexNeedsEndBorrow after return contains indices of arguments that +/// need end borrow. The reason why we are doing this in a separate array is +/// that we are going to eventually need to pass off Arguments to SILBuilder +/// which will want an ArrayRef() so using a composite type here would +/// force us to do some sort of conversion then. +static void +prepareCallArguments(ApplySite AI, SILBuilder &Builder, + const ReabstractionInfo &ReInfo, + SmallVectorImpl &Arguments, + SmallVectorImpl &ArgAtIndexNeedsEndBorrow, + SILValue &StoreResultTo) { /// SIL function conventions for the original apply site with substitutions. SILLocation Loc = AI.getLoc(); auto substConv = AI.getSubstCalleeConv(); @@ -1938,8 +1945,16 @@ static void prepareCallArguments(ApplySite AI, SILBuilder &Builder, if (ReInfo.isParamConverted(paramIdx)) { // An argument is converted from indirect to direct. Instead of the // address we pass the loaded value. - SILValue Val = Builder.createLoad( - Loc, Op.get(), LoadOwnershipQualifier::Unqualified); + auto argConv = substConv.getSILArgumentConvention(ArgIdx); + SILValue Val; + if (!argConv.isGuaranteedConvention() || isa(AI)) { + Val = Builder.emitLoadValueOperation(Loc, Op.get(), + LoadOwnershipQualifier::Take); + } else { + Val = Builder.emitLoadBorrowOperation(Loc, Op.get()); + if (Val.getOwnershipKind() == ValueOwnershipKind::Guaranteed) + ArgAtIndexNeedsEndBorrow.push_back(Arguments.size()); + } Arguments.push_back(Val); return true; } @@ -1953,6 +1968,16 @@ static void prepareCallArguments(ApplySite AI, SILBuilder &Builder, } } +static void +cleanupCallArguments(SILBuilder &builder, SILLocation loc, + ArrayRef values, + ArrayRef valueIndicesThatNeedEndBorrow) { + for (int index : valueIndicesThatNeedEndBorrow) { + auto *lbi = cast(values[index]); + builder.createEndBorrow(loc, lbi); + } +} + /// Create a new apply based on an old one, but with a different /// function being applied. static ApplySite replaceWithSpecializedCallee(ApplySite applySite, @@ -1961,14 +1986,20 @@ static ApplySite replaceWithSpecializedCallee(ApplySite applySite, SILBuilderWithScope builder(applySite.getInstruction()); SILLocation loc = applySite.getLoc(); SmallVector arguments; + SmallVector argsNeedingEndBorrow; SILValue resultOut; - prepareCallArguments(applySite, builder, reInfo, arguments, resultOut); + prepareCallArguments(applySite, builder, reInfo, arguments, + argsNeedingEndBorrow, resultOut); // Create a substituted callee type. + // + // NOTE: We do not perform this substitution if we are promoting a full apply + // site callee of a partial apply. auto canFnTy = callee->getType().castTo(); SubstitutionMap subs; - if (reInfo.getSpecializedType()->isPolymorphic()) { + if (reInfo.getSpecializedType()->isPolymorphic() && + canFnTy->isPolymorphic()) { subs = reInfo.getCallerParamSubstitutionMap(); subs = SubstitutionMap::get(canFnTy->getSubstGenericSignature(), subs); } @@ -1983,6 +2014,13 @@ static ApplySite replaceWithSpecializedCallee(ApplySite applySite, auto *tai = cast(applySite); SILBasicBlock *resultBlock = tai->getNormalBB(); assert(resultBlock->getSinglePredecessorBlock() == tai->getParent()); + // First insert the cleanups for our arguments int he appropriate spot. + FullApplySite(tai).insertAfterFullEvaluation( + [&](SILBasicBlock::iterator insertPt) { + SILBuilderWithScope argBuilder(insertPt); + cleanupCallArguments(argBuilder, loc, arguments, + argsNeedingEndBorrow); + }); auto *newTAI = builder.createTryApply(loc, callee, subs, arguments, resultBlock, tai->getErrorBB()); if (resultOut) { @@ -1995,23 +2033,28 @@ static ApplySite replaceWithSpecializedCallee(ApplySite applySite, SILArgument *arg = resultBlock->replacePhiArgument( 0, resultOut->getType().getObjectType(), ValueOwnershipKind::Owned); // Store the direct result to the original result address. - builder.createStore(loc, arg, resultOut, - StoreOwnershipQualifier::Unqualified); + builder.emitStoreValueOperation(loc, arg, resultOut, + StoreOwnershipQualifier::Init); } return newTAI; } case ApplySiteKind::ApplyInst: { auto *ai = cast(applySite); + FullApplySite(ai).insertAfterFullEvaluation( + [&](SILBasicBlock::iterator insertPt) { + SILBuilderWithScope argBuilder(insertPt); + cleanupCallArguments(argBuilder, loc, arguments, + argsNeedingEndBorrow); + }); auto *newAI = builder.createApply(loc, callee, subs, arguments, ai->isNonThrowing()); if (resultOut) { - assert(substConv.useLoweredAddresses()); if (!calleeSILSubstFnTy.isNoReturnFunction( builder.getModule(), builder.getTypeExpansionContext())) { // Store the direct result to the original result address. fixUsedVoidType(ai, loc, builder); - builder.createStore(loc, newAI, resultOut, - StoreOwnershipQualifier::Unqualified); + builder.emitStoreValueOperation(loc, newAI, resultOut, + StoreOwnershipQualifier::Init); } else { builder.createUnreachable(loc); // unreachable should be the terminator instruction. @@ -2027,6 +2070,12 @@ static ApplySite replaceWithSpecializedCallee(ApplySite applySite, case ApplySiteKind::BeginApplyInst: { auto *bai = cast(applySite); assert(!resultOut); + FullApplySite(bai).insertAfterFullEvaluation( + [&](SILBasicBlock::iterator insertPt) { + SILBuilderWithScope argBuilder(insertPt); + cleanupCallArguments(argBuilder, loc, arguments, + argsNeedingEndBorrow); + }); auto *newBAI = builder.createBeginApply(loc, callee, subs, arguments, bai->isNonThrowing()); bai->replaceAllUsesPairwiseWith(newBAI); @@ -2038,7 +2087,11 @@ static ApplySite replaceWithSpecializedCallee(ApplySite applySite, loc, callee, subs, arguments, pai->getType().getAs()->getCalleeConvention(), pai->isOnStack()); + // When we have a partial apply, we should always perform a load [take]. pai->replaceAllUsesWith(newPAI); + assert(llvm::none_of(arguments, + [](SILValue v) { return isa(v); }) && + "Partial apply consumes all of its parameters?!"); return newPAI; } } @@ -2096,8 +2149,9 @@ class ReabstractionThunkGenerator { SILFunction *createThunk(); protected: - SILValue createReabstractionThunkApply(SILBuilder &Builder); - SILArgument *convertReabstractionThunkArguments(SILBuilder &Builder); + FullApplySite createReabstractionThunkApply(SILBuilder &Builder); + SILArgument *convertReabstractionThunkArguments( + SILBuilder &Builder, SmallVectorImpl &ArgsNeedingEndBorrows); }; } // anonymous namespace @@ -2132,30 +2186,46 @@ SILFunction *ReabstractionThunkGenerator::createThunk() { SpecArg->getDecl()); Arguments.push_back(NewArg); } - SILValue ReturnValue = createReabstractionThunkApply(Builder); + FullApplySite ApplySite = createReabstractionThunkApply(Builder); + SILValue ReturnValue = ApplySite.getSingleDirectResult(); + assert(ReturnValue && "getSingleDirectResult out of sync with ApplySite?!"); Builder.createReturn(Loc, ReturnValue); + return Thunk; } // Handle lowered addresses. - SILArgument *ReturnValueAddr = convertReabstractionThunkArguments(Builder); + SmallVector ArgsThatNeedEndBorrow; + SILArgument *ReturnValueAddr = + convertReabstractionThunkArguments(Builder, ArgsThatNeedEndBorrow); + + FullApplySite ApplySite = createReabstractionThunkApply(Builder); - SILValue ReturnValue = createReabstractionThunkApply(Builder); + SILValue ReturnValue = ApplySite.getSingleDirectResult(); + assert(ReturnValue && "getSingleDirectResult out of sync with ApplySite?!"); if (ReturnValueAddr) { // Need to store the direct results to the original indirect address. - Builder.createStore(Loc, ReturnValue, ReturnValueAddr, - StoreOwnershipQualifier::Unqualified); + Builder.emitStoreValueOperation(Loc, ReturnValue, ReturnValueAddr, + StoreOwnershipQualifier::Init); SILType VoidTy = OrigPAI->getSubstCalleeType()->getDirectFormalResultsType( M, Builder.getTypeExpansionContext()); assert(VoidTy.isVoid()); ReturnValue = Builder.createTuple(Loc, VoidTy, {}); } Builder.createReturn(Loc, ReturnValue); + + // Now that we have finished constructing our CFG (note the return above), + // insert any compensating end borrows that we need. + ApplySite.insertAfterFullEvaluation([&](SILBasicBlock::iterator insertPt) { + SILBuilderWithScope argBuilder(insertPt); + cleanupCallArguments(argBuilder, Loc, Arguments, ArgsThatNeedEndBorrow); + }); + return Thunk; } /// Create a call to a reabstraction thunk. Return the call's direct result. -SILValue ReabstractionThunkGenerator::createReabstractionThunkApply( +FullApplySite ReabstractionThunkGenerator::createReabstractionThunkApply( SILBuilder &Builder) { SILFunction *Thunk = &Builder.getFunction(); auto *FRI = Builder.createFunctionRef(Loc, SpecializedFunc); @@ -2167,19 +2237,20 @@ SILValue ReabstractionThunkGenerator::createReabstractionThunkApply( // Create the logic for calling a throwing function. SILBasicBlock *NormalBB = Thunk->createBasicBlock(); SILBasicBlock *ErrorBB = Thunk->createBasicBlock(); - Builder.createTryApply(Loc, FRI, Subs, Arguments, NormalBB, ErrorBB); + auto *TAI = + Builder.createTryApply(Loc, FRI, Subs, Arguments, NormalBB, ErrorBB); auto *ErrorVal = ErrorBB->createPhiArgument( SpecializedFunc->mapTypeIntoContext( specConv.getSILErrorType(Builder.getTypeExpansionContext())), ValueOwnershipKind::Owned); Builder.setInsertionPoint(ErrorBB); Builder.createThrow(Loc, ErrorVal); - SILValue ReturnValue = NormalBB->createPhiArgument( + NormalBB->createPhiArgument( SpecializedFunc->mapTypeIntoContext( specConv.getSILResultType(Builder.getTypeExpansionContext())), ValueOwnershipKind::Owned); Builder.setInsertionPoint(NormalBB); - return ReturnValue; + return FullApplySite(TAI); } /// Create SIL arguments for a reabstraction thunk with lowered addresses. This @@ -2189,7 +2260,7 @@ SILValue ReabstractionThunkGenerator::createReabstractionThunkApply( /// FIXME: Remove this if we don't need to create reabstraction thunks after /// address lowering. SILArgument *ReabstractionThunkGenerator::convertReabstractionThunkArguments( - SILBuilder &Builder) { + SILBuilder &Builder, SmallVectorImpl &ArgsThatNeedEndBorrow) { SILFunction *Thunk = &Builder.getFunction(); CanSILFunctionType SpecType = SpecializedFunc->getLoweredFunctionType(); CanSILFunctionType SubstType = ReInfo.getSubstitutedType(); @@ -2251,11 +2322,18 @@ SILArgument *ReabstractionThunkGenerator::convertReabstractionThunkArguments( Builder.getTypeExpansionContext())); assert(ParamTy.isAddress()); SILArgument *SpecArg = *SpecArgIter++; - SILArgument *NewArg = + SILFunctionArgument *NewArg = EntryBB->createFunctionArgument(ParamTy, SpecArg->getDecl()); - auto *ArgVal = - Builder.createLoad(Loc, NewArg, LoadOwnershipQualifier::Unqualified); - Arguments.push_back(ArgVal); + if (!NewArg->getArgumentConvention().isGuaranteedConvention()) { + SILValue argVal = Builder.emitLoadValueOperation( + Loc, NewArg, LoadOwnershipQualifier::Take); + Arguments.push_back(argVal); + } else { + SILValue argVal = Builder.emitLoadBorrowOperation(Loc, NewArg); + if (argVal.getOwnershipKind() == ValueOwnershipKind::Guaranteed) + ArgsThatNeedEndBorrow.push_back(Arguments.size()); + Arguments.push_back(argVal); + } continue; } // Simply clone unconverted direct or indirect parameters. @@ -2358,15 +2436,6 @@ void swift::trySpecializeApplyOfGeneric( if (shouldNotSpecialize(RefF, F)) return; - // If our callee has ownership, do not specialize for now. This should only - // occur with transparent referenced functions. - // - // FIXME: Support this. - if (RefF->hasOwnership()) { - assert(RefF->isTransparent()); - return; - } - // If the caller and callee are both fragile, preserve the fragility when // cloning the callee. Otherwise, strip it off so that we can optimize // the body more. @@ -2408,11 +2477,24 @@ void swift::trySpecializeApplyOfGeneric( // this case we can just skip the existing re-abstraction. // 3) For all other cases we need to create a new re-abstraction thunk. needAdaptUsers = true; - for (Operand *Use : PAI->getUses()) { + SmallVector worklist(PAI->getUses()); + while (!worklist.empty()) { + auto *Use = worklist.pop_back_val(); + SILInstruction *User = Use->getUser(); + + // Look through copy_value. + if (auto *cvi = dyn_cast(User)) { + llvm::copy(cvi->getUses(), std::back_inserter(worklist)); + continue; + } + // Ignore destroy_value. + if (isa(User)) + continue; + // Ignore older ref count instructions. if (isa(User)) continue; - if (User->isDebugInstruction()) + if (isIncidentalUse(User)) continue; auto FAS = FullApplySite::isa(User); @@ -2443,7 +2525,6 @@ void swift::trySpecializeApplyOfGeneric( << SpecializedF->getName() << "\n" << "Specialized function type: " << SpecializedF->getLoweredFunctionType() << "\n"); - assert(!SpecializedF->hasOwnership()); NewFunctions.push_back(SpecializedF); } diff --git a/lib/Sema/DerivedConformanceDifferentiable.cpp b/lib/Sema/DerivedConformanceDifferentiable.cpp index 713b7ca8129b8..afa901b6185d5 100644 --- a/lib/Sema/DerivedConformanceDifferentiable.cpp +++ b/lib/Sema/DerivedConformanceDifferentiable.cpp @@ -668,7 +668,7 @@ getOrSynthesizeTangentVectorStruct(DerivedConformance &derived, Identifier id) { tangentProperty->setSetterAccess(member->getFormalAccess()); // Cache the tangent property. - C.evaluator.cacheOutput(TangentStoredPropertyRequest{member}, + C.evaluator.cacheOutput(TangentStoredPropertyRequest{member, CanType()}, TangentPropertyInfo(tangentProperty)); // Now that the original property has a corresponding tangent property, it diff --git a/lib/Sema/DerivedConformanceRawRepresentable.cpp b/lib/Sema/DerivedConformanceRawRepresentable.cpp index 2c03f3f5660c2..b8ecb3e61c3fa 100644 --- a/lib/Sema/DerivedConformanceRawRepresentable.cpp +++ b/lib/Sema/DerivedConformanceRawRepresentable.cpp @@ -198,7 +198,7 @@ struct RuntimeVersionCheck { // platformSpec = "\(attr.platform) \(attr.introduced)" auto platformSpec = new (C) PlatformVersionConstraintAvailabilitySpec( Platform, SourceLoc(), - Version, SourceLoc() + Version, Version, SourceLoc() ); // otherSpec = "*" diff --git a/lib/Sema/TypeCheckAttr.cpp b/lib/Sema/TypeCheckAttr.cpp index e2f05cfb4f7b4..8883713e5aa3f 100644 --- a/lib/Sema/TypeCheckAttr.cpp +++ b/lib/Sema/TypeCheckAttr.cpp @@ -4240,6 +4240,15 @@ IndexSubset *DifferentiableAttributeTypeCheckRequest::evaluate( auto *originalFnTy = original->getInterfaceType()->castTo(); + // Diagnose if original function has opaque result types. + if (auto *opaqueResultTypeDecl = original->getOpaqueResultTypeDecl()) { + diags.diagnose( + attr->getLocation(), + diag::autodiff_attr_opaque_result_type_unsupported); + attr->setInvalid(); + return nullptr; + } + // Diagnose if original function is an invalid class member. bool isOriginalClassMember = original->getDeclContext() && original->getDeclContext()->getSelfClassDecl(); @@ -4532,6 +4541,16 @@ static bool typeCheckDerivativeAttr(ASTContext &Ctx, Decl *D, return true; } } + + // Diagnose if original function has opaque result types. + if (auto *opaqueResultTypeDecl = originalAFD->getOpaqueResultTypeDecl()) { + diags.diagnose( + attr->getLocation(), + diag::autodiff_attr_opaque_result_type_unsupported); + attr->setInvalid(); + return true; + } + // Diagnose if original function is an invalid class member. bool isOriginalClassMember = originalAFD->getDeclContext() && @@ -5083,9 +5102,15 @@ void AttributeChecker::visitTransposeAttr(TransposeAttr *attr) { attr->setInvalid(); return; } - attr->setOriginalFunction(originalAFD); + // Diagnose if original function has opaque result types. + if (auto *opaqueResultTypeDecl = originalAFD->getOpaqueResultTypeDecl()) { + diagnose(attr->getLocation(), diag::autodiff_attr_opaque_result_type_unsupported); + attr->setInvalid(); + return; + } + // Get the linearity parameter types. SmallVector linearParams; expectedOriginalFnType->getSubsetParameters(linearParamIndices, linearParams, diff --git a/lib/Sema/TypeCheckAvailability.cpp b/lib/Sema/TypeCheckAvailability.cpp index be05a54427f8a..a62d73c95ff83 100644 --- a/lib/Sema/TypeCheckAvailability.cpp +++ b/lib/Sema/TypeCheckAvailability.cpp @@ -453,8 +453,8 @@ class TypeRefinementContextBuilder : private ASTWalker { continue; } - AvailabilityContext NewConstraint = contextForSpec(Spec); - Query->setAvailableRange(NewConstraint.getOSVersion()); + AvailabilityContext NewConstraint = contextForSpec(Spec, false); + Query->setAvailableRange(contextForSpec(Spec, true).getOSVersion()); // When compiling zippered for macCatalyst, we need to collect both // a macOS version (the target version) and an iOS/macCatalyst version @@ -464,7 +464,8 @@ class TypeRefinementContextBuilder : private ASTWalker { if (Context.LangOpts.TargetVariant) { AvailabilitySpec *VariantSpec = bestActiveSpecForQuery(Query, /*ForTargetVariant*/ true); - VersionRange VariantRange = contextForSpec(VariantSpec).getOSVersion(); + VersionRange VariantRange = + contextForSpec(VariantSpec, true).getOSVersion(); Query->setVariantAvailableRange(VariantRange); } @@ -594,13 +595,19 @@ class TypeRefinementContextBuilder : private ASTWalker { } /// Return the availability context for the given spec. - AvailabilityContext contextForSpec(AvailabilitySpec *Spec) { + AvailabilityContext contextForSpec(AvailabilitySpec *Spec, + bool GetRuntimeContext) { if (isa(Spec)) { return AvailabilityContext::alwaysAvailable(); } auto *VersionSpec = cast(Spec); - return AvailabilityContext(VersionRange::allGTE(VersionSpec->getVersion())); + + llvm::VersionTuple Version = (GetRuntimeContext ? + VersionSpec->getRuntimeVersion() : + VersionSpec->getVersion()); + + return AvailabilityContext(VersionRange::allGTE(Version)); } Expr *walkToExprPost(Expr *E) override { diff --git a/lib/TBDGen/TBDGen.cpp b/lib/TBDGen/TBDGen.cpp index a8685bcc06324..5d5a63d06d614 100644 --- a/lib/TBDGen/TBDGen.cpp +++ b/lib/TBDGen/TBDGen.cpp @@ -70,7 +70,12 @@ void TBDGenVisitor::addSymbolInternal(StringRef name, if (StringSymbols && kind == SymbolKind::GlobalSymbol) { auto isNewValue = StringSymbols->insert(name).second; (void)isNewValue; - assert(isNewValue && "symbol appears twice"); +#ifndef NDEBUG + if (!isNewValue) { + llvm::dbgs() << "TBDGen duplicate symbol: " << name << '\n'; + assert(false && "TBDGen symbol appears twice"); + } +#endif } } diff --git a/stdlib/public/Darwin/ObjectiveC/ObjectiveC.swift b/stdlib/public/Darwin/ObjectiveC/ObjectiveC.swift index e127f4366329e..0204b2cee461d 100644 --- a/stdlib/public/Darwin/ObjectiveC/ObjectiveC.swift +++ b/stdlib/public/Darwin/ObjectiveC/ObjectiveC.swift @@ -25,8 +25,8 @@ import ObjectiveC /// ObjCBool. @frozen public struct ObjCBool : ExpressibleByBooleanLiteral { -#if os(macOS) || (os(iOS) && (arch(i386) || arch(arm))) - // On OS X and 32-bit iOS, Objective-C's BOOL type is a "signed char". +#if (os(macOS) && arch(x86_64)) || (os(iOS) && (arch(i386) || arch(arm))) + // On Intel OS X and 32-bit iOS, Objective-C's BOOL type is a "signed char". @usableFromInline var _value: Int8 @_transparent @@ -52,7 +52,7 @@ public struct ObjCBool : ExpressibleByBooleanLiteral { /// The value of `self`, expressed as a `Bool`. @_transparent public var boolValue: Bool { -#if os(macOS) || (os(iOS) && (arch(i386) || arch(arm))) +#if (os(macOS) && arch(x86_64)) || (os(iOS) && (arch(i386) || arch(arm))) return _value != 0 #else return _value diff --git a/stdlib/public/SwiftRemoteMirror/SwiftRemoteMirror.cpp b/stdlib/public/SwiftRemoteMirror/SwiftRemoteMirror.cpp index 8c231ba22f053..7c7cbfa24622d 100644 --- a/stdlib/public/SwiftRemoteMirror/SwiftRemoteMirror.cpp +++ b/stdlib/public/SwiftRemoteMirror/SwiftRemoteMirror.cpp @@ -71,7 +71,7 @@ static int minimalDataLayoutQueryFunction(void *ReaderContext, #else auto applePlatform = false; #endif -#if defined(__APPLE__) && __APPLE__ && ((defined(TARGET_OS_IOS) && TARGET_OS_IOS) || (defined(TARGET_OS_IOS) && TARGET_OS_WATCH) || (defined(TARGET_OS_TV) && TARGET_OS_TV)) +#if defined(__APPLE__) && __APPLE__ && ((defined(TARGET_OS_IOS) && TARGET_OS_IOS) || (defined(TARGET_OS_IOS) && TARGET_OS_WATCH) || (defined(TARGET_OS_TV) && TARGET_OS_TV) || defined(__arm64__)) auto iosDerivedPlatform = true; #else auto iosDerivedPlatform = false; diff --git a/stdlib/public/runtime/Private.h b/stdlib/public/runtime/Private.h index 8a1bfaece97a2..d337409524f37 100644 --- a/stdlib/public/runtime/Private.h +++ b/stdlib/public/runtime/Private.h @@ -96,14 +96,22 @@ class TypeInfo { // out the proper includes from libobjc. The values MUST match the ones from // libobjc. Debug builds check these values against objc_debug_isa_class_mask // from libobjc. -# if TARGET_OS_SIMULATOR -// Simulators don't currently use isa masking, but we still want to emit +# if TARGET_OS_SIMULATOR && __x86_64__ +// Simulators don't currently use isa masking on x86, but we still want to emit // swift_isaMask and the corresponding code in case that changes. libobjc's // mask has the bottom bits clear to include pointer alignment, match that // value here. # define SWIFT_ISA_MASK 0xfffffffffffffff8ULL # elif __arm64__ -# define SWIFT_ISA_MASK 0x0000000ffffffff8ULL +# if __has_feature(ptrauth_calls) +# define SWIFT_ISA_MASK 0x007ffffffffffff8ULL +# else +# if TARGET_OS_OSX +# define SWIFT_ISA_MASK 0x00007ffffffffff8ULL +# else +# define SWIFT_ISA_MASK 0x0000000ffffffff8ULL +# endif +# endif # elif __x86_64__ # define SWIFT_ISA_MASK 0x00007ffffffffff8ULL # else diff --git a/stdlib/tools/swift-reflection-test/swift-reflection-test.c b/stdlib/tools/swift-reflection-test/swift-reflection-test.c index a80fae766152c..3b76e5d65f2f2 100644 --- a/stdlib/tools/swift-reflection-test/swift-reflection-test.c +++ b/stdlib/tools/swift-reflection-test/swift-reflection-test.c @@ -147,7 +147,7 @@ static int PipeMemoryReader_queryDataLayout(void *Context, #else int applePlatform = 0; #endif -#if defined(__APPLE__) && __APPLE__ && ((defined(TARGET_OS_IOS) && TARGET_OS_IOS) || (defined(TARGET_OS_IOS) && TARGET_OS_WATCH) || (defined(TARGET_OS_TV) && TARGET_OS_TV)) +#if defined(__APPLE__) && __APPLE__ && ((defined(TARGET_OS_IOS) && TARGET_OS_IOS) || (defined(TARGET_OS_IOS) && TARGET_OS_WATCH) || (defined(TARGET_OS_TV) && TARGET_OS_TV) || defined(__arm64__)) int iosDerivedPlatform = 1; #else int iosDerivedPlatform = 0; diff --git a/test/AutoDiff/SILOptimizer/differentiation_diagnostics.swift b/test/AutoDiff/SILOptimizer/differentiation_diagnostics.swift index 2398f39ad1d5f..13c23dcc656da 100644 --- a/test/AutoDiff/SILOptimizer/differentiation_diagnostics.swift +++ b/test/AutoDiff/SILOptimizer/differentiation_diagnostics.swift @@ -624,6 +624,22 @@ func testClassTangentPropertyNotStored(_ c: ClassTangentPropertyNotStored) -> Fl // CHECK-LABEL: sil {{.*}} @test_class_tangent_property_not_stored // CHECK: ref_element_addr {{%.*}} : $ClassTangentPropertyNotStored, #ClassTangentPropertyNotStored.x +// SR-13134: Test stored property access with conditionally `Differentiable` base type. + +struct Complex { + var real: T + var imaginary: T +} +extension Complex: Differentiable where T: Differentiable { + typealias TangentVector = Complex +} +extension Complex: AdditiveArithmetic {} + +@differentiable +func SR_13134(lhs: Complex, rhs: Complex) -> Float { + return lhs.real + rhs.real +} + //===----------------------------------------------------------------------===// // Wrapped property differentiation //===----------------------------------------------------------------------===// diff --git a/test/AutoDiff/Sema/derivative_attr_type_checking.swift b/test/AutoDiff/Sema/derivative_attr_type_checking.swift index 1de073a5d35fa..0b17860a1b51a 100644 --- a/test/AutoDiff/Sema/derivative_attr_type_checking.swift +++ b/test/AutoDiff/Sema/derivative_attr_type_checking.swift @@ -1,4 +1,4 @@ -// RUN: %target-swift-frontend-typecheck -verify %s +// RUN: %target-swift-frontend-typecheck -verify -disable-availability-checking %s import _Differentiation @@ -1124,3 +1124,13 @@ extension Float { fatalError() } } + +// Test original function with opaque result type. + +func opaqueResult(_ x: Float) -> some Differentiable { x } + +// expected-error @+1 {{could not find function 'opaqueResult' with expected type '(Float) -> Float'}} +@derivative(of: opaqueResult) +func vjpOpaqueResult(_ x: Float) -> (value: Float, pullback: (Float) -> Float) { + fatalError() +} diff --git a/test/AutoDiff/Sema/differentiable_attr_type_checking.swift b/test/AutoDiff/Sema/differentiable_attr_type_checking.swift index 55cdfee43d9c6..a090b5de6a121 100644 --- a/test/AutoDiff/Sema/differentiable_attr_type_checking.swift +++ b/test/AutoDiff/Sema/differentiable_attr_type_checking.swift @@ -1,4 +1,4 @@ -// RUN: %target-swift-frontend-typecheck -verify %s +// RUN: %target-swift-frontend-typecheck -verify -disable-availability-checking %s import _Differentiation @@ -697,3 +697,7 @@ struct Accessors: Differentiable { _modify { yield &stored } } } + +// expected-error @+1 {{cannot differentiate functions returning opaque result types}} +@differentiable +func opaqueResult(_ x: Float) -> some Differentiable { x } diff --git a/test/AutoDiff/compiler_crashers/sr12656-differentiation-opaque-result-type.swift b/test/AutoDiff/compiler_crashers_fixed/sr12656-differentiation-opaque-result-type.swift similarity index 94% rename from test/AutoDiff/compiler_crashers/sr12656-differentiation-opaque-result-type.swift rename to test/AutoDiff/compiler_crashers_fixed/sr12656-differentiation-opaque-result-type.swift index 703786fcd8031..ed48abb31be0f 100644 --- a/test/AutoDiff/compiler_crashers/sr12656-differentiation-opaque-result-type.swift +++ b/test/AutoDiff/compiler_crashers_fixed/sr12656-differentiation-opaque-result-type.swift @@ -1,4 +1,4 @@ -// RUN: not --crash %target-swift-frontend -disable-availability-checking -emit-sil -verify %s +// RUN: not %target-swift-frontend -disable-availability-checking -emit-sil -verify %s // REQUIRES: asserts // SR-12656: Differentiation transform crashes for original function with opaque diff --git a/test/ClangImporter/CoreGraphics_test.swift b/test/ClangImporter/CoreGraphics_test.swift index 017265f52a220..ef16031857079 100644 --- a/test/ClangImporter/CoreGraphics_test.swift +++ b/test/ClangImporter/CoreGraphics_test.swift @@ -4,6 +4,7 @@ import CoreGraphics // REQUIRES: OS=macosx +// REQUIRES: CPU=x86_64 // CHECK: [[SWITCHTABLE:@.*]] = private unnamed_addr constant [8 x i64] [i64 0, i64 12, i64 23, i64 34, i64 45, i64 55, i64 67, i64 71] diff --git a/test/ClangImporter/Inputs/custom-modules/MacOSVersionCanonicalization.h b/test/ClangImporter/Inputs/custom-modules/MacOSVersionCanonicalization.h new file mode 100644 index 0000000000000..b0b02c20e999b --- /dev/null +++ b/test/ClangImporter/Inputs/custom-modules/MacOSVersionCanonicalization.h @@ -0,0 +1,11 @@ +__attribute__((availability(macosx,introduced=10.16))) +void FunctionIntroducedIn10_16(); + +__attribute__((availability(macosx,introduced=11.0))) +void FunctionIntroducedIn11_0(); + +__attribute__((availability(macosx_app_extension,introduced=10.16))) +void FunctionIntroducedIn10_16AppExt(); + +__attribute__((availability(macosx_app_extension,introduced=11.0))) +void FunctionIntroducedIn11_0AppExt(); diff --git a/test/ClangImporter/Inputs/custom-modules/module.map b/test/ClangImporter/Inputs/custom-modules/module.map index 6c4612efb44c0..b66f030963f97 100644 --- a/test/ClangImporter/Inputs/custom-modules/module.map +++ b/test/ClangImporter/Inputs/custom-modules/module.map @@ -221,6 +221,10 @@ module BlocksReturningBool { header "BlocksReturningBool.h" } +module MacOSVersionCanonicalization { + header "MacOSVersionCanonicalization.h" +} + module Warnings1 { header "Warnings1.h" } module Warnings2 { header "Warnings2.h" } module Warnings3 { header "Warnings3.h" } diff --git a/test/ClangImporter/availability_implicit_macosx.swift b/test/ClangImporter/availability_implicit_macosx.swift index 71713bf1fff27..158a321fd06d5 100644 --- a/test/ClangImporter/availability_implicit_macosx.swift +++ b/test/ClangImporter/availability_implicit_macosx.swift @@ -1,5 +1,5 @@ -// RUN: %swift -typecheck -verify -target x86_64-apple-macosx10.51 %clang-importer-sdk -I %S/Inputs/custom-modules %s %S/Inputs/availability_implicit_macosx_other.swift -// RUN: not %swift -typecheck -target x86_64-apple-macosx10.51 %clang-importer-sdk -I %S/Inputs/custom-modules %s %S/Inputs/availability_implicit_macosx_other.swift 2>&1 | %FileCheck %s '--implicit-check-not=:0' +// RUN: %swift -typecheck -verify -target %target-cpu-apple-macosx10.51 %clang-importer-sdk -I %S/Inputs/custom-modules %s %S/Inputs/availability_implicit_macosx_other.swift +// RUN: not %swift -typecheck -target %target-cpu-apple-macosx10.51 %clang-importer-sdk -I %S/Inputs/custom-modules %s %S/Inputs/availability_implicit_macosx_other.swift 2>&1 | %FileCheck %s '--implicit-check-not=:0' // REQUIRES: OS=macosx diff --git a/test/ClangImporter/availability_macosx_canonical_versions.swift b/test/ClangImporter/availability_macosx_canonical_versions.swift new file mode 100644 index 0000000000000..29e6dd40dbd4b --- /dev/null +++ b/test/ClangImporter/availability_macosx_canonical_versions.swift @@ -0,0 +1,13 @@ +// RUN: %target-swift-frontend(mock-sdk: %clang-importer-sdk) -typecheck -verify -I %S/Inputs/custom-modules -target x86_64-apple-macosx10.15 %s + +// REQUIRES: OS=macosx + +import MacOSVersionCanonicalization + +FunctionIntroducedIn10_16() +// expected-error@-1 {{'FunctionIntroducedIn10_16()' is only available in macOS 11.0 or newer}} +// expected-note@-2 {{add 'if #available' version check}} + +FunctionIntroducedIn11_0() +// expected-error@-1 {{'FunctionIntroducedIn11_0()' is only available in macOS 11.0 or newer}} +// expected-note@-2 {{add 'if #available' version check}} diff --git a/test/ClangImporter/availability_macosx_canonical_versions_appext.swift b/test/ClangImporter/availability_macosx_canonical_versions_appext.swift new file mode 100644 index 0000000000000..b6357e8a553a5 --- /dev/null +++ b/test/ClangImporter/availability_macosx_canonical_versions_appext.swift @@ -0,0 +1,13 @@ +// RUN: %target-swift-frontend(mock-sdk: %clang-importer-sdk) -typecheck -verify -I %S/Inputs/custom-modules -target x86_64-apple-macosx10.15 -application-extension %s + +// REQUIRES: OS=macosx + +import MacOSVersionCanonicalization + +FunctionIntroducedIn10_16AppExt() +// expected-error@-1 {{'FunctionIntroducedIn10_16AppExt()' is only available in application extensions for macOS 11.0 or newer}} +// expected-note@-2 {{add 'if #available' version check}} + +FunctionIntroducedIn11_0AppExt() +// expected-error@-1 {{'FunctionIntroducedIn11_0AppExt()' is only available in application extensions for macOS 11.0 or newer}} +// expected-note@-2 {{add 'if #available' version check}} diff --git a/test/ClangImporter/bad-deployment-target.swift b/test/ClangImporter/bad-deployment-target.swift index 47d0bfa934d34..3e60703a55a5c 100644 --- a/test/ClangImporter/bad-deployment-target.swift +++ b/test/ClangImporter/bad-deployment-target.swift @@ -1,4 +1,4 @@ -// RUN: %target-swift-frontend(mock-sdk: %clang-importer-sdk) -typecheck -target x86_64-apple-macosx10.8 %s +// RUN: %target-swift-frontend(mock-sdk: %clang-importer-sdk) -typecheck -target %target-cpu-apple-macosx10.8 %s // // This test ensures that a -target that is too old for the standard library // will not crash in the ClangImporter. diff --git a/test/ClangImporter/enum-with-target.swift b/test/ClangImporter/enum-with-target.swift index 334276c10ae07..35d26fef25b1e 100644 --- a/test/ClangImporter/enum-with-target.swift +++ b/test/ClangImporter/enum-with-target.swift @@ -1,5 +1,5 @@ -// RUN: %swift %clang-importer-sdk -target x86_64-apple-macosx10.51 -typecheck %s -verify -// RUN: %swift %clang-importer-sdk -target x86_64-apple-macosx10.52 -typecheck %s -verify +// RUN: %swift %clang-importer-sdk -target %target-cpu-apple-macosx10.51 -typecheck %s -verify +// RUN: %swift %clang-importer-sdk -target %target-cpu-apple-macosx10.52 -typecheck %s -verify // REQUIRES: OS=macosx import Foundation diff --git a/test/ClangImporter/objc_factory_method.swift b/test/ClangImporter/objc_factory_method.swift index cef3cae8707a2..4fcfb4d9e7d38 100644 --- a/test/ClangImporter/objc_factory_method.swift +++ b/test/ClangImporter/objc_factory_method.swift @@ -1,7 +1,7 @@ // RUN: %empty-directory(%t) // RUN: %build-clang-importer-objc-overlays -// RUN: %target-swift-frontend(mock-sdk: %clang-importer-sdk-nosource -I %t) -target x86_64-apple-macosx10.51 -typecheck %s -verify +// RUN: %target-swift-frontend(mock-sdk: %clang-importer-sdk-nosource -I %t) -target %target-cpu-apple-macosx10.51 -typecheck %s -verify // REQUIRES: OS=macosx // REQUIRES: objc_interop diff --git a/test/ClangImporter/objc_ir.swift b/test/ClangImporter/objc_ir.swift index a817410b52c29..52adc62aa6c07 100644 --- a/test/ClangImporter/objc_ir.swift +++ b/test/ClangImporter/objc_ir.swift @@ -34,7 +34,7 @@ func instanceMethods(_ b: B) { func extensionMethods(b b: B) { // CHECK: load i8*, i8** @"\01L_selector(method:separateExtMethod:)", align 8 // CHECK: [[T0:%.*]] = call i8* bitcast (void ()* @objc_msgSend to i8* - // CHECK-NEXT: [[T1:%.*]] = {{.*}}call i8* @llvm.objc.retainAutoreleasedReturnValue(i8* [[T0]]) + // CHECK: [[T1:%.*]] = {{.*}}call i8* @llvm.objc.retainAutoreleasedReturnValue(i8* [[T0]]) // CHECK-NOT: [[T0]] // CHECK: [[T1]] b.method(1, separateExtMethod:1.5) diff --git a/test/DebugInfo/ASTSection_linker.swift b/test/DebugInfo/ASTSection_linker.swift index fc6ff338dd37e..dcf3b9f94ff05 100644 --- a/test/DebugInfo/ASTSection_linker.swift +++ b/test/DebugInfo/ASTSection_linker.swift @@ -14,6 +14,7 @@ // RUN: %lldb-moduleimport-test -verbose %t/ASTSection.dylib | %FileCheck %s // REQUIRES: OS=macosx +// REQUIRES: CPU=x86_64 // CHECK: - Swift Version: {{.+}}.{{.+}} // CHECK: - Compatibility Version: 4 diff --git a/test/Driver/linker.swift b/test/Driver/linker.swift index 84ebc83b8670b..c4c8d2f4bbc59 100644 --- a/test/Driver/linker.swift +++ b/test/Driver/linker.swift @@ -106,10 +106,26 @@ // RUN: %swiftc_driver -sdk "" -driver-print-jobs -target x86_64-apple-macosx10.9 -sdk %S/Inputs/MacOSX10.15.4.versioned.sdk %s 2>&1 | %FileCheck -check-prefix MACOS_10_15_4 %s // RUN: %swiftc_driver -sdk "" -driver-print-jobs -target x86_64-apple-macosx10.9 -sdk %S/Inputs/MacOSX10.15.sdk %s 2>&1 | %FileCheck -check-prefix MACOS_UNVERSIONED %s +// Check arm64 macOS first deployment version adjustment. +// RUN: %swiftc_driver -sdk "" -driver-print-jobs -target arm64-apple-macosx10.15.1 %s 2>&1 | %FileCheck -check-prefix ARM64E_MACOS_LINKER %s + +// Check x86 macOS 11 deployment version adjustment. +// RUN: %swiftc_driver -sdk "" -driver-print-jobs -target x86_64-apple-macosx11.0 %s 2>&1 | %FileCheck -check-prefix X86_MACOS11_LINKER %s +// RUN: %swiftc_driver -sdk "" -driver-print-jobs -target arm64-apple-macosx11.0 %s 2>&1 | %FileCheck -check-prefix ARM64E_MACOS_LINKER %s + +// Check arm64 simulators first deployment version adjustment. +// RUN: %swiftc_driver -sdk "" -driver-print-jobs -target arm64-apple-ios13.0-simulator %s 2>&1 | %FileCheck -check-prefix ARM64_IOS_SIMULATOR_LINKER %s + + // MACOS_10_15: -platform_version macos 10.9.0 10.15.0 // MACOS_10_15_4: -platform_version macos 10.9.0 10.15.4 // MACOS_UNVERSIONED: -platform_version macos 10.9.0 0.0.0 +// ARM64E_MACOS_LINKER: -platform_version macos 11.0.0 +// X86_MACOS11_LINKER: -platform_version macos 10.16.0 +// X86_64_WATCHOS_SIM_LINKER: -platform_version watchos-simulator 7.0.0 +// ARM64_IOS_SIMULATOR_LINKER: -platform_version ios-simulator 14.0.0 + // There are more RUN lines further down in the file. // CHECK: swift diff --git a/test/Driver/macabi-environment.swift b/test/Driver/macabi-environment.swift index 7455ca0ce154c..358894416710e 100644 --- a/test/Driver/macabi-environment.swift +++ b/test/Driver/macabi-environment.swift @@ -34,6 +34,9 @@ // IOS12-MACABI-DAG: -rpath [[MACOSX_SDK_STDLIB_PATH]] // IOS12-MACABI-DAG: -platform_version mac-catalyst 13.0.0 0.0.0 +// RUN: %swiftc_driver -driver-print-jobs -target arm64-apple-ios12.0-macabi -sdk %S/../Inputs/clang-importer-sdk %s | %FileCheck -check-prefix=IOS14-MACABI %s +// IOS14-MACABI: -platform_version mac-catalyst 14.0.0 0.0.0 + // Test using target-variant to build zippered outputs // RUN: %swiftc_driver -sdk "" -driver-print-jobs -c -target x86_64-apple-macosx10.14 -target-variant x86_64-apple-ios13.0-macabi %s | %FileCheck -check-prefix=ZIPPERED-VARIANT-OBJECT %s diff --git a/test/Driver/options.swift b/test/Driver/options.swift index 5f1fe4649c35f..130eb959bf901 100644 --- a/test/Driver/options.swift +++ b/test/Driver/options.swift @@ -1,3 +1,5 @@ +// REQUIRES: swift_interpreter + // RUN: not %swiftc_driver -emit-silgen -parse-as-library %s -module-name "Swift" 2>&1 | %FileCheck -check-prefix=STDLIB_MODULE %s // RUN: %target-swiftc_driver -emit-silgen -parse-as-library %s -module-name "Swift" -parse-stdlib -### // STDLIB_MODULE: error: module name "Swift" is reserved for the standard library{{$}} diff --git a/test/Driver/print_target_info_macos.swift b/test/Driver/print_target_info_macos.swift index 14074424cf484..a66420b5fa595 100644 --- a/test/Driver/print_target_info_macos.swift +++ b/test/Driver/print_target_info_macos.swift @@ -7,5 +7,5 @@ // REQUIRES: OS=macosx -// CHECK: "triple": "x86_64-apple-macosx10 -// CHECK: "unversionedTriple": "x86_64-apple-macosx" +// CHECK: "triple": "{{.*}}-apple-macosx{{[0-9][0-9]}} +// CHECK: "unversionedTriple": "{{.*}}-apple-macosx" diff --git a/test/Frontend/emit-interface-macos-canonical-version.swift b/test/Frontend/emit-interface-macos-canonical-version.swift new file mode 100644 index 0000000000000..e21c9348887f2 --- /dev/null +++ b/test/Frontend/emit-interface-macos-canonical-version.swift @@ -0,0 +1,18 @@ +// RUN: %empty-directory(%t) +// RUN: %target-swift-frontend -typecheck %s -enable-library-evolution -emit-module-interface-path %t/Module.swiftinterface -experimental-skip-non-inlinable-function-bodies +// RUN: %FileCheck %s --check-prefixes CHECK < %t/Module.swiftinterface + +// REQUIRES: OS=macosx + +@available(macOS 10.16, *) +public func introduced10_16() { } +// CHECK: @available(OSX 11.0, *) +// CHECK-NEXT: public func introduced10_16() + + +@available(OSX 11.0, *) +public func introduced11_0() { } +// CHECK-NEXT: @available(OSX 11.0, *) +// CHECK-NEXT: public func introduced11_0() + + diff --git a/test/IDE/print_ast_tc_decls_macosx_canonical_versions.swift b/test/IDE/print_ast_tc_decls_macosx_canonical_versions.swift new file mode 100644 index 0000000000000..86a6565b740af --- /dev/null +++ b/test/IDE/print_ast_tc_decls_macosx_canonical_versions.swift @@ -0,0 +1,16 @@ +// RUN: %empty-directory(%t) +// +// +// RUN: %target-swift-frontend(mock-sdk: -sdk %S/../Inputs/clang-importer-sdk -I %t) -swift-version 4 -typecheck -verify %s -F %S/Inputs/mock-sdk -enable-objc-interop -disable-objc-attr-requires-foundation-module +// +// RUN: %target-swift-ide-test(mock-sdk: -sdk %S/../Inputs/clang-importer-sdk -I %t) -swift-version 4 -skip-deinit=false -print-ast-typechecked -source-filename %s -F %S/Inputs/mock-sdk -function-definitions=false -prefer-type-repr=false -print-implicit-attrs=true -enable-objc-interop -disable-objc-attr-requires-foundation-module > %t.printed.txt +// RUN: %FileCheck %s -check-prefix=PASS_COMMON -strict-whitespace < %t.printed.txt + + +// FIXME: rdar://problem/19648117 Needs splitting objc parts out +// REQUIRES: objc_interop + +@available(iOS 10.16, OSX 10.16, *) +func introduced10_16() {} +// PASS_COMMON: {{^}}@available(iOS 10.16, OSX 11.0, *){{$}} +// PASS_COMMON-NEXT: {{^}}func introduced10_16(){{$}} diff --git a/test/IDE/print_clang_header_i386.swift b/test/IDE/print_clang_header_i386.swift index 5f514182ce9fb..4774771e3fb83 100644 --- a/test/IDE/print_clang_header_i386.swift +++ b/test/IDE/print_clang_header_i386.swift @@ -1,4 +1,5 @@ // REQUIRES: OS=macosx +// REQUIRES: CPU=x86_64 // FIXME: rdar://problem/19648117 Needs splitting objc parts out // XFAIL: linux, freebsd diff --git a/test/IDE/print_module_bad_target.swift b/test/IDE/print_module_bad_target.swift index da4a02bb5684b..5ebec7359c244 100644 --- a/test/IDE/print_module_bad_target.swift +++ b/test/IDE/print_module_bad_target.swift @@ -1,7 +1,7 @@ // RUN: not %swift-ide-test -source-filename %s -print-module -module-to-print Swift -target x86_64-unknown-solaris // RUN: %empty-directory(%t) -// RUN: %target-swift-frontend -emit-module -o %t -module-name Dummy -target x86_64-apple-macosx10.99 %s +// RUN: %target-swift-frontend -emit-module -o %t -module-name Dummy -target %target-cpu-apple-macosx10.99 %s // RUN: not %target-swift-ide-test -source-filename %s -print-module -module-to-print Dummy -I %t // REQUIRES: OS=macosx diff --git a/test/IRGen/Inputs/ObjectiveC.swift b/test/IRGen/Inputs/ObjectiveC.swift index 2a21acf99b142..f455271717cab 100644 --- a/test/IRGen/Inputs/ObjectiveC.swift +++ b/test/IRGen/Inputs/ObjectiveC.swift @@ -2,7 +2,8 @@ @_exported import ObjectiveC public struct ObjCBool : CustomStringConvertible { -#if os(macOS) || (os(iOS) && (arch(i386) || arch(arm))) +#if (os(macOS) && arch(x86_64)) || (os(iOS) && (arch(i386) || arch(arm) || targetEnvironment(macCatalyst))) + // On macOS and 32-bit iOS, Objective-C's BOOL type is a "signed char". private var value: Int8 diff --git a/test/IRGen/abitypes.swift b/test/IRGen/abitypes.swift index b542eaedf1153..0158278f8a8f7 100644 --- a/test/IRGen/abitypes.swift +++ b/test/IRGen/abitypes.swift @@ -17,6 +17,7 @@ import Foundation // 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 } +// arm64-macosx: [[ARM64E_MYRECT:%.*]] = type { float, float, float, float } class Foo { // x86_64-macosx: define hidden swiftcc { float, float, float, float } @"$s8abitypes3FooC3bar{{[_0-9a-zA-Z]*}}F"(%T8abitypes3FooC* swiftself %0) {{.*}} { @@ -428,7 +429,12 @@ class Foo { // armv7k-watchos: [[TOOBJCBOOL:%[0-9]+]] = call swiftcc i1 @"$s10ObjectiveC22_convertBoolToObjCBool{{[_0-9a-zA-Z]*}}F"(i1 [[NEG]]) // armv7k-watchos: ret i1 [[TOOBJCBOOL]] // - @objc dynamic func negate2(_ b: Bool) -> Bool { + + // arm64-macosx: define hidden zeroext i1 @"$s8abitypes3FooC7negate2{{[_0-9a-zA-Z]*}}FTo"(i8* %0, i8* %1, i1 zeroext %2) + // arm64-macosx: [[NEG:%[0-9]+]] = call swiftcc i1 @"$s8abitypes3FooC7negate2{{[_0-9a-zA-Z]*}}F"(i1 + // arm64-macosx: [[TOOBJCBOOL:%[0-9]+]] = call swiftcc i1 @"$s10ObjectiveC22_convertBoolToObjCBool{{[_0-9a-zA-Z]*}}F"(i1 [[NEG]]) + // arm64-macosx: ret i1 [[TOOBJCBOOL]] +@objc dynamic func negate2(_ b: Bool) -> Bool { var g = Gadget() return g.negate(b) } @@ -532,6 +538,8 @@ class Foo { // // 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]*}} { + // arm64-macosx: 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-macosx: define hidden void @"$s8abitypes3FooC14callJustReturn{{[_0-9a-zA-Z]*}}FTo"(%TSo9BigStructV* noalias nocapture sret %0, i8* %1, i8* %2, [[OPAQUE:.*]]* %3, %TSo9BigStructV* %4) {{.*}} { @objc dynamic func callJustReturn(_ r: StructReturns, with v: BigStruct) -> BigStruct { return r.justReturn(v) } @@ -585,6 +593,15 @@ public func testInlineAgg(_ rect: MyRect) -> Float { // 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]]) +// arm64-macosx: define swiftcc void @"$s8abitypes14testBOOLStructyyF"() +// arm64-macosx: [[COERCED:%.*]] = alloca i64 +// arm64-macosx: [[STRUCTPTR:%.*]] = bitcast i64* [[COERCED]] to %TSo14FiveByteStructV +// arm64-macosx: [[PTR0:%.*]] = getelementptr inbounds %TSo14FiveByteStructV, %TSo14FiveByteStructV* [[STRUCTPTR]], {{i.*}} 0, {{i.*}} 0 +// arm64-macosx: [[PTR1:%.*]] = getelementptr inbounds %T10ObjectiveC8ObjCBoolV, %T10ObjectiveC8ObjCBoolV* [[PTR0]], {{i.*}} 0, {{i.*}} 0 +// arm64-macosx: [[PTR2:%.*]] = getelementptr inbounds %TSb, %TSb* [[PTR1]], {{i.*}} 0, {{i.*}} 0 +// arm64-macosx: store i1 false, i1* [[PTR2]], align 8 +// arm64-macosx: [[ARG:%.*]] = load i64, i64* [[COERCED]] +// arm64-macosx: 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/autolink-runtime-compatibility-arm64-maccatalyst.swift b/test/IRGen/autolink-runtime-compatibility-arm64-maccatalyst.swift new file mode 100644 index 0000000000000..9f6d38802a5b2 --- /dev/null +++ b/test/IRGen/autolink-runtime-compatibility-arm64-maccatalyst.swift @@ -0,0 +1,13 @@ +// REQUIRES: CPU=arm64,OS=maccatalyst + +// Doesn't autolink compatibility library because target OS doesn't need it +// RUN: %target-swift-frontend -target arm64-apple-ios12.0-macabi -emit-ir -parse-stdlib %s | %FileCheck -check-prefix=NO-FORCE-LOAD %s + +public func foo() {} + +// NO-FORCE-LOAD-NOT: FORCE_LOAD +// NO-FORCE-LOAD-NOT: !{!"-lswiftCompatibility50"} +// NO-FORCE-LOAD-NOT: !{!"-lswiftCompatibility51"} +// NO-FORCE-LOAD-NOT: !{!"-lswiftCompatibility52"} +// NO-FORCE-LOAD-NOT: !{!"-lswiftCompatibility53"} +// NO-FORCE-LOAD-NOT: !{!"-lswiftCompatibilityDynamicReplacements"} diff --git a/test/IRGen/autolink-runtime-compatibility-arm64-macos.swift b/test/IRGen/autolink-runtime-compatibility-arm64-macos.swift new file mode 100644 index 0000000000000..48e9c61955e44 --- /dev/null +++ b/test/IRGen/autolink-runtime-compatibility-arm64-macos.swift @@ -0,0 +1,13 @@ +// REQUIRES: CPU=arm64,OS=macosx + +// Doesn't autolink compatibility library because target OS doesn't need it +// RUN: %target-swift-frontend -target arm64-apple-macosx10.14 -emit-ir -parse-stdlib %s | %FileCheck -check-prefix=NO-FORCE-LOAD %s + +public func foo() {} + +// NO-FORCE-LOAD-NOT: FORCE_LOAD +// NO-FORCE-LOAD-NOT: !{!"-lswiftCompatibility50"} +// NO-FORCE-LOAD-NOT: !{!"-lswiftCompatibility51"} +// NO-FORCE-LOAD-NOT: !{!"-lswiftCompatibility52"} +// NO-FORCE-LOAD-NOT: !{!"-lswiftCompatibility53"} +// NO-FORCE-LOAD-NOT: !{!"-lswiftCompatibilityDynamicReplacements"} diff --git a/test/IRGen/autolink-runtime-compatibility.swift b/test/IRGen/autolink-runtime-compatibility.swift index 99dc558382103..54102577c19b3 100644 --- a/test/IRGen/autolink-runtime-compatibility.swift +++ b/test/IRGen/autolink-runtime-compatibility.swift @@ -1,23 +1,23 @@ // REQUIRES: OS=macosx // Doesn't autolink compatibility library because autolinking is disabled -// RUN: %target-swift-frontend -disable-autolinking-runtime-compatibility-dynamic-replacements -target x86_64-apple-macosx10.9 -disable-autolinking-runtime-compatibility -emit-ir -parse-stdlib %s | %FileCheck -check-prefix=NO-FORCE-LOAD %s +// RUN: %target-swift-frontend -disable-autolinking-runtime-compatibility-dynamic-replacements -target %target-cpu-apple-macosx10.9 -disable-autolinking-runtime-compatibility -emit-ir -parse-stdlib %s | %FileCheck -check-prefix=NO-FORCE-LOAD %s // RUN: %target-swift-frontend -disable-autolinking-runtime-compatibility-dynamic-replacements -runtime-compatibility-version 5.0 -disable-autolinking-runtime-compatibility -emit-ir -parse-stdlib %s | %FileCheck -check-prefix=NO-FORCE-LOAD %s // Doesn't autolink compatibility library because runtime compatibility library is disabled // RUN: %target-swift-frontend -runtime-compatibility-version none -emit-ir -parse-stdlib %s | %FileCheck -check-prefix=NO-FORCE-LOAD %s // Doesn't autolink compatibility library because target OS doesn't need it -// RUN: %target-swift-frontend -target x86_64-apple-macosx10.24 -emit-ir -parse-stdlib %s | %FileCheck -check-prefix=NO-FORCE-LOAD %s +// RUN: %target-swift-frontend -target %target-cpu-apple-macosx10.24 -emit-ir -parse-stdlib %s | %FileCheck -check-prefix=NO-FORCE-LOAD %s // Only autolinks 5.1 compatibility library because target OS has 5.1 -// RUN: %target-swift-frontend -target x86_64-apple-macosx10.15 -emit-ir -parse-stdlib %s | %FileCheck -check-prefix=FORCE-LOAD-51 %s +// RUN: %target-swift-frontend -target %target-cpu-apple-macosx10.15 -emit-ir -parse-stdlib %s | %FileCheck -check-prefix=FORCE-LOAD-51 %s // Autolinks because compatibility library was explicitly asked for // RUN: %target-swift-frontend -runtime-compatibility-version 5.0 -emit-ir -parse-stdlib %s | %FileCheck -check-prefix=FORCE-LOAD %s // RUN: %target-swift-frontend -runtime-compatibility-version 5.1 -emit-ir -parse-stdlib %s | %FileCheck -check-prefix=FORCE-LOAD-51 %s -// RUN: %target-swift-frontend -target x86_64-apple-macosx10.24 -runtime-compatibility-version 5.0 -emit-ir -parse-stdlib %s | %FileCheck -check-prefix=FORCE-LOAD %s -// RUN: %target-swift-frontend -target x86_64-apple-macosx10.24 -runtime-compatibility-version 5.1 -emit-ir -parse-stdlib %s | %FileCheck -check-prefix=FORCE-LOAD-51 %s +// RUN: %target-swift-frontend -target %target-cpu-apple-macosx10.24 -runtime-compatibility-version 5.0 -emit-ir -parse-stdlib %s | %FileCheck -check-prefix=FORCE-LOAD %s +// RUN: %target-swift-frontend -target %target-cpu-apple-macosx10.24 -runtime-compatibility-version 5.1 -emit-ir -parse-stdlib %s | %FileCheck -check-prefix=FORCE-LOAD-51 %s public func foo() {} diff --git a/test/IRGen/condfail.sil b/test/IRGen/condfail.sil index 528e63a65474e..ebdc6b92318bc 100644 --- a/test/IRGen/condfail.sil +++ b/test/IRGen/condfail.sil @@ -17,8 +17,8 @@ import Swift // CHECK-powerpc64: .cfi_startproc // CHECK-powerpc64le: .cfi_startproc // CHECK-s390x: .cfi_startproc -// CHECK-OPT-macosx: ## InlineAsm Start -// CHECK-OPT-macosx: ## InlineAsm End +// CHECK-OPT-macosx: InlineAsm Start +// CHECK-OPT-macosx: InlineAsm End // CHECK-OPT-linux: ##APP // CHECK-OPT-linux: ##NO_APP // CHECK-OPT-windows: ##APP @@ -27,8 +27,8 @@ import Swift // CHECK-OPT-linux-androideabi: @NO_APP // CHECK-OPT-linux-android: //APP // CHECK-OPT-linux-android: //NO_APP -// CHECK-NOOPT-macosx-NOT: ## InlineAsm Start -// CHECK-NOOPT-macosx-NOT: ## InlineAsm End +// CHECK-NOOPT-macosx-NOT: InlineAsm Start +// CHECK-NOOPT-macosx-NOT: InlineAsm End // CHECK-NOOPT-linux-NOT: ##APP // CHECK-NOOPT-linux-NOT: ##NO_APP // CHECK-NOOPT-windows-NOT: ##APP @@ -55,14 +55,14 @@ import Swift // CHECK-NOT-powerpc64: .cfi_endproc // CHECK-NOT-powerpc64le: .cfi_endproc // CHECK-NOT-s390x: .cfi_endproc -// CHECK-OPT-macosx: ## InlineAsm Start -// CHECK-OPT-macosx: ## InlineAsm End +// CHECK-OPT-macosx: InlineAsm Start +// CHECK-OPT-macosx: InlineAsm End // CHECK-OPT-linux: ##APP // CHECK-OPT-linux: ##NO_APP // CHECK-OPT-windows: ##APP // CHECK-OPT-windows: ##NO_APP -// CHECK-NOOPT-macosx-NOT: ## InlineAsm Start -// CHECK-NOOPT-macosx-NOT: ## InlineAsm End +// CHECK-NOOPT-macosx-NOT: InlineAsm Start +// CHECK-NOOPT-macosx-NOT: InlineAsm End // CHECK-NOOPT-linux-NOT: ##APP // CHECK-NOOPT-linux-NOT: ##NO_APP // CHECK-NOOPT-windows-NOT: ##APP diff --git a/test/IRGen/conditional_conformances_gettypemetdatabyname.swift b/test/IRGen/conditional_conformances_gettypemetdatabyname.swift index 7ab1f91295f61..a194e081a7a01 100644 --- a/test/IRGen/conditional_conformances_gettypemetdatabyname.swift +++ b/test/IRGen/conditional_conformances_gettypemetdatabyname.swift @@ -1,5 +1,7 @@ -// RUN: %target-swift-frontend -disable-generic-metadata-prespecialization -target x86_64-apple-macosx10.99 -emit-ir %S/../Inputs/conditional_conformance_basic_conformances.swift | %FileCheck %S/../Inputs/conditional_conformance_basic_conformances.swift --check-prefix=TYPEBYNAME -// RUN: %target-swift-frontend -prespecialize-generic-metadata -target x86_64-apple-macosx10.99 -emit-ir %S/../Inputs/conditional_conformance_basic_conformances.swift | %FileCheck %S/../Inputs/conditional_conformance_basic_conformances.swift --check-prefix=TYPEBYNAME_PRESPECIALIZED +// RUN: %target-swift-frontend -disable-generic-metadata-prespecialization -target %target-cpu-apple-macosx10.15.4 -emit-ir %S/../Inputs/conditional_conformance_basic_conformances.swift | %FileCheck %S/../Inputs/conditional_conformance_basic_conformances.swift --check-prefix=TYPEBYNAME +// RUN: %target-swift-frontend -prespecialize-generic-metadata -target %target-cpu-apple-macosx99.99 -emit-ir %S/../Inputs/conditional_conformance_basic_conformances.swift | %FileCheck %S/../Inputs/conditional_conformance_basic_conformances.swift --check-prefix=TYPEBYNAME_PRESPECIALIZED +// RUN: %target-swift-frontend -target %target-cpu-apple-macosx10.15.4 -emit-ir %S/../Inputs/conditional_conformance_basic_conformances.swift | %FileCheck %S/../Inputs/conditional_conformance_basic_conformances.swift --check-prefix=CHECK --check-prefix=CHECK-STABLE-ABI-TRUE + // Too many pointer-sized integers in the IR // REQUIRES: PTRSIZE=64 diff --git a/test/IRGen/generic_metatypes_future.swift b/test/IRGen/generic_metatypes_future.swift index 88dfd18bbd07f..bf18d17617de0 100644 --- a/test/IRGen/generic_metatypes_future.swift +++ b/test/IRGen/generic_metatypes_future.swift @@ -1,5 +1,5 @@ -// RUN: %swift -prespecialize-generic-metadata -module-name generic_metatypes -target x86_64-apple-macosx10.99 -emit-ir -disable-legacy-type-info -parse-stdlib -primary-file %s | %FileCheck --check-prefix=CHECK --check-prefix=CHECK-64 -DINT=i64 %s +// RUN: %swift -prespecialize-generic-metadata -module-name generic_metatypes -target x86_64-apple-macosx50.99 -emit-ir -disable-legacy-type-info -parse-stdlib -primary-file %s | %FileCheck --check-prefix=CHECK --check-prefix=CHECK-64 -DINT=i64 %s // RUN: %swift -prespecialize-generic-metadata -module-name generic_metatypes -target x86_64-apple-ios99.0 -emit-ir -disable-legacy-type-info -parse-stdlib -primary-file %s | %FileCheck --check-prefix=CHECK --check-prefix=CHECK-64 -DINT=i64 %s // RUN: %swift -prespecialize-generic-metadata -module-name generic_metatypes -target x86_64-apple-tvos99.0 -emit-ir -disable-legacy-type-info -parse-stdlib -primary-file %s | %FileCheck --check-prefix=CHECK --check-prefix=CHECK-64 -DINT=i64 %s // RUN: %swift -prespecialize-generic-metadata -module-name generic_metatypes -target i386-apple-watchos9.99 -emit-ir -disable-legacy-type-info -parse-stdlib -primary-file %s | %FileCheck --check-prefix=CHECK --check-prefix=CHECK-32 -DINT=i32 %s diff --git a/test/IRGen/lazy_metadata_with-g.swift b/test/IRGen/lazy_metadata_with-g.swift index b5f02f6720249..d532778d2fe96 100644 --- a/test/IRGen/lazy_metadata_with-g.swift +++ b/test/IRGen/lazy_metadata_with-g.swift @@ -1,4 +1,4 @@ -// RUN: %target-swiftc_driver -parse-as-library -module-name=test -target x86_64-apple-macosx10.15 -wmo -O -g -emit-ir %s | %FileCheck %s +// RUN: %target-swiftc_driver -parse-as-library -module-name=test -target %target-cpu-apple-macosx10.15 -wmo -O -g -emit-ir %s | %FileCheck %s // REQUIRES: OS=macosx // Check that the compiler does not emit any metadata for unused internal diff --git a/test/IRGen/metadata.swift b/test/IRGen/metadata.swift index f838c4e1f43b4..54fbd30a6d31a 100644 --- a/test/IRGen/metadata.swift +++ b/test/IRGen/metadata.swift @@ -10,7 +10,7 @@ enum Singleton { // CHECK: @"$s1A1GC14zeroSizedFieldAA9SingletonOvpWvd" = hidden constant i{{(64|32)}} 0 // Check that the instance start is after the header (at 8 or 16). -// CHECK-macosx: _DATA__TtC1A1G = private constant {{.*}} { i32 128, i32 {{(16|8)}} +// CHECK-macosx: _DATA__TtC1A1G = private constant {{.*}} { i32 {{(128|129)}}, i32 {{(16|8|40)}} // CHECK-ios: _DATA__TtC1A1G = private constant {{.*}} { i32 {{(128|129)}}, i32 {{(16|8|40)}} // CHECK-watchos: _DATA__TtC1A1G = private constant {{.*}} { i32 128, i32 {{(16|8)}} // CHECK-tvos: _DATA__TtC1A1G = private constant {{.*}} { i32 128, i32 {{(16|8)}} diff --git a/test/IRGen/objc_properties.swift b/test/IRGen/objc_properties.swift index bcf966829a886..8d740e51985b1 100644 --- a/test/IRGen/objc_properties.swift +++ b/test/IRGen/objc_properties.swift @@ -1,7 +1,7 @@ // This file is also used by objc_properties_ios.swift. -// RUN: %swift -target x86_64-apple-macosx10.11 %s -disable-target-os-checking -emit-ir -disable-objc-attr-requires-foundation-module | %FileCheck -check-prefix=CHECK -check-prefix=CHECK-NEW %s -// RUN: %swift -target x86_64-apple-macosx10.10 %s -disable-target-os-checking -emit-ir -disable-objc-attr-requires-foundation-module | %FileCheck -check-prefix=CHECK -check-prefix=CHECK-OLD %s +// RUN: %swift -target %target-cpu-apple-macosx10.11 %s -disable-target-os-checking -emit-ir -disable-objc-attr-requires-foundation-module | %FileCheck -check-prefix=CHECK -check-prefix=CHECK-NEW %s +// RUN: %swift -target %target-cpu-apple-macosx10.10 %s -disable-target-os-checking -emit-ir -disable-objc-attr-requires-foundation-module | %FileCheck -check-prefix=CHECK -check-prefix=CHECK-OLD %s // REQUIRES: OS=macosx // REQUIRES: objc_interop @@ -118,7 +118,7 @@ class SomeWrapperTests { // CHECK-SAME: i32 {{[0-9]+}}, i32 {{[0-9]+}}, i32 {{[0-9]+}}, i32 {{[0-9]+}}, // CHECK-SAME: i8* null, // CHECK-SAME: i8* getelementptr inbounds ([{{.+}} x i8], [{{.+}} x i8]* {{@.+}}, i64 0, i64 0), -// CHECK-SAME: { {{.+}} }* @_CLASS_METHODS__TtC15objc_properties10SomeObject, +// CHECK-SAME: { {{.+}} }* @_CLASS_METHODS__TtC15objc_properties10SomeObject{{(\.ptrauth)?}} // CHECK-SAME: i8* null, i8* null, i8* null, // CHECK-NEW-SAME: { {{.+}} }* @_CLASS_PROPERTIES__TtC15objc_properties10SomeObject // CHECK-OLD-SAME: i8* null @@ -133,35 +133,35 @@ class SomeWrapperTests { // CHECK: [8 x { i8*, i8*, i8* }] [{ // CHECK: i8* getelementptr inbounds ([9 x i8], [9 x i8]* @"\01L_selector_data(readonly)", i64 0, i64 0), // CHECK: i8* getelementptr inbounds ([8 x i8], [8 x i8]* [[GETTER_SIGNATURE]], i64 0, i64 0), -// CHECK: i8* bitcast ([[OPAQUE0:%.*]]* ([[OPAQUE1:%.*]]*, i8*)* @"$s15objc_properties10SomeObjectC8readonlyACvgTo" to i8*) +// CHECK: @"$s15objc_properties10SomeObjectC8readonlyACvgTo{{(.ptrauth)?}}" // CHECK: }, { // CHECK: i8* getelementptr inbounds ([10 x i8], [10 x i8]* @"\01L_selector_data(readwrite)", i64 0, i64 0), // CHECK: i8* getelementptr inbounds ([8 x i8], [8 x i8]* [[GETTER_SIGNATURE]], i64 0, i64 0), -// CHECK: i8* bitcast ([[OPAQUE0]]* ([[OPAQUE1]]*, i8*)* @"$s15objc_properties10SomeObjectC9readwriteACvgTo" to i8*) +// CHECK: @"$s15objc_properties10SomeObjectC9readwriteACvgTo{{(.ptrauth)?}}" // CHECK: }, { // CHECK: i8* getelementptr inbounds ([14 x i8], [14 x i8]* @"\01L_selector_data(setReadwrite:)", i64 0, i64 0), // CHECK: i8* getelementptr inbounds ([11 x i8], [11 x i8]* [[SETTER_SIGNATURE]], i64 0, i64 0), -// CHECK: i8* bitcast (void ([[OPAQUE3:%.*]]*, i8*, [[OPAQUE4:%.*]]*)* @"$s15objc_properties10SomeObjectC9readwriteACvsTo" to i8*) +// CHECK: @"$s15objc_properties10SomeObjectC9readwriteACvsTo{{(.ptrauth)?}}" // CHECK: }, { // CHECK: i8* getelementptr inbounds ([9 x i8], [9 x i8]* @"\01L_selector_data(bareIvar)", i64 0, i64 0), // CHECK: i8* getelementptr inbounds ([8 x i8], [8 x i8]* [[GETTER_SIGNATURE]], i64 0, i64 0), -// CHECK: i8* bitcast ([[OPAQUE0]]* ([[OPAQUE1]]*, i8*)* @"$s15objc_properties10SomeObjectC8bareIvarACvgTo" to i8*) +// CHECK: @"$s15objc_properties10SomeObjectC8bareIvarACvgTo{{(.ptrauth)?}}" // CHECK: }, { // CHECK: i8* getelementptr inbounds ([13 x i8], [13 x i8]* @"\01L_selector_data(setBareIvar:)", i64 0, i64 0), // CHECK: i8* getelementptr inbounds ([11 x i8], [11 x i8]* [[SETTER_SIGNATURE]], i64 0, i64 0), -// CHECK: i8* bitcast (void ([[OPAQUE3]]*, i8*, [[OPAQUE4]]*)* @"$s15objc_properties10SomeObjectC8bareIvarACvsTo" to i8*) +// CHECK: @"$s15objc_properties10SomeObjectC8bareIvarACvsTo{{(.ptrauth)?}}" // CHECK: }, { // CHECK: i8* getelementptr inbounds ([7 x i8], [7 x i8]* @"\01L_selector_data(wobble)", i64 0, i64 0), // CHECK: i8* getelementptr inbounds ([8 x i8], [8 x i8]* [[GETTER_SIGNATURE]], i64 0, i64 0), -// CHECK: i8* bitcast (%0* (%0*, i8*)* @"$s15objc_properties10SomeObjectC6wibbleACvgTo" to i8*) +// CHECK: @"$s15objc_properties10SomeObjectC6wibbleACvgTo{{(.ptrauth)?}}" // CHECK: }, { // CHECK: i8* getelementptr inbounds ([11 x i8], [11 x i8]* @"\01L_selector_data(setWobble:)", i64 0, i64 0), // CHECK: i8* getelementptr inbounds ([11 x i8], [11 x i8]* [[SETTER_SIGNATURE]], i64 0, i64 0), -// CHECK: i8* bitcast (void (%0*, i8*, %0*)* @"$s15objc_properties10SomeObjectC6wibbleACvsTo" to i8*) +// CHECK: @"$s15objc_properties10SomeObjectC6wibbleACvsTo{{(.ptrauth)?}}" // CHECK: }, { // CHECK: i8* getelementptr inbounds ([5 x i8], [5 x i8]* @"\01L_selector_data(init)", i64 0, i64 0), // CHECK: i8* getelementptr inbounds ([8 x i8], [8 x i8]* [[GETTER_SIGNATURE]], i64 0, i64 0), -// CHECK: i8* bitcast ([[OPAQUE5:%.*]]* ([[OPAQUE6:%.*]]*, i8*)* @"$s15objc_properties10SomeObjectCACycfcTo" to i8*) +// CHECK: @"$s15objc_properties10SomeObjectCACycfcTo{{(.ptrauth)?}}" // CHECK: }] // CHECK: }, section "__DATA, __objc_const", align 8 @@ -201,7 +201,7 @@ class SomeWrapperTests { // CHECK: i32 {{[0-9]+}}, i32 {{[0-9]+}}, i32 {{[0-9]+}}, i32 {{[0-9]+}}, // CHECK: i8* null, // CHECK: i8* getelementptr inbounds ([{{.+}} x i8], [{{.+}} x i8]* {{@.+}}, i64 0, i64 0), -// CHECK: { {{.+}} }* @_INSTANCE_METHODS__TtC15objc_properties10SomeObject, +// CHECK: { {{.+}} }* @_INSTANCE_METHODS__TtC15objc_properties10SomeObject{{(\.ptrauth)?}} // CHECK: i8* null, // CHECK: { {{.+}} }* @_IVARS__TtC15objc_properties10SomeObject, // CHECK: i8* null, @@ -214,11 +214,11 @@ class SomeWrapperTests { // CHECK: [2 x { i8*, i8*, i8* }] [{ // CHECK: { i8* getelementptr inbounds ([18 x i8], [18 x i8]* @"\01L_selector_data(extensionProperty)", i64 0, i64 0), // CHECK: i8* getelementptr inbounds ([8 x i8], [8 x i8]* [[GETTER_SIGNATURE]], i64 0, i64 0), -// CHECK: i8* bitcast ([[OPAQUE0]]* ([[OPAQUE1]]*, i8*)* @"$s15objc_properties10SomeObjectC17extensionPropertyACvgTo" to i8*) +// CHECK: @"$s15objc_properties10SomeObjectC17extensionPropertyACvgTo{{(.ptrauth)?}}" // CHECK: }, { // CHECK: i8* getelementptr inbounds ([22 x i8], [22 x i8]* @"\01L_selector_data(setExtensionProperty:)", i64 0, i64 0), // CHECK: i8* getelementptr inbounds ([11 x i8], [11 x i8]* [[SETTER_SIGNATURE]], i64 0, i64 0), -// CHECK: i8* bitcast (void ([[OPAQUE3]]*, i8*, [[OPAQUE4]]*)* @"$s15objc_properties10SomeObjectC17extensionPropertyACvsTo" to i8*) +// CHECK: @"$s15objc_properties10SomeObjectC17extensionPropertyACvsTo{{(.ptrauth)?}}" // CHECK: }] // CHECK: }, section "__DATA, __objc_const", align 8 @@ -250,11 +250,11 @@ class SomeWrapperTests { // CHECK: @"_CATEGORY__TtC15objc_properties10SomeObject_$_objc_properties" = private constant { {{.+}} } { // CHECK: i8* getelementptr inbounds ([{{.+}} x i8], [{{.+}} x i8]* {{@.+}}, i64 0, i64 0), -// CHECK: %swift.type* bitcast (i64* getelementptr inbounds (<{ {{.+}} }>* @"$s15objc_properties10SomeObjectCMf", i32 0, i32 2) to %swift.type*), -// CHECK: { {{.+}} }* @"_CATEGORY_INSTANCE_METHODS__TtC15objc_properties10SomeObject_$_objc_properties", -// CHECK: { {{.+}} }* @"_CATEGORY_CLASS_METHODS__TtC15objc_properties10SomeObject_$_objc_properties", +// CHECK: @"$s15objc_properties10SomeObjectCMf", i32 0, i32 2 +// CHECK: { {{.+}} }* @"_CATEGORY_INSTANCE_METHODS__TtC15objc_properties10SomeObject_$_objc_properties{{(\.ptrauth)?}}" +// CHECK: { {{.+}} }* @"_CATEGORY_CLASS_METHODS__TtC15objc_properties10SomeObject_$_objc_properties{{(\.ptrauth)?}}" // CHECK: i8* null, -// CHECK: { {{.+}} }* @"_CATEGORY_PROPERTIES__TtC15objc_properties10SomeObject_$_objc_properties", +// CHECK: { {{.+}} }* @"_CATEGORY_PROPERTIES__TtC15objc_properties10SomeObject_$_objc_properties{{(\.ptrauth)?}}", // CHECK-NEW: { {{.+}} }* @"_CATEGORY_CLASS_PROPERTIES__TtC15objc_properties10SomeObject_$_objc_properties", // CHECK-OLD: i8* null, // CHECK: i32 60 @@ -264,10 +264,10 @@ class SomeWrapperTests { // CHECK: @_INSTANCE_METHODS__TtC15objc_properties4Tree = // CHECK: i8* getelementptr inbounds ([7 x i8], [7 x i8]* @"\01L_selector_data(parent)", i64 0, i64 0), // CHECK: i8* getelementptr inbounds ([8 x i8], [8 x i8]* [[GETTER_SIGNATURE]], i64 0, i64 0), -// CHECK: i8* bitcast (%2* (%2*, i8*)* @"$s15objc_properties4TreeC6parentACSgvgTo" to i8*) +// CHECK: @"$s15objc_properties4TreeC6parentACSgvgTo{{(.ptrauth)?}}" // CHECK: i8* getelementptr inbounds ([11 x i8], [11 x i8]* @"\01L_selector_data(setParent:)", i64 0, i64 0), // CHECK: i8* getelementptr inbounds ([11 x i8], [11 x i8]* [[SETTER_SIGNATURE]], i64 0, i64 0), -// CHECK: i8* bitcast (void (%2*, i8*, %2*)* @"$s15objc_properties4TreeC6parentACSgvsTo" to i8*) +// CHECK: @"$s15objc_properties4TreeC6parentACSgvsTo{{(.ptrauth)?}}" // CHECK: @_PROTOCOL__TtP15objc_properties5Proto_ = private constant { {{.+}} } { // CHECK: i8* null, diff --git a/test/IRGen/objc_protocol_extended_method_types.swift b/test/IRGen/objc_protocol_extended_method_types.swift index 3b23b810e7ec7..173e51d289587 100644 --- a/test/IRGen/objc_protocol_extended_method_types.swift +++ b/test/IRGen/objc_protocol_extended_method_types.swift @@ -102,26 +102,26 @@ print(P.self) // CHECK-JIT: [[NEW_PROTOCOL:%.+]] = call %swift.protocol* @objc_allocateProtocol(i8* getelementptr inbounds ([45 x i8], [45 x i8]* @2, i64 0, i64 0)) // -- requiredInstanceMethod: // CHECK-JIT: [[SELECTOR:%.+]] = call i8* @sel_registerName(i8* getelementptr inbounds ([{{[0-9]+}} x i8], [{{[0-9]+}} x i8]* @"\01L_selector_data(requiredInstanceMethod:)", i64 0, i64 0)) -// CHECK-JIT: call void @protocol_addMethodDescription(%swift.protocol* [[NEW_PROTOCOL]], i8* [[SELECTOR]], i8* getelementptr inbounds ([{{[0-9]+}} x i8], [{{[0-9]+}} x i8]* [[TY_ID_ID]], i64 0, i64 0), i8 1, i8 1) +// CHECK-JIT: call void @protocol_addMethodDescription(%swift.protocol* [[NEW_PROTOCOL]], i8* [[SELECTOR]], i8* getelementptr inbounds ([{{[0-9]+}} x i8], [{{[0-9]+}} x i8]* [[TY_ID_ID]], i64 0, i64 0), {{(i8 1|i1 true)}}, {{(i8 1|i1 true)}}) // -- optionalInstanceMethod: // CHECK-JIT: [[SELECTOR:%.+]] = call i8* @sel_registerName(i8* getelementptr inbounds ([{{[0-9]+}} x i8], [{{[0-9]+}} x i8]* @"\01L_selector_data(optionalInstanceMethod:)", i64 0, i64 0)) -// CHECK-JIT: call void @protocol_addMethodDescription(%swift.protocol* [[NEW_PROTOCOL]], i8* [[SELECTOR]], i8* getelementptr inbounds ([{{[0-9]+}} x i8], [{{[0-9]+}} x i8]* [[TY_ID_ID]], i64 0, i64 0), i8 0, i8 1) +// CHECK-JIT: call void @protocol_addMethodDescription(%swift.protocol* [[NEW_PROTOCOL]], i8* [[SELECTOR]], i8* getelementptr inbounds ([{{[0-9]+}} x i8], [{{[0-9]+}} x i8]* [[TY_ID_ID]], i64 0, i64 0), {{(i8 0|i1 false)}}, {{(i8 1|i1 true)}}) // -- requiredClassMethod: // CHECK-JIT: [[SELECTOR:%.+]] = call i8* @sel_registerName(i8* getelementptr inbounds ([{{[0-9]+}} x i8], [{{[0-9]+}} x i8]* @"\01L_selector_data(requiredClassMethod:)", i64 0, i64 0)) -// CHECK-JIT: call void @protocol_addMethodDescription(%swift.protocol* [[NEW_PROTOCOL]], i8* [[SELECTOR]], i8* getelementptr inbounds ([{{[0-9]+}} x i8], [{{[0-9]+}} x i8]* [[TY_ID_ID]], i64 0, i64 0), i8 1, i8 0) +// CHECK-JIT: call void @protocol_addMethodDescription(%swift.protocol* [[NEW_PROTOCOL]], i8* [[SELECTOR]], i8* getelementptr inbounds ([{{[0-9]+}} x i8], [{{[0-9]+}} x i8]* [[TY_ID_ID]], i64 0, i64 0), {{(i8 1|i1 true)}}, {{(i8 0|i1 false)}}) // -- optionalClassMethod: // CHECK-JIT: [[SELECTOR:%.+]] = call i8* @sel_registerName(i8* getelementptr inbounds ([{{[0-9]+}} x i8], [{{[0-9]+}} x i8]* @"\01L_selector_data(optionalClassMethod:)", i64 0, i64 0)) -// CHECK-JIT: call void @protocol_addMethodDescription(%swift.protocol* [[NEW_PROTOCOL]], i8* [[SELECTOR]], i8* getelementptr inbounds ([{{[0-9]+}} x i8], [{{[0-9]+}} x i8]* [[TY_VOID_ID]], i64 0, i64 0), i8 0, i8 0) +// CHECK-JIT: call void @protocol_addMethodDescription(%swift.protocol* [[NEW_PROTOCOL]], i8* [[SELECTOR]], i8* getelementptr inbounds ([{{[0-9]+}} x i8], [{{[0-9]+}} x i8]* [[TY_VOID_ID]], i64 0, i64 0), {{(i8 0|i1 false)}}, {{(i8 0|i1 false)}}) // -- requiredInstanceProperty // CHECK-JIT: [[SELECTOR:%.+]] = call i8* @sel_registerName(i8* getelementptr inbounds ([{{[0-9]+}} x i8], [{{[0-9]+}} x i8]* @"\01L_selector_data(requiredInstanceProperty)", i64 0, i64 0)) -// CHECK-JIT: call void @protocol_addMethodDescription(%swift.protocol* [[NEW_PROTOCOL]], i8* [[SELECTOR]], i8* getelementptr inbounds ([{{[0-9]+}} x i8], [{{[0-9]+}} x i8]* [[TY_ID]], i64 0, i64 0), i8 1, i8 1) +// CHECK-JIT: call void @protocol_addMethodDescription(%swift.protocol* [[NEW_PROTOCOL]], i8* [[SELECTOR]], i8* getelementptr inbounds ([{{[0-9]+}} x i8], [{{[0-9]+}} x i8]* [[TY_ID]], i64 0, i64 0), {{(i8 1|i1 true)}}, {{(i8 1|i1 true)}}) // Make sure we don't emit storage accessors multiple times. // CHECK-JIT-NOT: requiredInstanceProperty // -- setRequiredInstanceProperty: // CHECK-JIT: [[SELECTOR:%.+]] = call i8* @sel_registerName(i8* getelementptr inbounds ([{{[0-9]+}} x i8], [{{[0-9]+}} x i8]* @"\01L_selector_data(setRequiredInstanceProperty:)", i64 0, i64 0)) -// CHECK-JIT: call void @protocol_addMethodDescription(%swift.protocol* [[NEW_PROTOCOL]], i8* [[SELECTOR]], i8* getelementptr inbounds ([{{[0-9]+}} x i8], [{{[0-9]+}} x i8]* [[TY_VOID_ID]], i64 0, i64 0), i8 1, i8 1) +// CHECK-JIT: call void @protocol_addMethodDescription(%swift.protocol* [[NEW_PROTOCOL]], i8* [[SELECTOR]], i8* getelementptr inbounds ([{{[0-9]+}} x i8], [{{[0-9]+}} x i8]* [[TY_VOID_ID]], i64 0, i64 0), {{(i8 1|i1 true)}}, {{(i8 1|i1 true)}}) // Make sure we don't emit storage accessors multiple times. // CHECK-JIT-NOT: requiredInstanceProperty @@ -129,34 +129,34 @@ print(P.self) // -- requiredROInstanceProperty // CHECK-JIT: [[SELECTOR:%.+]] = call i8* @sel_registerName(i8* getelementptr inbounds ([{{[0-9]+}} x i8], [{{[0-9]+}} x i8]* @"\01L_selector_data(requiredROInstanceProperty)", i64 0, i64 0)) -// CHECK-JIT: call void @protocol_addMethodDescription(%swift.protocol* [[NEW_PROTOCOL]], i8* [[SELECTOR]], i8* getelementptr inbounds ([{{[0-9]+}} x i8], [{{[0-9]+}} x i8]* [[TY_ID]], i64 0, i64 0), i8 1, i8 1) +// CHECK-JIT: call void @protocol_addMethodDescription(%swift.protocol* [[NEW_PROTOCOL]], i8* [[SELECTOR]], i8* getelementptr inbounds ([{{[0-9]+}} x i8], [{{[0-9]+}} x i8]* [[TY_ID]], i64 0, i64 0), {{(i8 1|i1 true)}}, {{(i8 1|i1 true)}}) // -- requiredInstanceMethod2: // CHECK-JIT: [[SELECTOR:%.+]] = call i8* @sel_registerName(i8* getelementptr inbounds ([{{[0-9]+}} x i8], [{{[0-9]+}} x i8]* @"\01L_selector_data(requiredInstanceMethod2:)", i64 0, i64 0)) -// CHECK-JIT: call void @protocol_addMethodDescription(%swift.protocol* [[NEW_PROTOCOL]], i8* [[SELECTOR]], i8* getelementptr inbounds ([{{[0-9]+}} x i8], [{{[0-9]+}} x i8]* [[TY_ID_ID]], i64 0, i64 0), i8 1, i8 1) +// CHECK-JIT: call void @protocol_addMethodDescription(%swift.protocol* [[NEW_PROTOCOL]], i8* [[SELECTOR]], i8* getelementptr inbounds ([{{[0-9]+}} x i8], [{{[0-9]+}} x i8]* [[TY_ID_ID]], i64 0, i64 0), {{(i8 1|i1 true)}}, {{(i8 1|i1 true)}}) // -- optionalInstanceMethod2: // CHECK-JIT: [[SELECTOR:%.+]] = call i8* @sel_registerName(i8* getelementptr inbounds ([{{[0-9]+}} x i8], [{{[0-9]+}} x i8]* @"\01L_selector_data(optionalInstanceMethod2:)", i64 0, i64 0)) -// CHECK-JIT: call void @protocol_addMethodDescription(%swift.protocol* [[NEW_PROTOCOL]], i8* [[SELECTOR]], i8* getelementptr inbounds ([{{[0-9]+}} x i8], [{{[0-9]+}} x i8]* [[TY_ID_ID]], i64 0, i64 0), i8 0, i8 1) +// CHECK-JIT: call void @protocol_addMethodDescription(%swift.protocol* [[NEW_PROTOCOL]], i8* [[SELECTOR]], i8* getelementptr inbounds ([{{[0-9]+}} x i8], [{{[0-9]+}} x i8]* [[TY_ID_ID]], i64 0, i64 0), {{(i8 0|i1 false)}}, {{(i8 1|i1 true)}}) // -- requiredClassMethod2: // CHECK-JIT: [[SELECTOR:%.+]] = call i8* @sel_registerName(i8* getelementptr inbounds ([{{[0-9]+}} x i8], [{{[0-9]+}} x i8]* @"\01L_selector_data(requiredClassMethod2:)", i64 0, i64 0)) -// CHECK-JIT: call void @protocol_addMethodDescription(%swift.protocol* [[NEW_PROTOCOL]], i8* [[SELECTOR]], i8* getelementptr inbounds ([{{[0-9]+}} x i8], [{{[0-9]+}} x i8]* [[TY_ID_ID]], i64 0, i64 0), i8 1, i8 0) +// CHECK-JIT: call void @protocol_addMethodDescription(%swift.protocol* [[NEW_PROTOCOL]], i8* [[SELECTOR]], i8* getelementptr inbounds ([{{[0-9]+}} x i8], [{{[0-9]+}} x i8]* [[TY_ID_ID]], i64 0, i64 0), {{(i8 1|i1 true)}}, {{(i8 0|i1 false)}}) // -- optionalClassMethod2: // CHECK-JIT: [[SELECTOR:%.+]] = call i8* @sel_registerName(i8* getelementptr inbounds ([{{[0-9]+}} x i8], [{{[0-9]+}} x i8]* @"\01L_selector_data(optionalClassMethod2:)", i64 0, i64 0)) -// CHECK-JIT: call void @protocol_addMethodDescription(%swift.protocol* [[NEW_PROTOCOL]], i8* [[SELECTOR]], i8* getelementptr inbounds ([{{[0-9]+}} x i8], [{{[0-9]+}} x i8]* [[TY_VOID_ID]], i64 0, i64 0), i8 0, i8 0) +// CHECK-JIT: call void @protocol_addMethodDescription(%swift.protocol* [[NEW_PROTOCOL]], i8* [[SELECTOR]], i8* getelementptr inbounds ([{{[0-9]+}} x i8], [{{[0-9]+}} x i8]* [[TY_VOID_ID]], i64 0, i64 0), {{(i8 0|i1 false)}}, {{(i8 0|i1 false)}}) // -- requiredInstanceProperty2 // CHECK-JIT: [[SELECTOR:%.+]] = call i8* @sel_registerName(i8* getelementptr inbounds ([{{[0-9]+}} x i8], [{{[0-9]+}} x i8]* @"\01L_selector_data(requiredInstanceProperty2)", i64 0, i64 0)) -// CHECK-JIT: call void @protocol_addMethodDescription(%swift.protocol* [[NEW_PROTOCOL]], i8* [[SELECTOR]], i8* getelementptr inbounds ([{{[0-9]+}} x i8], [{{[0-9]+}} x i8]* [[TY_ID]], i64 0, i64 0), i8 1, i8 1) +// CHECK-JIT: call void @protocol_addMethodDescription(%swift.protocol* [[NEW_PROTOCOL]], i8* [[SELECTOR]], i8* getelementptr inbounds ([{{[0-9]+}} x i8], [{{[0-9]+}} x i8]* [[TY_ID]], i64 0, i64 0), {{(i8 1|i1 true)}}, {{(i8 1|i1 true)}}) // -- setRequiredInstanceProperty2: // CHECK-JIT: [[SELECTOR:%.+]] = call i8* @sel_registerName(i8* getelementptr inbounds ([{{[0-9]+}} x i8], [{{[0-9]+}} x i8]* @"\01L_selector_data(setRequiredInstanceProperty2:)", i64 0, i64 0)) -// CHECK-JIT: call void @protocol_addMethodDescription(%swift.protocol* [[NEW_PROTOCOL]], i8* [[SELECTOR]], i8* getelementptr inbounds ([{{[0-9]+}} x i8], [{{[0-9]+}} x i8]* [[TY_VOID_ID]], i64 0, i64 0), i8 1, i8 1) +// CHECK-JIT: call void @protocol_addMethodDescription(%swift.protocol* [[NEW_PROTOCOL]], i8* [[SELECTOR]], i8* getelementptr inbounds ([{{[0-9]+}} x i8], [{{[0-9]+}} x i8]* [[TY_VOID_ID]], i64 0, i64 0), {{(i8 1|i1 true)}}, {{(i8 1|i1 true)}}) // -- requiredROInstanceProperty2 // CHECK-JIT: [[SELECTOR:%.+]] = call i8* @sel_registerName(i8* getelementptr inbounds ([{{[0-9]+}} x i8], [{{[0-9]+}} x i8]* @"\01L_selector_data(requiredROInstanceProperty2)", i64 0, i64 0)) -// CHECK-JIT: call void @protocol_addMethodDescription(%swift.protocol* [[NEW_PROTOCOL]], i8* [[SELECTOR]], i8* getelementptr inbounds ([{{[0-9]+}} x i8], [{{[0-9]+}} x i8]* [[TY_ID]], i64 0, i64 0), i8 1, i8 1) +// CHECK-JIT: call void @protocol_addMethodDescription(%swift.protocol* [[NEW_PROTOCOL]], i8* [[SELECTOR]], i8* getelementptr inbounds ([{{[0-9]+}} x i8], [{{[0-9]+}} x i8]* [[TY_ID]], i64 0, i64 0), {{(i8 1|i1 true)}}, {{(i8 1|i1 true)}}) // -- objectAtIndexedSubscript: // CHECK-JIT: [[SELECTOR:%.+]] = call i8* @sel_registerName(i8* getelementptr inbounds ([{{[0-9]+}} x i8], [{{[0-9]+}} x i8]* @"\01L_selector_data(objectAtIndexedSubscript:)", i64 0, i64 0)) -// CHECK-JIT: call void @protocol_addMethodDescription(%swift.protocol* [[NEW_PROTOCOL]], i8* [[SELECTOR]], i8* getelementptr inbounds ([{{[0-9]+}} x i8], [{{[0-9]+}} x i8]* [[TY_INT_INT]], i64 0, i64 0), i8 1, i8 1) +// CHECK-JIT: call void @protocol_addMethodDescription(%swift.protocol* [[NEW_PROTOCOL]], i8* [[SELECTOR]], i8* getelementptr inbounds ([{{[0-9]+}} x i8], [{{[0-9]+}} x i8]* [[TY_INT_INT]], i64 0, i64 0), {{(i8 1|i1 true)}}, {{(i8 1|i1 true)}}) // -- init // CHECK-JIT: [[SELECTOR:%.+]] = call i8* @sel_registerName(i8* getelementptr inbounds ([{{[0-9]+}} x i8], [{{[0-9]+}} x i8]* @"\01L_selector_data(init)", i64 0, i64 0)) -// CHECK-JIT: call void @protocol_addMethodDescription(%swift.protocol* [[NEW_PROTOCOL]], i8* [[SELECTOR]], i8* getelementptr inbounds ([{{[0-9]+}} x i8], [{{[0-9]+}} x i8]* [[TY_ID]], i64 0, i64 0), i8 1, i8 1) +// CHECK-JIT: call void @protocol_addMethodDescription(%swift.protocol* [[NEW_PROTOCOL]], i8* [[SELECTOR]], i8* getelementptr inbounds ([{{[0-9]+}} x i8], [{{[0-9]+}} x i8]* [[TY_ID]], i64 0, i64 0), {{(i8 1|i1 true)}}, {{(i8 1|i1 true)}}) // CHECK-JIT: call void @objc_registerProtocol(%swift.protocol* [[NEW_PROTOCOL]]) // CHECK-JIT: br label %[[FINISH_LABEL]] diff --git a/test/IRGen/opaque_result_type_availability.swift b/test/IRGen/opaque_result_type_availability.swift index ebbc05a55bfaa..06d7e6d245e82 100644 --- a/test/IRGen/opaque_result_type_availability.swift +++ b/test/IRGen/opaque_result_type_availability.swift @@ -1,5 +1,5 @@ // RUN: %target-swift-frontend -enable-implicit-dynamic -target x86_64-apple-macosx10.9 -Onone -emit-ir %s | %FileCheck --check-prefix=MAYBE-AVAILABLE %s -// RUN: %target-swift-frontend -enable-implicit-dynamic -target x86_64-apple-macosx10.15 -Onone -emit-ir %s | %FileCheck --check-prefix=ALWAYS-AVAILABLE %s +// RUN: %target-swift-frontend -enable-implicit-dynamic -target %target-cpu-apple-macosx10.15 -Onone -emit-ir %s | %FileCheck --check-prefix=ALWAYS-AVAILABLE %s // REQUIRES: OS=macosx protocol P {} diff --git a/test/IRGen/osx-targets.swift b/test/IRGen/osx-targets.swift index deb62e65ff4c3..b967650dc2f9c 100644 --- a/test/IRGen/osx-targets.swift +++ b/test/IRGen/osx-targets.swift @@ -1,13 +1,12 @@ // RUN: %swift %s -emit-ir | %FileCheck %s -// RUN: %swift -target x86_64-apple-macosx10.51 %s -emit-ir | %FileCheck -check-prefix=CHECK-SPECIFIC %s - -// disable this test until macOS 11 support lands in Swift. -// : %swift -target x86_64-apple-darwin55 %s -emit-ir | %FileCheck -check-prefix=CHECK-SPECIFIC %s +// RUN: %swift -target %target-cpu-apple-macosx10.51 %s -emit-ir | %FileCheck -check-prefix=CHECK-SPECIFIC-MAC-10-X %s +// RUN: %swift -target %target-cpu-apple-darwin55 %s -emit-ir | %FileCheck -check-prefix=CHECK-DARWIN-OVER-11 %s // REQUIRES: OS=macosx -// CHECK: target triple = "x86_64-apple-macosx10. -// CHECK-SPECIFIC: target triple = "x86_64-apple-macosx10.51.0" +// CHECK: target triple = "{{.*}}-apple-macosx{{[0-9][0-9]}}. +// CHECK-SPECIFIC-MAC-10-X: target triple = "{{.*}}-apple-macosx10.51.0" +// CHECK-DARWIN-OVER-11: target triple = "{{.*}}-apple-macosx46.0.0" public func anchor() {} anchor() diff --git a/test/IRGen/weak_import_clang.swift b/test/IRGen/weak_import_clang.swift index df29eed02992e..52630b5233810 100644 --- a/test/IRGen/weak_import_clang.swift +++ b/test/IRGen/weak_import_clang.swift @@ -4,8 +4,8 @@ // Specify explicit target triples for the deployment target to test weak // linking for a symbol introduced in OS X 10.51. // -// RUN: %target-swift-frontend(mock-sdk: -target x86_64-apple-macosx10.50 -sdk %S/Inputs -I %t) -primary-file %s -emit-ir | %FileCheck -check-prefix=CHECK-10_50 %s -// RUN: %target-swift-frontend(mock-sdk: -target x86_64-apple-macosx10.51 -sdk %S/Inputs -I %t) -primary-file %s -emit-ir | %FileCheck -check-prefix=CHECK-10_51 %s +// RUN: %target-swift-frontend(mock-sdk: -target %target-cpu-apple-macosx10.50 -sdk %S/Inputs -I %t) -primary-file %s -emit-ir | %FileCheck -check-prefix=CHECK-10_50 %s +// RUN: %target-swift-frontend(mock-sdk: -target %target-cpu-apple-macosx10.51 -sdk %S/Inputs -I %t) -primary-file %s -emit-ir | %FileCheck -check-prefix=CHECK-10_51 %s // REQUIRES: OS=macosx // REQUIRES: objc_interop diff --git a/test/IRGen/weak_import_deployment_target.swift b/test/IRGen/weak_import_deployment_target.swift index cbab1d9dce2ef..b906c7df5383d 100644 --- a/test/IRGen/weak_import_deployment_target.swift +++ b/test/IRGen/weak_import_deployment_target.swift @@ -1,12 +1,12 @@ // RUN: %empty-directory(%t) // -// RUN: %target-swift-frontend -enable-library-evolution -emit-module -target x86_64-apple-macosx10.50 -emit-module-path %t/weak_import_deployment_target_helper.swiftmodule -parse-as-library %S/Inputs/weak_import_deployment_target_helper.swift -// RUN: %target-swift-frontend -primary-file %s -I %t -emit-ir -target x86_64-apple-macosx10.50 | %FileCheck %s --check-prefix=CHECK-OLD -// RUN: %target-swift-frontend -primary-file %s -I %t -emit-ir -target x86_64-apple-macosx10.60 | %FileCheck %s --check-prefix=CHECK-NEW +// RUN: %target-swift-frontend -enable-library-evolution -emit-module -target %target-cpu-apple-macosx10.50 -emit-module-path %t/weak_import_deployment_target_helper.swiftmodule -parse-as-library %S/Inputs/weak_import_deployment_target_helper.swift +// RUN: %target-swift-frontend -primary-file %s -I %t -emit-ir -target %target-cpu-apple-macosx10.50 | %FileCheck %s --check-prefix=CHECK-OLD +// RUN: %target-swift-frontend -primary-file %s -I %t -emit-ir -target %target-cpu-apple-macosx10.60 | %FileCheck %s --check-prefix=CHECK-NEW // -// RUN: %target-swift-frontend -enable-library-evolution -emit-module -target x86_64-apple-macosx10.60 -emit-module-path %t/weak_import_deployment_target_helper.swiftmodule -parse-as-library %S/Inputs/weak_import_deployment_target_helper.swift -// RUN: %target-swift-frontend -primary-file %s -I %t -emit-ir -target x86_64-apple-macosx10.50 | %FileCheck %s --check-prefix=CHECK-OLD -// RUN: %target-swift-frontend -primary-file %s -I %t -emit-ir -target x86_64-apple-macosx10.60 | %FileCheck %s --check-prefix=CHECK-NEW +// RUN: %target-swift-frontend -enable-library-evolution -emit-module -target %target-cpu-apple-macosx10.60 -emit-module-path %t/weak_import_deployment_target_helper.swiftmodule -parse-as-library %S/Inputs/weak_import_deployment_target_helper.swift +// RUN: %target-swift-frontend -primary-file %s -I %t -emit-ir -target %target-cpu-apple-macosx10.50 | %FileCheck %s --check-prefix=CHECK-OLD +// RUN: %target-swift-frontend -primary-file %s -I %t -emit-ir -target %target-cpu-apple-macosx10.60 | %FileCheck %s --check-prefix=CHECK-NEW // // REQUIRES: OS=macosx diff --git a/test/Inputs/clang-importer-sdk/swift-modules/ObjectiveC.swift b/test/Inputs/clang-importer-sdk/swift-modules/ObjectiveC.swift index f56fd986c4460..278fb9d340760 100644 --- a/test/Inputs/clang-importer-sdk/swift-modules/ObjectiveC.swift +++ b/test/Inputs/clang-importer-sdk/swift-modules/ObjectiveC.swift @@ -2,38 +2,33 @@ // The iOS/arm64 target uses _Bool for Objective-C's BOOL. We include // x86_64 here as well because the iOS simulator also uses _Bool. -#if ((os(iOS) || os(tvOS)) && (arch(arm64) || arch(x86_64))) || os(watchOS) public struct ObjCBool { - private var value : Bool +#if (os(macOS) && arch(x86_64)) || (os(iOS) && (arch(i386) || arch(arm) || targetEnvironment(macCatalyst))) + + // On macOS and 32-bit iOS, Objective-C's BOOL type is a "signed char". + private var value: UInt8 public init(_ value: Bool) { - self.value = value + self.value = value ? 1 : 0 } + /// Allow use in a Boolean context. public var boolValue: Bool { - return value + return value != 0 } -} - #else - -public struct ObjCBool { - private var value : UInt8 + // Everywhere else it is C/C++'s "Bool" + private var value: Bool public init(_ value: Bool) { - self.value = value ? 1 : 0 - } - - public init(_ value: UInt8) { self.value = value } public var boolValue: Bool { - if value == 0 { return false } - return true + return value } -} #endif +} extension ObjCBool : ExpressibleByBooleanLiteral { public init(booleanLiteral: Bool) { diff --git a/test/Interpreter/Inputs/availability_host_os.h b/test/Interpreter/Inputs/availability_host_os.h index aaab1ee10f87a..b6fc096f9548c 100644 --- a/test/Interpreter/Inputs/availability_host_os.h +++ b/test/Interpreter/Inputs/availability_host_os.h @@ -2,5 +2,5 @@ static inline int mavericks() { return 9; } __attribute__((availability(macosx,introduced=10.10))) static inline int yosemite() { return 10; } - __attribute__((availability(macosx,introduced=10.99))) + __attribute__((availability(macosx,introduced=99.99))) static inline int todosSantos() { return 99; } diff --git a/test/Interpreter/SDK/interpret_with_options.swift b/test/Interpreter/SDK/interpret_with_options.swift index c427e0b9b4cc5..22e95023c2a8f 100644 --- a/test/Interpreter/SDK/interpret_with_options.swift +++ b/test/Interpreter/SDK/interpret_with_options.swift @@ -5,6 +5,7 @@ // RUN: cd %S && %swift_driver -sdk %sdk -lInputs/libTestLoad.dylib %s | %FileCheck -check-prefix=WITH-LIB %s // REQUIRES: OS=macosx // REQUIRES: executable_test +// REQUIRES: swift_interpreter import ObjectiveC diff --git a/test/Interpreter/availability_host_os.swift b/test/Interpreter/availability_host_os.swift index 17eeffcb79b5a..3078ae252b5c4 100644 --- a/test/Interpreter/availability_host_os.swift +++ b/test/Interpreter/availability_host_os.swift @@ -8,11 +8,12 @@ // REQUIRES: OS=macosx // REQUIRES: executable_test +// REQUIRES: swift_interpreter print(mavericks()) // CHECK: {{^9$}} print(yosemite()) // CHECK-NEXT: {{^10$}} #if FAIL -print(todosSantos()) // expected-error {{'todosSantos()' is only available in macOS 10.99 or newer}} +print(todosSantos()) // expected-error {{'todosSantos()' is only available in macOS 99.99 or newer}} // expected-note@-1 {{add 'if #available' version check}} #endif diff --git a/test/Interpreter/objc_class_properties_runtime.swift b/test/Interpreter/objc_class_properties_runtime.swift index 3cbeee721b554..1d1cf21348c45 100644 --- a/test/Interpreter/objc_class_properties_runtime.swift +++ b/test/Interpreter/objc_class_properties_runtime.swift @@ -1,6 +1,6 @@ // RUN: %empty-directory(%t) -// RUN: %clang -arch x86_64 -mmacosx-version-min=10.11 -isysroot %sdk -fobjc-arc %S/Inputs/ObjCClasses/ObjCClasses.m -c -o %t/ObjCClasses.o +// RUN: %clang -arch %target-cpu -mmacosx-version-min=10.11 -isysroot %sdk -fobjc-arc %S/Inputs/ObjCClasses/ObjCClasses.m -c -o %t/ObjCClasses.o // RUN: %swiftc_driver -target $(echo '%target-triple' | sed -E -e 's/macosx10.(9|10).*/macosx10.11/') -sdk %sdk -I %S/Inputs/ObjCClasses/ %t/ObjCClasses.o %s -o %t/a.out // RUN: %target-run %t/a.out diff --git a/test/ModuleInterface/ModuleCache/module-cache-deployment-target-irrelevant.swift b/test/ModuleInterface/ModuleCache/module-cache-deployment-target-irrelevant.swift index 27aad747e5426..13f132c586477 100644 --- a/test/ModuleInterface/ModuleCache/module-cache-deployment-target-irrelevant.swift +++ b/test/ModuleInterface/ModuleCache/module-cache-deployment-target-irrelevant.swift @@ -10,17 +10,17 @@ // RUN: echo 'import LeafModule' >%t/other.swift // RUN: echo 'public func OtherFunc() -> Int { return LeafFunc(); }' >>%t/other.swift // -// Phase 1: build LeafModule into a .swiftinterface file with -target x86_64-macosx-10.9: +// Phase 1: build LeafModule into a .swiftinterface file with -target %target-cpu-macosx-10.9: // -// RUN: %swift -target x86_64-apple-macosx10.9 -I %t -module-cache-path %t/modulecache -emit-module-interface-path %t/LeafModule.swiftinterface -module-name LeafModule %t/leaf.swift -typecheck +// RUN: %swift -target %target-cpu-apple-macosx10.9 -I %t -module-cache-path %t/modulecache -emit-module-interface-path %t/LeafModule.swiftinterface -module-name LeafModule %t/leaf.swift -typecheck // -// Phase 2: build OtherModule into a .swiftinterface file with -target x86_64-macosx-10.10: +// Phase 2: build OtherModule into a .swiftinterface file with -target %target-cpu-macosx-10.10: // -// RUN: %swift -target x86_64-apple-macosx10.10 -I %t -module-cache-path %t/modulecache -emit-module-interface-path %t/OtherModule.swiftinterface -module-name OtherModule %t/other.swift -typecheck +// RUN: %swift -target %target-cpu-apple-macosx10.10 -I %t -module-cache-path %t/modulecache -emit-module-interface-path %t/OtherModule.swiftinterface -module-name OtherModule %t/other.swift -typecheck // -// Phase 3: build TestModule in -target x86_64-apple-macosx10.11 and import both of these: +// Phase 3: build TestModule in -target %target-cpu-apple-macosx10.11 and import both of these: // -// RUN: %swift -target x86_64-apple-macosx10.11 -I %t -module-cache-path %t/modulecache -module-name TestModule %s -typecheck +// RUN: %swift -target %target-cpu-apple-macosx10.11 -I %t -module-cache-path %t/modulecache -module-name TestModule %s -typecheck // // Phase 4: make sure we only compiled LeafModule and OtherModule one time: // diff --git a/test/ModuleInterface/NoWrongSDKWarning.swiftinterface b/test/ModuleInterface/NoWrongSDKWarning.swiftinterface index 61b7f7fde6708..6918b235f91a4 100644 --- a/test/ModuleInterface/NoWrongSDKWarning.swiftinterface +++ b/test/ModuleInterface/NoWrongSDKWarning.swiftinterface @@ -6,6 +6,7 @@ // RUN: %swift -sdk %sdk -target arm64-apple-ios10 -compile-module-from-interface %s -o %t/NoWrongSDKWarning.swiftmodule 2>&1 | %FileCheck -allow-empty %s // REQUIRES: OS=macosx +// REQUIRES: CPU=x86_64 public func empty() diff --git a/test/PrintAsObjC/availability_macosx_canonical_versions.swift b/test/PrintAsObjC/availability_macosx_canonical_versions.swift new file mode 100644 index 0000000000000..fae1907434932 --- /dev/null +++ b/test/PrintAsObjC/availability_macosx_canonical_versions.swift @@ -0,0 +1,20 @@ +// RUN: %empty-directory(%t) +// RUN: %target-swift-frontend(mock-sdk: %clang-importer-sdk) -emit-module -o %t %s -disable-objc-attr-requires-foundation-module +// RUN: %target-swift-frontend(mock-sdk: %clang-importer-sdk) -parse-as-library %t/availability_macosx_canonical_versions.swiftmodule -typecheck -emit-objc-header-path %t/availability.h -import-objc-header %S/../Inputs/empty.h -disable-objc-attr-requires-foundation-module +// RUN: %FileCheck %s < %t/availability.h +// RUN: %check-in-clang %t/availability.h + +// REQUIRES: objc_interop + +// CHECK-LABEL: @interface Availability{{$}} +// CHECK-NEXT: - (void)alwaysAvailable; +// CHECK-NEXT: - (void)introducedOn10_16 +// CHECK-DAG: SWIFT_AVAILABILITY(macos,introduced=11.0) +// CHECK-DAG: SWIFT_AVAILABILITY(ios,introduced=10.16) + +@objc class Availability { + @objc func alwaysAvailable() {} + @available(macOS 10.16, *) + @available(iOS, introduced: 10.16) + @objc func introducedOn10_16() {} +} diff --git a/test/Runtime/stable-bit-backward-deployment.swift b/test/Runtime/stable-bit-backward-deployment.swift index aa0e7b33dea43..09e18a7432c15 100644 --- a/test/Runtime/stable-bit-backward-deployment.swift +++ b/test/Runtime/stable-bit-backward-deployment.swift @@ -1,7 +1,7 @@ // RUN: %empty-directory(%t) // -- Deployment target is set to pre-10.14.4 so that we use the "old" // Swift runtime bit in compiler-emitted classes -// RUN: %target-build-swift -target x86_64-apple-macosx10.9 %s -module-name main -o %t/a.out +// RUN: %target-build-swift -target %target-cpu-apple-macosx10.9 %s -module-name main -o %t/a.out // RUN: %target-run %t/a.out | %FileCheck %s // REQUIRES: executable_test diff --git a/test/SILGen/availability_attribute.swift b/test/SILGen/availability_attribute.swift index c2bb509828e8c..cceb0ca07da9d 100644 --- a/test/SILGen/availability_attribute.swift +++ b/test/SILGen/availability_attribute.swift @@ -1,6 +1,6 @@ // RUN: %target-swift-emit-silgen %s | %FileCheck %s -// RUN: %target-swift-emit-silgen %s -target x86_64-apple-macosx10.50 | %FileCheck %s -// RUN: %target-swift-emit-silgen %s -target x86_64-apple-macosx10.60 | %FileCheck %s +// RUN: %target-swift-emit-silgen %s -target %target-cpu-apple-macosx10.50 | %FileCheck %s +// RUN: %target-swift-emit-silgen %s -target %target-cpu-apple-macosx10.60 | %FileCheck %s // REQUIRES: OS=macosx // CHECK-LABEL: sil [available 10.50] [ossa] @$s22availability_attribute17availableFunctionyyF : $@convention(thin) () -> () diff --git a/test/SILGen/availability_query.swift b/test/SILGen/availability_query.swift index 5ae132e316ddb..6cae310c96d7b 100644 --- a/test/SILGen/availability_query.swift +++ b/test/SILGen/availability_query.swift @@ -1,5 +1,5 @@ -// RUN: %target-swift-emit-sil %s -target x86_64-apple-macosx10.50 -verify -// RUN: %target-swift-emit-silgen %s -target x86_64-apple-macosx10.50 | %FileCheck %s +// RUN: %target-swift-emit-sil %s -target %target-cpu-apple-macosx10.50 -verify +// RUN: %target-swift-emit-silgen %s -target %target-cpu-apple-macosx10.50 | %FileCheck %s // REQUIRES: OS=macosx diff --git a/test/SILGen/availability_query_maccatalyst_zippered_canonical_versions.swift b/test/SILGen/availability_query_maccatalyst_zippered_canonical_versions.swift new file mode 100644 index 0000000000000..0c68ea7c8b30c --- /dev/null +++ b/test/SILGen/availability_query_maccatalyst_zippered_canonical_versions.swift @@ -0,0 +1,22 @@ +// RUN: %target-swift-emit-silgen %s -target x86_64-apple-macosx10.52 -target-variant x86_64-apple-ios50.0-macabi | %FileCheck %s +// RUN: %target-swift-emit-silgen %s -target x86_64-apple-ios50.0-macabi -target-variant x86_64-apple-macosx10.52 | %FileCheck %s + + +// REQUIRES: maccatalyst_support + +// CHECK-LABEL: sil{{.+}}@main{{.*}} { + + +// Test for the runtime non-canonical version hack for canonical macOS versioning. +// This will eventually change to be the correctly canonicalized version. + +// CHECK: [[MACOS_MAJOR:%.*]] = integer_literal $Builtin.Word, 10 +// CHECK: [[MACOS_MINOR:%.*]] = integer_literal $Builtin.Word, 16 +// CHECK: [[MACOS_PATCH:%.*]] = integer_literal $Builtin.Word, 0 +// CHECK: [[IOS_MAJOR:%.*]] = integer_literal $Builtin.Word, 51 +// CHECK: [[IOS_MINOR:%.*]] = integer_literal $Builtin.Word, 1 +// CHECK: [[IOS_PATCH:%.*]] = integer_literal $Builtin.Word, 2 +// CHECK: [[FUNC:%.*]] = function_ref @$ss042_stdlib_isOSVersionAtLeastOrVariantVersiondE0yBi1_Bw_BwBwBwBwBwtF : $@convention(thin) (Builtin.Word, Builtin.Word, Builtin.Word, Builtin.Word, Builtin.Word, Builtin.Word) -> Builtin.Int1 +// CHECK: [[QUERY_RESULT:%.*]] = apply [[FUNC]]([[MACOS_MAJOR]], [[MACOS_MINOR]], [[MACOS_PATCH]], [[IOS_MAJOR]], [[IOS_MINOR]], [[IOS_PATCH]]) : $@convention(thin) (Builtin.Word, Builtin.Word, Builtin.Word, Builtin.Word, Builtin.Word, Builtin.Word) -> Builtin.Int1 +if #available(OSX 10.16, iOS 51.1.2, *) { +} diff --git a/test/SILGen/availability_query_macosx_canonical_versions.swift b/test/SILGen/availability_query_macosx_canonical_versions.swift new file mode 100644 index 0000000000000..becbe903eb6b1 --- /dev/null +++ b/test/SILGen/availability_query_macosx_canonical_versions.swift @@ -0,0 +1,17 @@ +// RUN: %target-swift-emit-sil %s -target %target-cpu-apple-macosx10.50 -verify +// RUN: %target-swift-emit-silgen %s -target %target-cpu-apple-macosx10.50 | %FileCheck %s + +// REQUIRES: OS=macosx + +// CHECK-LABEL: sil{{.+}}@main{{.*}} { + +// Test for the runtime non-canonical version hack for canonical macOS versioning. +// This will eventually change to be the correctly canonicalized version. + +// CHECK: [[MAJOR:%.*]] = integer_literal $Builtin.Word, 10 +// CHECK: [[MINOR:%.*]] = integer_literal $Builtin.Word, 16 +// CHECK: [[PATCH:%.*]] = integer_literal $Builtin.Word, 0 +// CHECK: [[FUNC:%.*]] = function_ref @$ss26_stdlib_isOSVersionAtLeastyBi1_Bw_BwBwtF : $@convention(thin) (Builtin.Word, Builtin.Word, Builtin.Word) -> Builtin.Int1 +// CHECK: [[QUERY_RESULT:%.*]] = apply [[FUNC]]([[MAJOR]], [[MINOR]], [[PATCH]]) : $@convention(thin) (Builtin.Word, Builtin.Word, Builtin.Word) -> Builtin.Int1 +if #available(OSX 10.16, iOS 7.1, *) { +} \ No newline at end of file diff --git a/test/SILGen/enum_raw_representable_available.swift b/test/SILGen/enum_raw_representable_available.swift index 080112253913e..404684a261fa7 100644 --- a/test/SILGen/enum_raw_representable_available.swift +++ b/test/SILGen/enum_raw_representable_available.swift @@ -1,10 +1,10 @@ -// RUN: %target-typecheck-verify-swift -target x86_64-apple-macosx10.52 +// RUN: %target-typecheck-verify-swift -target %target-cpu-apple-macosx10.52 -// RUN: %target-swift-emit-silgen -target x86_64-apple-macosx10.52 -emit-sorted-sil -o %t.fragile.sil %s +// RUN: %target-swift-emit-silgen -target %target-cpu-apple-macosx10.52 -emit-sorted-sil -o %t.fragile.sil %s // RUN: %FileCheck %s < %t.fragile.sil // RUN: %FileCheck -check-prefix NEGATIVE %s < %t.fragile.sil -// RUN: %target-swift-emit-silgen -target x86_64-apple-macosx10.52 -emit-sorted-sil -enable-library-evolution -o %t.resilient.sil %s +// RUN: %target-swift-emit-silgen -target %target-cpu-apple-macosx10.52 -emit-sorted-sil -enable-library-evolution -o %t.resilient.sil %s // RUN: %FileCheck %s < %t.resilient.sil // RUN: %FileCheck -check-prefix NEGATIVE %s < %t.resilient.sil diff --git a/test/SILOptimizer/specialize_anyobject.swift b/test/SILOptimizer/specialize_anyobject.swift index 31426157e5608..b5c0654720980 100644 --- a/test/SILOptimizer/specialize_anyobject.swift +++ b/test/SILOptimizer/specialize_anyobject.swift @@ -1,4 +1,3 @@ - // RUN: %target-swift-frontend -module-name specialize_anyobject -O -sil-inline-threshold 0 -emit-sil -primary-file %s | %FileCheck %s // rdar://problem/20338028 diff --git a/test/SILOptimizer/specialize_default_witness_ossa.sil b/test/SILOptimizer/specialize_default_witness_ossa.sil new file mode 100644 index 0000000000000..beacfa832a0d8 --- /dev/null +++ b/test/SILOptimizer/specialize_default_witness_ossa.sil @@ -0,0 +1,53 @@ +// RUN: %target-sil-opt -enable-sil-verify-all -sil-generic-specializer-enable-ownership -generic-specializer %s | %FileCheck %s + +sil_stage canonical + +import Builtin +import Swift + +public protocol ResilientProtocol { + func defaultA() + func defaultB() +} + +struct ConformingStruct : ResilientProtocol { + func defaultA() + func defaultB() +} + +// CHECK-LABEL: sil shared [ossa] @$s8defaultA4main16ConformingStructV_Tg5 +// CHECK: bb0(%0 : $ConformingStruct): +// CHECK: [[FN:%.*]] = function_ref @$s8defaultB4main16ConformingStructV_Tg5 +// CHECK: [[RESULT:%.*]] = apply [[FN]] +// CHECK: return [[RESULT]] + +sil [ossa] @defaultA : $@convention(witness_method: ResilientProtocol) (@in_guaranteed Self) -> () { +bb0(%0 : $*Self): + %fn = function_ref @defaultB : $@convention(witness_method: ResilientProtocol) (@in_guaranteed T) -> () + %result = apply %fn(%0) : $@convention(witness_method: ResilientProtocol) (@in_guaranteed T) -> () + return %result : $() +} + +// CHECK-LABEL: sil shared [ossa] @$s8defaultB4main16ConformingStructV_Tg5 +// CHECK: bb0(%0 : $ConformingStruct): +// CHECK: [[RESULT:%.*]] = tuple () +// CHECK: return [[RESULT]] + +sil [ossa] @defaultB : $@convention(witness_method: ResilientProtocol) (@in_guaranteed Self) -> () { +bb0(%0 : $*Self): + %result = tuple () + return %result : $() +} + +// CHECK-LABEL: sil hidden [ossa] @test_specialize_default_witness_method +// CHECK: bb0(%0 : $*ConformingStruct): +// CHECK: [[FN:%.*]] = function_ref @$s8defaultA4main16ConformingStructV_Tg5 +// CHECK: [[RESULT:%.*]] = apply [[FN]] +// CHECK: return [[RESULT]] + +sil hidden [ossa] @test_specialize_default_witness_method : $@convention(thin) (@in_guaranteed ConformingStruct) -> () { +bb0(%0 : $*ConformingStruct): + %fn = function_ref @defaultA : $@convention(witness_method: ResilientProtocol) (@in_guaranteed T) -> () + %result = apply %fn(%0) : $@convention(witness_method: ResilientProtocol) (@in_guaranteed T) -> () + return %result : $() +} diff --git a/test/SILOptimizer/specialize_default_witness_resilience_ossa.sil b/test/SILOptimizer/specialize_default_witness_resilience_ossa.sil new file mode 100644 index 0000000000000..2de2e23b74d55 --- /dev/null +++ b/test/SILOptimizer/specialize_default_witness_resilience_ossa.sil @@ -0,0 +1,101 @@ +// RUN: %target-sil-opt -enable-library-evolution -enable-sil-verify-all -generic-specializer -sil-generic-specializer-enable-ownership %s | %FileCheck %s + +sil_stage canonical + +import Builtin +import Swift + +public protocol ResilientProtocol { + func defaultA() + func defaultB() +} + +public struct ConformingStruct : ResilientProtocol { + public func defaultA() + public func defaultB() +} + +class Klass {} + +// Used to make sure we also handle non-trivial structs correctly. +public struct ConformingNonTrivialStruct : ResilientProtocol { + var k: Klass + + public func defaultA() + public func defaultB() +} + +// CHECK-LABEL: sil shared [ossa] @$s8defaultA4main16ConformingStructV_Tg5 +// CHECK: bb0(%0 : $ConformingStruct): +// CHECK-NEXT: [[TMP:%.*]] = alloc_stack $ConformingStruct +// CHECK-NEXT: store %0 to [trivial] [[TMP]] : $*ConformingStruct +// CHECK: [[FN:%.*]] = function_ref @$s8defaultB4main16ConformingStructV_Tg5 +// CHECK-NEXT: [[LOAD:%.*]] = load [trivial] [[TMP]] : $*ConformingStruct +// CHECK-NEXT: [[RESULT:%.*]] = apply [[FN]]([[LOAD]]) +// CHECK-NEXT: dealloc_stack [[TMP]] : $*ConformingStruct +// CHECK } // end sil function 's8defaultA4main16ConformingStructV_Tg5' + +// CHECK-LABEL: sil shared [ossa] @$s8defaultA4main26ConformingNonTrivialStructV_Tg5 +// CHECK: bb0(%0 : @guaranteed $ConformingNonTrivialStruct): +// CHECK-NEXT: [[TMP:%.*]] = alloc_stack $ConformingNonTrivialStruct +// CHECK-NEXT: store_borrow %0 to [[TMP]] : $*ConformingNonTrivialStruct +// CHECK: [[FN:%.*]] = function_ref @$s8defaultB4main26ConformingNonTrivialStructV_Tg5 +// CHECK-NEXT: [[LOAD:%.*]] = load_borrow [[TMP]] : $*ConformingNonTrivialStruct +// CHECK-NEXT: [[RESULT:%.*]] = apply [[FN]]([[LOAD]]) +// CHECK: dealloc_stack [[TMP]] : $*ConformingNonTrivialStruct +// CHECK } // end sil function 's8defaultA4main16ConformingNonTrivialStructV_Tg5' + +sil [ossa] @defaultA : $@convention(witness_method: ResilientProtocol) (@in_guaranteed Self) -> () { +bb0(%0 : $*Self): + %fn = function_ref @defaultB : $@convention(witness_method: ResilientProtocol) (@in_guaranteed T) -> () + %result = apply %fn(%0) : $@convention(witness_method: ResilientProtocol) (@in_guaranteed T) -> () + return %result : $() +} + +// CHECK-LABEL: sil shared [ossa] @$s8defaultB4main16ConformingStructV_Tg5 : +// CHECK: bb0(%0 : $ConformingStruct): +// CHECK-NEXT: [[TMP:%.*]] = alloc_stack $ConformingStruct +// CHECK-NEXT: store %0 to [trivial] [[TMP]] : $*ConformingStruct +// CHECK: dealloc_stack [[TMP]] : $*ConformingStruct +// CHECK: } // end sil function '$s8defaultB4main16ConformingStructV_Tg5' + +// CHECK-LABEL: sil shared [ossa] @$s8defaultB4main26ConformingNonTrivialStructV_Tg5 : +// CHECK: bb0(%0 : @guaranteed $ConformingNonTrivialStruct): +// CHECK-NEXT: [[TMP:%.*]] = alloc_stack $ConformingNonTrivialStruct +// CHECK-NEXT: store_borrow %0 to [[TMP]] : $*ConformingNonTrivialStruct +// CHECK: dealloc_stack [[TMP]] : $*ConformingNonTrivialStruct +// CHECK: } // end sil function '$s8defaultB4main26ConformingNonTrivialStructV_Tg5' + +sil [ossa] @defaultB : $@convention(witness_method: ResilientProtocol) (@in_guaranteed Self) -> () { +bb0(%0 : $*Self): + %result = tuple () + return %result : $() +} + +// CHECK-LABEL: sil hidden [ossa] @test_specialize_default_witness_method +// CHECK: bb0(%0 : $*ConformingStruct): +// CHECK: [[FN:%.*]] = function_ref @$s8defaultA4main16ConformingStructV_Tg5 +// CHECK-NEXT: [[VALUE:%.*]] = load [trivial] %0 : $*ConformingStruct +// CHECK-NEXT: [[RESULT:%.*]] = apply [[FN]]([[VALUE]]) +// CHECK-NEXT: return [[RESULT]] + +sil hidden [ossa] @test_specialize_default_witness_method : $@convention(thin) (@in_guaranteed ConformingStruct) -> () { +bb0(%0 : $*ConformingStruct): + %fn = function_ref @defaultA : $@convention(witness_method: ResilientProtocol) (@in_guaranteed T) -> () + %result = apply %fn(%0) : $@convention(witness_method: ResilientProtocol) (@in_guaranteed T) -> () + return %result : $() +} + +// CHECK-LABEL: sil hidden [ossa] @test_specialize_default_witness_method_nontrivial +// CHECK: bb0(%0 : $*ConformingNonTrivialStruct): +// CHECK: [[FN:%.*]] = function_ref @$s8defaultA4main26ConformingNonTrivialStructV_Tg5 +// CHECK-NEXT: [[VALUE:%.*]] = load_borrow %0 : $*ConformingNonTrivialStruct +// CHECK-NEXT: [[RESULT:%.*]] = apply [[FN]]([[VALUE]]) +// CHECK: } // end sil function 'test_specialize_default_witness_method_nontrivial' + +sil hidden [ossa] @test_specialize_default_witness_method_nontrivial : $@convention(thin) (@in_guaranteed ConformingNonTrivialStruct) -> () { +bb0(%0 : $*ConformingNonTrivialStruct): + %fn = function_ref @defaultA : $@convention(witness_method: ResilientProtocol) (@in_guaranteed T) -> () + %result = apply %fn(%0) : $@convention(witness_method: ResilientProtocol) (@in_guaranteed T) -> () + return %result : $() +} diff --git a/test/SILOptimizer/specialize_inherited_ossa.sil b/test/SILOptimizer/specialize_inherited_ossa.sil new file mode 100644 index 0000000000000..feafbd1446590 --- /dev/null +++ b/test/SILOptimizer/specialize_inherited_ossa.sil @@ -0,0 +1,71 @@ +// RUN: %target-sil-opt -enable-sil-verify-all -generic-specializer -module-name inherit -sil-generic-specializer-enable-ownership %s | %FileCheck %s + +import Builtin +import Swift + +class MMFont { +} + +class Klass {} + +struct MMStorage { + var k: Klass = Klass() +} + +func ==(lhs: MMObject, rhs: MMObject) -> Bool + +class MMObject : Hashable { + func hash(into hasher: inout Hasher) +} + +class MMString : MMObject { +} + +// CHECK-LABEL: @caller : $@convention(thin) (Int, Int, @owned MMString) -> @owned MMStorage> { +sil [ossa] @caller : $@convention(thin) (Int, Int, @owned MMString) -> @owned MMStorage> { +bb0(%0 : $Int, %1 : $Int, %2 : @owned $MMString): + %3 = metatype $@thin MMStorage>.Type + %13 = function_ref @ext_fn1 : $@convention(thin) (Int, @thin MMStorage>.Type) -> @owned MMStorage> + %14 = apply %13(%0, %3) : $@convention(thin) (Int, @thin MMStorage>.Type) -> @owned MMStorage> + %15 = copy_value %14 : $MMStorage> + + // CHECK: [[STACK:%[0-9]+]] = alloc_stack $MMString + %37 = alloc_stack $MMString + store %2 to [init] %37 : $*MMString + // CHECK: [[ID:%[0-9]+]] = function_ref @$s6callee7inherit8MMStringC_AB6MMFontCSgTg5 : $@convention(method) (@owned MMString, Int, @owned MMStorage>) -> Bool + %34 = function_ref @callee : $@convention(method) <τ_0_0, τ_0_1 where τ_0_0 : Hashable> (@in τ_0_0, Int, @owned MMStorage<τ_0_0, τ_0_1>) -> Bool + // CHECK: [[LOAD:%[0-9]+]] = load [take] [[STACK]] + // CHECK: apply [[ID]]([[LOAD]], %1, %{{[0-9]+}}) : $@convention(method) (@owned MMString, Int, @owned MMStorage>) -> Bool + %45 = apply %34(%37, %1, %14) : $@convention(method) <τ_0_0, τ_0_1 where τ_0_0 : Hashable> (@in τ_0_0, Int, @owned MMStorage<τ_0_0, τ_0_1>) -> Bool + dealloc_stack %37 : $*MMString + + return %15 : $MMStorage> +} + +// CHECK-LABEL: @$s6callee7inherit8MMStringC_AB6MMFontCSgTg5 : $@convention(method) (@owned MMString, Int, @owned MMStorage>) -> Bool { +// CHECK: [[META:%[0-9]+]] = metatype $@thick MMString.Type +// CHECK: [[ID3:%[0-9]+]] = witness_method $MMString, #Equatable."==" : +// CHECK: [[STACK2:%[0-9]+]] = alloc_stack $MMString +// CHECK: [[STACK3:%[0-9]+]] = alloc_stack $MMString +// CHECK: apply [[ID3]]([[STACK2]], [[STACK3]], [[META]]) : $@convention(witness_method: Equatable) <τ_0_0 where τ_0_0 : Equatable> (@in τ_0_0, @in τ_0_0, @thick τ_0_0.Type) -> Bool + +// CHECK-LABEL: @callee : $@convention(method) (@in Key, Int, @owned MMStorage) -> Bool { +sil [noinline] [ossa] @callee : $@convention(method) (@in Key, Int, @owned MMStorage) -> Bool { +bb0(%0 : $*Key, %1 : $Int, %2 : @owned $MMStorage): + %25 = metatype $@thick Key.Type + // CHECK: [[ID2:%[0-9]+]] = witness_method $Key, #Equatable."==" : + %26 = witness_method $Key, #Equatable."==" : $@convention(witness_method: Equatable) <τ_0_0 where τ_0_0 : Equatable> (@in τ_0_0, @in τ_0_0, @thick τ_0_0.Type) -> Bool + %27 = alloc_stack $Key + %33 = alloc_stack $Key + copy_addr %0 to [initialization] %27 : $*Key + copy_addr %0 to [initialization] %33 : $*Key + // CHECK: apply [[ID2]] + %35 = apply %26(%27, %33, %25) : $@convention(witness_method: Equatable) <τ_0_0 where τ_0_0 : Equatable> (@in τ_0_0, @in τ_0_0, @thick τ_0_0.Type) -> Bool + dealloc_stack %33 : $*Key + dealloc_stack %27 : $*Key + destroy_value %2 : $MMStorage + destroy_addr %0 : $*Key + return %35 : $Bool +} + +sil @ext_fn1 : $@convention(thin) (Int, @thin MMStorage>.Type) -> @owned MMStorage> diff --git a/test/SILOptimizer/specialize_opaque_ossa.sil b/test/SILOptimizer/specialize_opaque_ossa.sil new file mode 100644 index 0000000000000..b7eab611c04cd --- /dev/null +++ b/test/SILOptimizer/specialize_opaque_ossa.sil @@ -0,0 +1,45 @@ +// RUN: %target-sil-opt -enable-sil-opaque-values -enable-sil-verify-all -generic-specializer -sil-generic-specializer-enable-ownership %s | %FileCheck %s + +sil_stage canonical + +import Builtin + +// Test that foo is specialized on Builtin.Int64 and the copy_values and destroy_values are dropped. +// +// CHECK-LABEL: sil shared [ossa] @$s3fooBi64__Tg5 : $@convention(thin) (Builtin.Int64, Builtin.Int64) -> () { +// CHECK: bb0(%0 : $Builtin.Int64, %1 : $Builtin.Int64): +// CHECK: [[F:%.*]] = function_ref @$s3fooBi64__Tg5 : $@convention(thin) (Builtin.Int64, Builtin.Int64) -> () +// CHECK: %{{.*}} = apply [[F]](%0, %1) : $@convention(thin) (Builtin.Int64, Builtin.Int64) -> () +// CHECK-NOT: copy_value +// CHECK-NOT: destroy_value +// CHECK: return %{{.*}} : $() +// CHECK: } // end sil function '$s3fooBi64__Tg5' + +// Test that foo when specialized on Builtin.NativeObject, keeps copy_value/etc. +// CHECK-LABEL: sil shared [ossa] @$s3fooBo_Tg5 : $@convention(thin) (@owned Builtin.NativeObject, @owned Builtin.NativeObject) -> () { +// CHECK: copy_value +// CHECK: apply +// CHECK: destroy_value +// CHECK: } // end sil function '$s3fooBo_Tg5' + +sil hidden [ossa] @foo : $@convention(thin) (@in T, @in T) -> () { +bb0(%0 : @owned $T, %1 : @owned $T): + %f = function_ref @foo : $@convention(thin) <τ_0_0> (@in τ_0_0, @in τ_0_0) -> () + %cp0 = copy_value %0 : $T + %cp1 = copy_value %1 : $T + %call = apply %f(%cp0, %cp1) : $@convention(thin) <τ_0_0> (@in τ_0_0, @in τ_0_0) -> () + destroy_value %1 : $T + destroy_value %0 : $T + %10 = tuple () + return %10 : $() +} + +sil [ossa] @testSpecialize : $@convention(thin) (Builtin.Int64, @owned Builtin.NativeObject) -> () { +bb0(%0 : $Builtin.Int64, %1 : @owned $Builtin.NativeObject): + %f = function_ref @foo : $@convention(thin) (@in T, @in T) -> () + %call = apply %f(%0, %0) : $@convention(thin) <τ_0_0> (@in τ_0_0, @in τ_0_0) -> () + %1a = copy_value %1 : $Builtin.NativeObject + %call2 = apply %f(%1, %1a) : $@convention(thin) <τ_0_0> (@in τ_0_0, @in τ_0_0) -> () + %999 = tuple () + return %999 : $() +} diff --git a/test/SILOptimizer/specialize_opaque_result_types_ossa.sil b/test/SILOptimizer/specialize_opaque_result_types_ossa.sil new file mode 100644 index 0000000000000..1ead1ab5274b6 --- /dev/null +++ b/test/SILOptimizer/specialize_opaque_result_types_ossa.sil @@ -0,0 +1,74 @@ +// RUN: %empty-directory(%t) +// RUN: %target-swift-frontend -disable-availability-checking %S/Inputs/opaque_result_types.swift -module-name External -emit-module -emit-module-path %t/External.swiftmodule +// RUN: %target-sil-opt -I %t -enable-sil-verify-all %s -generic-specializer -sil-generic-specializer-enable-ownership | %FileCheck %s + +// REQUIRES: CPU=x86_64 + +import Builtin +import Swift +import SwiftShims +import External + +sil_stage canonical + +sil @project : $@convention(thin) (@in Test) -> @out IndexingIterator + +sil shared [ossa] @test : $@convention(thin) (@owned Test) -> () { +bb0(%0 : @owned $Test): + %3 = alloc_stack $Test + store %0 to [init] %3 : $*Test + %5 = alloc_stack $IndexingIterator + %6 = function_ref @project : $@convention(thin) (@in Test) -> @out IndexingIterator + %7 = apply %6(%5, %3) : $@convention(thin) (@in Test) -> @out IndexingIterator + %44 = alloc_stack $Optional + // function_ref protocol witness for IteratorProtocol.next() in conformance IndexingIterator + %45 = function_ref @next : $@convention(witness_method: IteratorProtocol) <τ_0_0 where τ_0_0 : Collection> (@inout IndexingIterator<τ_0_0>) -> @out Optional<τ_0_0.Element> + %46 = apply %45(%44, %5) : $@convention(witness_method: IteratorProtocol) <τ_0_0 where τ_0_0 : Collection> (@inout IndexingIterator<τ_0_0>) -> @out Optional<τ_0_0.Element> + destroy_addr %44: $*Optional + dealloc_stack %44 : $*Optional + destroy_addr %5: $*IndexingIterator + dealloc_stack %5 : $*IndexingIterator + dealloc_stack %3 : $*Test + %41 = tuple () + return %41 : $() +} +// CHECK-LABEL: sil shared [ossa] @$s4next8External4TestV_Tg5 : $@convention(witness_method: IteratorProtocol) (@inout IndexingIterator) -> Optional +// CHECK: bb0(%0 : $*IndexingIterator): +// CHECK: alloc_stack $Optional +// CHECK: ([[RES:%.*]], %{{.*}}) = begin_apply {{.*}}({{.*}}) : $@yield_once @convention(witness_method: Collection) <τ_0_0 where τ_0_0 : Collection> (@in_guaranteed τ_0_0.Index, @in_guaranteed τ_0_0) -> @yields @in_guaranteed τ_0_0.Element +// CHECK: [[DEST:%.*]] = init_enum_data_addr %1 : $*Optional, #Optional.some!enumelt +// CHECK: copy_addr [[RES]] to [initialization] {{.*}} : $*Int64 +// CHECK: } // end sil function '$s4next8External4TestV_Tg5' +sil [ossa] @next : $@convention(witness_method: IteratorProtocol) <τ_0_0 where τ_0_0 : Collection> (@inout IndexingIterator<τ_0_0>) -> @out Optional<τ_0_0.Element> { +bb0(%0 : $*Optional<τ_0_0.Element>, %1 : $*IndexingIterator<τ_0_0>): + %2 = metatype $@thick τ_0_0.Index.Type + %3 = struct_element_addr %1 : $*IndexingIterator<τ_0_0>, #IndexingIterator._position + %4 = alloc_stack $τ_0_0.Index + copy_addr %3 to [initialization] %4 : $*τ_0_0.Index + %6 = struct_element_addr %1 : $*IndexingIterator<τ_0_0>, #IndexingIterator._elements + %20 = alloc_stack $τ_0_0 + copy_addr %6 to [initialization] %20 : $*τ_0_0 + %22 = alloc_stack $τ_0_0.Index + copy_addr %3 to [initialization] %22 : $*τ_0_0.Index + %24 = alloc_stack $τ_0_0 + copy_addr [take] %20 to [initialization] %24 : $*τ_0_0 + %26 = witness_method $τ_0_0, #Collection.subscript!read : (Self) -> (Self.Index) -> () : $@yield_once @convention(witness_method: Collection) <τ_0_0 where τ_0_0 : Collection> (@in_guaranteed τ_0_0.Index, @in_guaranteed τ_0_0) -> @yields @in_guaranteed τ_0_0.Element + + // The specialized begin apply %26 has a result type of t_0_0.Element + // which works out to be an opaque result type whose underlying type is Int64. + // Make sure that the specialized code handles this correctly. + (%27, %28) = begin_apply %26<τ_0_0>(%22, %24) : $@yield_once @convention(witness_method: Collection) <τ_0_0 where τ_0_0 : Collection> (@in_guaranteed τ_0_0.Index, @in_guaranteed τ_0_0) -> @yields @in_guaranteed τ_0_0.Element + + %29 = init_enum_data_addr %0 : $*Optional<τ_0_0.Element>, #Optional.some!enumelt + copy_addr %27 to [initialization] %29 : $*τ_0_0.Element + end_apply %28 + destroy_addr %22 : $*τ_0_0.Index + destroy_addr %24 : $*τ_0_0 + dealloc_stack %24 : $*τ_0_0 + dealloc_stack %22 : $*τ_0_0.Index + dealloc_stack %20 : $*τ_0_0 + destroy_addr %4 : $*τ_0_0.Index + dealloc_stack %4 : $*τ_0_0.Index + %41 = tuple () + return %41 : $() +} diff --git a/test/SILOptimizer/specialize_ossa.sil b/test/SILOptimizer/specialize_ossa.sil index b76d6621600fa..45714dcc4f9f5 100644 --- a/test/SILOptimizer/specialize_ossa.sil +++ b/test/SILOptimizer/specialize_ossa.sil @@ -1,10 +1,12 @@ -// RUN: %target-sil-opt -enable-sil-verify-all -generic-specializer %/s | %FileCheck %s +// RUN: %target-sil-opt -enable-sil-verify-all -sil-partial-specialization -generic-specializer -sil-generic-specializer-enable-ownership %s | %FileCheck %s sil_stage canonical import Builtin import Swift +class Klass {} + sil [ossa] [transparent] @ossaTransparentCallee : $@convention(thin) (@in T) -> () { bb0(%0 : $*T): destroy_addr %0 : $*T @@ -12,9 +14,12 @@ bb0(%0 : $*T): return %9999 : $() } +// We specialize this case today and just respect the already set ownership in +// each function. This makes sense since ossa can be specialized. +// // CHECK-LABEL: sil @caller : $@convention(thin) (@owned Builtin.NativeObject) -> () { -// CHECK: [[FUNC:%.*]] = function_ref @ossaTransparentCallee : $@convention(thin) <τ_0_0> (@in τ_0_0) -> () -// CHECK: apply [[FUNC]]( +// CHECK: [[FUNC:%.*]] = function_ref @$s21ossaTransparentCalleeBo_Tg5 : $@convention(thin) (@owned Builtin.NativeObject) -> () +// CHECK: apply [[FUNC]]( // CHECK: } // end sil function 'caller' sil @caller : $@convention(thin) (@owned Builtin.NativeObject) -> () { bb0(%0 : $Builtin.NativeObject): @@ -26,3 +31,1222 @@ bb0(%0 : $Builtin.NativeObject): %9999 = tuple() return %9999 : $() } + +// CHECK-LABEL: sil [ossa] @exp1 : $@convention(thin) () -> () { +// CHECK-NOT: apply +// Call of specialized initializer: +// CHECK: [[CTOR:%[0-9]+]] = function_ref @$s8XXX_inits5Int32V_Tg5 +// CHECK: apply [[CTOR]] +// CHECK: [[ACCEPTS_INT:%[0-9]+]] = function_ref @acceptsInt +// Call of specialized XXX_foo: +// CHECK: [[FOO:%[0-9]+]] = function_ref @$s7XXX_foos5Int32V_Tg5 +// CHECK: apply [[FOO]] +// CHECK: apply [[ACCEPTS_INT]] +// CHECK: return +// CHECK: } // end sil function 'exp1' + +// CHECK: sil [ossa] @exp2 : $@convention(thin) () -> () { +// CHECK: } // end sil function 'exp2' + +struct XXX { + init(t: T) + mutating func foo(t: T) -> Int32 + var m_t: T +} + +// specialize.XXX.init (specialize.XXX.Type)(t : A) -> specialize.XXX +sil [ossa] [noinline] @XXX_init : $@convention(thin) (@in T, @thin XXX.Type) -> @out XXX { +bb0(%0 : $*XXX, %1 : $*T, %2 : $@thin XXX.Type): + %3 = alloc_stack $XXX, var, name "sf" // users: %7, %11, %13 + debug_value_addr %1 : $*T, let, name "t" // id: %4 + %5 = alloc_stack $T // users: %6, %8, %9 + copy_addr %1 to [initialization] %5 : $*T // id: %6 + %7 = struct_element_addr %3 : $*XXX, #XXX.m_t // user: %8 + copy_addr [take] %5 to [initialization] %7 : $*T // id: %8 + dealloc_stack %5 : $*T // id: %9 + destroy_addr %1 : $*T // id: %10 + copy_addr [take] %3 to [initialization] %0 : $*XXX // id: %11 + %12 = tuple () // user: %14 + dealloc_stack %3 : $*XXX // id: %13 + return %12 : $() // id: %14 +} + +// specialize.XXX.foo (@inout specialize.XXX)(t : A) -> Swift.Int32 +sil [ossa] [noinline] @XXX_foo : $@convention(method) (@in T, @inout XXX) -> Int32 { +bb0(%0 : $*T, %1 : $*XXX): + debug_value_addr %0 : $*T, let, name "t" // id: %2 + %3 = alloc_stack $T // users: %4, %6, %7 + copy_addr %0 to [initialization] %3 : $*T // id: %4 + %5 = struct_element_addr %1 : $*XXX, #XXX.m_t // user: %6 + copy_addr [take] %3 to %5 : $*T // id: %6 + dealloc_stack %3 : $*T // id: %7 + %8 = integer_literal $Builtin.Int32, 4 // user: %9 + %9 = struct $Int32 (%8 : $Builtin.Int32) // user: %11 + destroy_addr %0 : $*T // id: %10 + return %9 : $Int32 // id: %11 +} + +sil [ossa] [noinline] @XXX_init_guaranteed : $@convention(thin) (@in_guaranteed T, @thin XXX.Type) -> @out XXX { +bb0(%0 : $*XXX, %1 : $*T, %2 : $@thin XXX.Type): + %3 = alloc_stack $XXX, var, name "sf" // users: %7, %11, %13 + debug_value_addr %1 : $*T, let, name "t" // id: %4 + %5 = alloc_stack $T // users: %6, %8, %9 + copy_addr %1 to [initialization] %5 : $*T // id: %6 + %7 = struct_element_addr %3 : $*XXX, #XXX.m_t // user: %8 + copy_addr [take] %5 to [initialization] %7 : $*T // id: %8 + dealloc_stack %5 : $*T // id: %9 + copy_addr [take] %3 to [initialization] %0 : $*XXX // id: %11 + %12 = tuple () // user: %14 + dealloc_stack %3 : $*XXX // id: %13 + return %12 : $() // id: %14 +} + +// specialize.XXX.foo (@inout specialize.XXX)(t : A) -> Swift.Int32 +sil [ossa] [noinline] @XXX_foo_guaranteed : $@convention(method) (@in_guaranteed T, @inout XXX) -> Int32 { +bb0(%0 : $*T, %1 : $*XXX): + debug_value_addr %0 : $*T, let, name "t" // id: %2 + %3 = alloc_stack $T // users: %4, %6, %7 + copy_addr %0 to [initialization] %3 : $*T // id: %4 + %5 = struct_element_addr %1 : $*XXX, #XXX.m_t // user: %6 + copy_addr [take] %3 to %5 : $*T // id: %6 + dealloc_stack %3 : $*T // id: %7 + %8 = integer_literal $Builtin.Int32, 4 // user: %9 + %9 = struct $Int32 (%8 : $Builtin.Int32) // user: %11 + return %9 : $Int32 // id: %11 +} + +// Swift.Int32._convertFromBuiltinIntegerLiteral (Swift.Int32.Type)(Builtin.IntLiteral) -> Swift.Int32 +sil public_external [ossa] [transparent] @$sSi33_convertFromBuiltinIntegerLiteralySiBI_cSimF : $@convention(thin) (Builtin.IntLiteral, @thin Int32.Type) -> Int32 { +bb0(%0 : $Builtin.IntLiteral, %1 : $@thin Int32.Type): + %3 = builtin "s_to_s_checked_trunc_IntLiteral_Int32"(%0 : $Builtin.IntLiteral) : $(Builtin.Int32, Builtin.Int1) + %4 = tuple_extract %3 : $(Builtin.Int32, Builtin.Int1), 0 // user: %5 + %5 = struct $Int32 (%4 : $Builtin.Int32) // user: %6 + return %5 : $Int32 // id: %6 +} + +// specialize.acceptsInt (Swift.Int32) -> () +sil [noinline] [ossa] @acceptsInt : $@convention(thin) (Int32) -> () { +bb0(%0 : $Int32): + debug_value %0 : $Int32, let, name "x" // id: %1 + %2 = tuple () // user: %3 + return %2 : $() // id: %3 +} + +// specialize.exp1 () -> () +sil [ossa] @exp1 : $@convention(thin) () -> () { +bb0: + %0 = alloc_stack $XXX, var, name "II" // users: %7, %15, %19 + // function_ref specialize.XXX.init (specialize.XXX.Type)(t : A) -> specialize.XXX + %1 = function_ref @XXX_init : $@convention(thin) <τ_0_0> (@in τ_0_0, @thin XXX<τ_0_0>.Type) -> @out XXX<τ_0_0> // user: %7 + %2 = metatype $@thin XXX.Type // user: %7 + %3 = alloc_stack $Int32 // users: %6, %7, %8 + %4 = integer_literal $Builtin.Int32, 5 // user: %5 + %5 = struct $Int32 (%4 : $Builtin.Int32) // user: %6 + store %5 to [trivial] %3 : $*Int32 // id: %6 + %7 = apply %1(%0, %3, %2) : $@convention(thin) <τ_0_0> (@in τ_0_0, @thin XXX<τ_0_0>.Type) -> @out XXX<τ_0_0> + dealloc_stack %3 : $*Int32 // id: %8 + // function_ref specialize.acceptsInt (Swift.Int32) -> () + %9 = function_ref @acceptsInt : $@convention(thin) (Int32) -> () // user: %16 + // function_ref specialize.XXX.foo (@inout specialize.XXX)(t : A) -> Swift.Int32 + %10 = function_ref @XXX_foo : $@convention(method) <τ_0_0> (@in τ_0_0, @inout XXX<τ_0_0>) -> Int32 // user: %15 + %11 = alloc_stack $Int32 // users: %14, %15, %17 + %12 = integer_literal $Builtin.Int32, 4 // user: %13 + %13 = struct $Int32 (%12 : $Builtin.Int32) // user: %14 + store %13 to [trivial] %11 : $*Int32 // id: %14 + %15 = apply %10(%11, %0) : $@convention(method) <τ_0_0> (@in τ_0_0, @inout XXX<τ_0_0>) -> Int32 // user: %16 + %16 = apply %9(%15) : $@convention(thin) (Int32) -> () + dealloc_stack %11 : $*Int32 // id: %17 + %18 = tuple () // user: %20 + dealloc_stack %0 : $*XXX // id: %19 + return %18 : $() // id: %20 +} + +// specialize.exp2 () -> () +sil [ossa] @exp2 : $@convention(thin) () -> () { +bb0: + %0 = alloc_stack $XXX, var, name "I8" // users: %7, %15, %19 + // function_ref specialize.XXX.init (specialize.XXX.Type)(t : A) -> specialize.XXX + %1 = function_ref @XXX_init : $@convention(thin) <τ_0_0> (@in τ_0_0, @thin XXX<τ_0_0>.Type) -> @out XXX<τ_0_0> // user: %7 + %2 = metatype $@thin XXX.Type // user: %7 + %3 = alloc_stack $UInt8 // users: %6, %7, %8 + %4 = integer_literal $Builtin.Int8, 5 // user: %5 + %5 = struct $UInt8 (%4 : $Builtin.Int8) // user: %6 + store %5 to [trivial] %3 : $*UInt8 // id: %6 + %7 = apply %1(%0, %3, %2) : $@convention(thin) <τ_0_0> (@in τ_0_0, @thin XXX<τ_0_0>.Type) -> @out XXX<τ_0_0> + dealloc_stack %3 : $*UInt8 // id: %8 + // function_ref specialize.acceptsInt (Swift.Int32) -> () + %9 = function_ref @acceptsInt : $@convention(thin) (Int32) -> () // user: %16 + // function_ref specialize.XXX.foo (@inout specialize.XXX)(t : A) -> Swift.Int32 + %10 = function_ref @XXX_foo : $@convention(method) <τ_0_0> (@in τ_0_0, @inout XXX<τ_0_0>) -> Int32 // user: %15 + %11 = alloc_stack $UInt8 // users: %14, %15, %17 + %12 = integer_literal $Builtin.Int8, 4 // user: %13 + %13 = struct $UInt8 (%12 : $Builtin.Int8) // user: %14 + store %13 to [trivial] %11 : $*UInt8 // id: %14 + %15 = apply %10(%11, %0) : $@convention(method) <τ_0_0> (@in τ_0_0, @inout XXX<τ_0_0>) -> Int32 // user: %16 + %16 = apply %9(%15) : $@convention(thin) (Int32) -> () + dealloc_stack %11 : $*UInt8 // id: %17 + %18 = tuple () // user: %20 + dealloc_stack %0 : $*XXX // id: %19 + return %18 : $() // id: %20 +} + +sil [ossa] @exp2_nativeObject : $@convention(thin) (@guaranteed Builtin.NativeObject) -> () { +bb0(%arg : @guaranteed $Builtin.NativeObject): + %0 = alloc_stack $XXX + // function_ref specialize.XXX.init (specialize.XXX.Type)(t : A) -> specialize.XXX + %1 = function_ref @XXX_init : $@convention(thin) <τ_0_0> (@in τ_0_0, @thin XXX<τ_0_0>.Type) -> @out XXX<τ_0_0> // user: %7 + %2 = metatype $@thin XXX.Type // user: %7 + %3 = alloc_stack $Builtin.NativeObject // users: %6, %7, %8 + %arg1 = copy_value %arg : $Builtin.NativeObject + store %arg1 to [init] %3 : $*Builtin.NativeObject // id: %6 + %7 = apply %1(%0, %3, %2) : $@convention(thin) <τ_0_0> (@in τ_0_0, @thin XXX<τ_0_0>.Type) -> @out XXX<τ_0_0> + dealloc_stack %3 : $*Builtin.NativeObject // id: %8 + + %1g = function_ref @XXX_init_guaranteed : $@convention(thin) <τ_0_0> (@in_guaranteed τ_0_0, @thin XXX<τ_0_0>.Type) -> @out XXX<τ_0_0> + %3g = alloc_stack $Builtin.NativeObject // users: %6, %7, %8 + %3g_out = alloc_stack $XXX // users: %6, %7, %8 + %arg1g = copy_value %arg : $Builtin.NativeObject + store %arg1g to [init] %3g : $*Builtin.NativeObject // id: %6 + %7g = apply %1(%3g_out, %3g, %2) : $@convention(thin) <τ_0_0> (@in τ_0_0, @thin XXX<τ_0_0>.Type) -> @out XXX<τ_0_0> + destroy_addr %3g_out : $*XXX + dealloc_stack %3g_out : $*XXX + dealloc_stack %3g : $*Builtin.NativeObject // id: %8 + + // function_ref specialize.acceptsInt (Swift.Int32) -> () + %9 = function_ref @acceptsInt : $@convention(thin) (Int32) -> () // user: %16 + // function_ref specialize.XXX.foo (@inout specialize.XXX)(t : A) -> Swift.Int32 + %10 = function_ref @XXX_foo : $@convention(method) <τ_0_0> (@in τ_0_0, @inout XXX<τ_0_0>) -> Int32 // user: %15 + %11 = alloc_stack $Builtin.NativeObject // users: %14, %15, %17 + %arg2 = copy_value %arg : $Builtin.NativeObject + store %arg2 to [init] %11 : $*Builtin.NativeObject + %15 = apply %10(%11, %0) : $@convention(method) <τ_0_0> (@in τ_0_0, @inout XXX<τ_0_0>) -> Int32 // user: %16 + %16 = apply %9(%15) : $@convention(thin) (Int32) -> () + dealloc_stack %11 : $*Builtin.NativeObject // id: %17 + + %10g = function_ref @XXX_foo_guaranteed : $@convention(method) <τ_0_0> (@in_guaranteed τ_0_0, @inout XXX<τ_0_0>) -> Int32 // user: %15 + %11g = alloc_stack $Builtin.NativeObject // users: %14, %15, %17 + %arg2g = copy_value %arg : $Builtin.NativeObject + store %arg2g to [init] %11g : $*Builtin.NativeObject + %15g = apply %10g(%11g, %0) : $@convention(method) <τ_0_0> (@in_guaranteed τ_0_0, @inout XXX<τ_0_0>) -> Int32 // user: %16 + apply %9(%15g) : $@convention(thin) (Int32) -> () + destroy_addr %11g : $*Builtin.NativeObject + dealloc_stack %11g : $*Builtin.NativeObject // id: %17 + destroy_addr %0 : $*XXX + dealloc_stack %0 : $*XXX // id: %19 + %18 = tuple () // user: %20 + return %18 : $() // id: %20 +} + +// specialize.useClosure (fun : () -> A) -> A +sil [ossa] @useClosure : $@convention(thin) (@owned @callee_owned () -> @out T) -> @out T { +bb0(%0 : $*T, %1 : @owned $@callee_owned () -> @out T): + debug_value %1 : $@callee_owned () -> @out T, let, name "fun" // id: %2 + %2 = copy_value %1 : $@callee_owned () -> @out T // id: %3 + %4 = apply %2(%0) : $@callee_owned () -> @out T + destroy_value %1 : $@callee_owned () -> @out T // id: %5 + %6 = tuple () // user: %7 + return %6 : $() // id: %7 +} + +// specialize.getGenericClosure (t : A) -> () -> A +sil [ossa] @getGenericClosure : $@convention(thin) (@in T) -> @owned @callee_owned () -> @out T { +bb0(%0 : $*T): + debug_value_addr %0 : $*T, let, name "t" // id: %1 + // function_ref specialize.(getGenericClosure (t : A) -> () -> A).(tmp #1) (())A + %2 = function_ref @getGenericClosure_closure : $@convention(thin) <τ_0_0> (@owned <τ_0_0> { var τ_0_0 } <τ_0_0>) -> @out τ_0_0 // user: %5 + %3 = alloc_box $<τ_0_0> { var τ_0_0 } + %3b = begin_borrow %3 : $<τ_0_0> { var τ_0_0 } + %3a = project_box %3b : $<τ_0_0> { var τ_0_0 } , 0 + copy_addr %0 to [initialization] %3a : $*T // id: %4 + end_borrow %3b : $<τ_0_0> { var τ_0_0 } + %5 = partial_apply %2(%3) : $@convention(thin) <τ_0_0> (@owned <τ_0_0> { var τ_0_0 } <τ_0_0>) -> @out τ_0_0 // user: %7 + destroy_addr %0 : $*T // id: %6 + return %5 : $@callee_owned () -> @out T // id: %7 +} + +// specialize.(getGenericClosure (t : A) -> () -> A).(tmp #1) (()) +sil shared [ossa] @getGenericClosure_closure : $@convention(thin) (@owned <τ_0_0> { var τ_0_0 } ) -> @out T { +bb0(%0 : $*T, %1 : @owned $<τ_0_0> { var τ_0_0 } ): + %1a = begin_borrow %1 : $<τ_0_0> { var τ_0_0 } + %2 = project_box %1a : $<τ_0_0> { var τ_0_0 } , 0 + copy_addr %2 to [initialization] %0 : $*T // id: %3 + end_borrow %1a : $<τ_0_0> { var τ_0_0 } + destroy_value %1 : $<τ_0_0> { var τ_0_0 } // id: %4 + %5 = tuple () // user: %6 + return %5 : $() // id: %6 +} + +// specialize.specializePartialApplies () -> Swift.UInt8 +sil [ossa] @specializePartialApplies : $@convention(thin) () -> UInt8 { +bb0: + %0 = alloc_stack $UInt8, var, name "i" // users: %3, %18 + %1 = integer_literal $Builtin.Int8, 5 // user: %2 + %2 = struct $UInt8 (%1 : $Builtin.Int8) // users: %3, %7 + store %2 to [trivial] %0 : $*UInt8 // id: %3 + // function_ref specialize.useClosure (fun : () -> A) -> A + %4 = function_ref @useClosure : $@convention(thin) <τ_0_0> (@owned @callee_owned () -> @out τ_0_0) -> @out τ_0_0 // user: %14 + // function_ref specialize.getGenericClosure (t : A) -> () -> A + %5 = function_ref @getGenericClosure : $@convention(thin) <τ_0_0> (@in τ_0_0) -> @owned @callee_owned () -> @out τ_0_0 // user: %8 + %6 = alloc_stack $UInt8 // users: %7, %8, %17 + store %2 to [trivial] %6 : $*UInt8 // id: %7 + %8 = apply %5(%6) : $@convention(thin) <τ_0_0> (@in τ_0_0) -> @owned @callee_owned () -> @out τ_0_0 // user: %10 + // function_ref reabstraction thunk helper from @callee_owned () -> (@out Swift.UInt8) to @callee_owned () -> (@unowned Swift.UInt8) + %9 = function_ref @$ss5UInt8VIxr_ABIxd_TR : $@convention(thin) (@owned @callee_owned () -> @out UInt8) -> UInt8 // user: %10 + %10 = partial_apply %9(%8) : $@convention(thin) (@owned @callee_owned () -> @out UInt8) -> UInt8 // user: %12 + // function_ref reabstraction thunk helper from @callee_owned () -> (@unowned Swift.UInt8) to @callee_owned () -> (@out Swift.UInt8) + %11 = function_ref @$ss5UInt8VIxd_ABIxr_TR : $@convention(thin) (@owned @callee_owned () -> UInt8) -> @out UInt8 // user: %12 + %12 = partial_apply %11(%10) : $@convention(thin) (@owned @callee_owned () -> UInt8) -> @out UInt8 // user: %14 + %13 = alloc_stack $UInt8 // users: %14, %15, %16 + %14 = apply %4(%13, %12) : $@convention(thin) <τ_0_0> (@owned @callee_owned () -> @out τ_0_0) -> @out τ_0_0 + %15 = load [trivial] %13 : $*UInt8 // user: %19 + dealloc_stack %13 : $*UInt8 // id: %16 + dealloc_stack %6 : $*UInt8 // id: %17 + dealloc_stack %0 : $*UInt8 // id: %18 + return %15 : $UInt8 // id: %19 +} + +// reabstraction thunk helper from @callee_owned () -> (@out Swift.UInt8) to @callee_owned () -> (@unowned Swift.UInt8) +sil shared [ossa] [transparent] @$ss5UInt8VIxr_ABIxd_TR : $@convention(thin) (@owned @callee_owned () -> @out UInt8) -> UInt8 { +bb0(%0 : @owned $@callee_owned () -> @out UInt8): + %1 = alloc_stack $UInt8 // users: %2, %3, %4 + %2 = apply %0(%1) : $@callee_owned () -> @out UInt8 + %3 = load [trivial] %1 : $*UInt8 // user: %5 + dealloc_stack %1 : $*UInt8 // id: %4 + return %3 : $UInt8 // id: %5 +} + +// reabstraction thunk helper from @callee_owned () -> (@unowned Swift.UInt8) to @callee_owned () -> (@out Swift.UInt8) +sil shared [ossa] [transparent] @$ss5UInt8VIxd_ABIxr_TR : $@convention(thin) (@owned @callee_owned () -> UInt8) -> @out UInt8 { +bb0(%0 : $*UInt8, %1 : @owned $@callee_owned () -> UInt8): + %2 = apply %1() : $@callee_owned () -> UInt8 // user: %3 + store %2 to [trivial] %0 : $*UInt8 // id: %3 + %4 = tuple () // user: %5 + return %4 : $() // id: %5 +} + + +class Base { +} +sil_vtable Base { +} + +sil [ossa] @generic_upcast : $@convention(thin) (@owned T) -> @owned Base { +bb0(%0 : @owned $T): + %2 = upcast %0 : $T to $Base + return %2 : $Base +} + +sil [ossa] @specialize_generic_upcast : $@convention(thin)(@owned Base) -> @owned Base { +bb0(%0 : @owned $Base): + %1 = function_ref @generic_upcast : $@convention(thin) (@owned T) -> @owned Base + %2 = apply %1(%0) : $@convention(thin) (@owned T) -> @owned Base + return %2 : $Base +} + +// CHECK-LABEL: sil shared [ossa] @{{.*}}generic_upcast{{.*}}Tg5 : $@convention(thin) (@owned Base) -> @owned Base { +// CHECK: bb0(%0 : @owned $Base): +// CHECK: return %0 : $Base + +// Check generic specialization of partial_apply + +protocol P { func get() -> Int32 } + +struct C : P { func get() -> Int32 } + +// test4.C.get (test4.C)() -> Swift.Int32 +sil hidden [ossa] @C_get : $@convention(method) (C) -> Int32 { +bb0(%0 : $C): + debug_value %0 : $C, let, name "self" // id: %1 + %2 = integer_literal $Builtin.Int32, 1 // user: %3 + %3 = struct $Int32 (%2 : $Builtin.Int32) // user: %4 + return %3 : $Int32 // id: %4 +} + +// test4.C.init (test4.C.Type)() -> test4.C +sil hidden [ossa][noinline] @C_init : $@convention(thin) (@thin C.Type) -> C { +bb0(%0 : $@thin C.Type): + %1 = alloc_stack $C, var, name "sf" // user: %3 + %2 = struct $C () // user: %4 + dealloc_stack %1 : $*C // id: %3 + return %2 : $C // id: %4 +} + +// protocol witness for test4.P.get (test4.P.Self)() -> Swift.Int32 in conformance test4.C : test4.P in test4 +sil hidden [ossa] [transparent] [thunk] @test4_P_get_witness_C : $@convention(witness_method: P) (@in_guaranteed C) -> Int32 { +bb0(%0 : $*C): + %1 = load [trivial] %0 : $*C // user: %3 + // function_ref test4.C.get (test4.C)() -> Swift.Int32 + %2 = function_ref @C_get : $@convention(method) (C) -> Int32 // user: %3 + %3 = apply %2(%1) : $@convention(method) (C) -> Int32 // user: %4 + return %3 : $Int32 // id: %4 +} + +// test4.boo (A) -> (Swift.Int32, B) -> Swift.Int32 +sil hidden [ossa] [noinline] @boo : $@convention(thin) (@in U) -> @owned @callee_owned (Int32, @in T) -> Int32 { +bb0(%0 : $*U): + debug_value_addr %0 : $*U, let, name "y" // id: %1 + // function_ref test4.(boo (A) -> (Swift.Int32, B) -> Swift.Int32).(closure #1) + %2 = function_ref @boo_closure : $@convention(thin) <τ_0_0, τ_0_1 where τ_0_0 : P> (Int32, @in τ_0_1, @owned <τ_0_0> { var τ_0_0 } <τ_0_0>) -> Int32 // user: %5 + %3 = alloc_box $<τ_0_0> { var τ_0_0 } // users: %4, %5, %5 + %3a = project_box %3 : $<τ_0_0> { var τ_0_0 } , 0 + copy_addr %0 to [initialization] %3a : $*U // id: %4 + %5 = partial_apply %2(%3) : $@convention(thin) <τ_0_0, τ_0_1 where τ_0_0 : P> (Int32, @in τ_0_1, @owned <τ_0_0> { var τ_0_0 } <τ_0_0>) -> Int32 // user: %7 + destroy_addr %0 : $*U // id: %6 + return %5 : $@callee_owned (Int32, @in T) -> Int32 // id: %7 +} + +// test4.(boo (A) -> (Swift.Int32, B) -> Swift.Int32).(closure #1) +sil shared [ossa] [noinline] @boo_closure : $@convention(thin) (Int32, @in T, @owned <τ_0_0> { var τ_0_0 } ) -> Int32 { +bb0(%0 : $Int32, %1 : $*T, %2 : @owned $<τ_0_0> { var τ_0_0 } ): + %3 = project_box %2 : $<τ_0_0> { var τ_0_0 } , 0 + debug_value %0 : $Int32, let, name "x" // id: %4 + debug_value_addr %1 : $*T, let, name "z" // id: %5 + %6 = witness_method $U, #P.get : $@convention(witness_method: P) <τ_0_0 where τ_0_0 : P> (@in_guaranteed τ_0_0) -> Int32 // user: %7 + %7 = apply %6(%3) : $@convention(witness_method: P) <τ_0_0 where τ_0_0 : P> (@in_guaranteed τ_0_0) -> Int32 // user: %8 + %8 = struct_extract %7 : $Int32, #Int32._value // user: %11 + %9 = struct_extract %0 : $Int32, #Int32._value // user: %11 + %10 = integer_literal $Builtin.Int1, -1 // user: %11 + %11 = builtin "sadd_with_overflow_Int32"(%8 : $Builtin.Int32, %9 : $Builtin.Int32, %10 : $Builtin.Int1) : $(Builtin.Int32, Builtin.Int1) // users: %12, %13 + %12 = tuple_extract %11 : $(Builtin.Int32, Builtin.Int1), 0 // user: %15 + %13 = tuple_extract %11 : $(Builtin.Int32, Builtin.Int1), 1 // user: %14 + cond_fail %13 : $Builtin.Int1 // id: %14 + %15 = struct $Int32 (%12 : $Builtin.Int32) // user: %18 + destroy_value %2 : $<τ_0_0> { var τ_0_0 } // id: %16 + destroy_addr %1 : $*T // id: %17 + return %15 : $Int32 // id: %18 +} + +// static Swift.+ infix (Swift.Int32, Swift.Int32) -> Swift.Int32 +sil public_external [ossa] [transparent] [serialized] @$ss1poiys5Int32VAC_ACtFZ : $@convention(thin) (Int32, Int32) -> Int32 { +bb0(%0 : $Int32, %1 : $Int32): + %2 = struct_extract %0 : $Int32, #Int32._value // user: %5 + %3 = struct_extract %1 : $Int32, #Int32._value // user: %5 + %4 = integer_literal $Builtin.Int1, -1 // user: %5 + %5 = builtin "sadd_with_overflow_Int32"(%2 : $Builtin.Int32, %3 : $Builtin.Int32, %4 : $Builtin.Int1) : $(Builtin.Int32, Builtin.Int1) // users: %6, %7 + %6 = tuple_extract %5 : $(Builtin.Int32, Builtin.Int1), 0 // user: %9 + %7 = tuple_extract %5 : $(Builtin.Int32, Builtin.Int1), 1 // user: %8 + cond_fail %7 : $Builtin.Int1 // id: %8 + %9 = struct $Int32 (%6 : $Builtin.Int32) // user: %10 + return %9 : $Int32 // id: %10 +} + +// test4.foo (A, B) -> (Swift.Int32, Swift.Float) -> Swift.Int32 +sil hidden [ossa] [noinline] @foo : $@convention(thin) (@in T, @in U) -> @owned @callee_owned (Int32, Float) -> Int32 { +bb0(%0 : $*T, %1 : $*U): + debug_value_addr %0 : $*T, let, name "x" // id: %2 + debug_value_addr %1 : $*U, let, name "y" // id: %3 + // function_ref test4.boo (A) -> (Swift.Int32, B) -> Swift.Int32 + %4 = function_ref @boo : $@convention(thin) <τ_0_0, τ_0_1 where τ_0_0 : P> (@in τ_0_0) -> @owned @callee_owned (Int32, @in τ_0_1) -> Int32 // user: %7 + %5 = alloc_stack $U // users: %6, %7, %10 + copy_addr %1 to [initialization] %5 : $*U // id: %6 + %7 = apply %4(%5) : $@convention(thin) <τ_0_0, τ_0_1 where τ_0_0 : P> (@in τ_0_0) -> @owned @callee_owned (Int32, @in τ_0_1) -> Int32 // user: %9 + // function_ref reabstraction thunk helper from @callee_owned (@unowned Swift.Int32, @in Swift.Float) -> (@unowned Swift.Int32) to @callee_owned (@unowned Swift.Int32, @unowned Swift.Float) -> (@unowned Swift.Int32) + %8 = function_ref @_TTRG1_RPq_P5test41P_Pq0_PS0___XFo_dVs5Int32iSf_dS1__XFo_dS1_dSf_dS1__ : $@convention(thin) <τ_0_0, τ_0_1 where τ_0_0 : P, τ_0_1 : P> (Int32, Float, @owned @callee_owned (Int32, @in Float) -> Int32) -> Int32 // user: %9 + %9 = partial_apply %8(%7) : $@convention(thin) <τ_0_0, τ_0_1 where τ_0_0 : P, τ_0_1 : P> (Int32, Float, @owned @callee_owned (Int32, @in Float) -> Int32) -> Int32 // user: %13 + dealloc_stack %5 : $*U // id: %10 + destroy_addr %1 : $*U // id: %11 + destroy_addr %0 : $*T // id: %12 + return %9 : $@callee_owned (Int32, Float) -> Int32 // id: %13 +} + +// reabstraction thunk helper from @callee_owned (@unowned Swift.Int32, @in Swift.Float) -> (@unowned Swift.Int32) to @callee_owned (@unowned Swift.Int32, @unowned Swift.Float) -> (@unowned Swift.Int32) +sil shared [ossa] [transparent] [thunk] @_TTRG1_RPq_P5test41P_Pq0_PS0___XFo_dVs5Int32iSf_dS1__XFo_dS1_dSf_dS1__ : $@convention(thin) (Int32, Float, @owned @callee_owned (Int32, @in Float) -> Int32) -> Int32 { +bb0(%0 : $Int32, %1 : $Float, %2 : @owned $@callee_owned (Int32, @in Float) -> Int32): + %3 = alloc_stack $Float // users: %4, %5, %6 + store %1 to [trivial] %3 : $*Float // id: %4 + %5 = apply %2(%0, %3) : $@callee_owned (Int32, @in Float) -> Int32 // user: %7 + dealloc_stack %3 : $*Float // id: %6 + return %5 : $Int32 // id: %7 +} + +// test4.gen1 (A) -> (Swift.Int32) -> Swift.Int32 +sil hidden [ossa] [noinline] @gen1 : $@convention(thin) (@in T) -> @owned @callee_owned (Int32) -> Int32 { +bb0(%0 : $*T): + debug_value_addr %0 : $*T, let, name "x" // id: %1 + // function_ref test4.(gen1 (A) -> (Swift.Int32) -> Swift.Int32).(closure #1) + %2 = function_ref @gen1_closure : $@convention(thin) <τ_0_0 where τ_0_0 : P> (Int32, @owned <τ_0_0> { var τ_0_0 } <τ_0_0>) -> Int32 // user: %5 + %3 = alloc_box $<τ_0_0> { var τ_0_0 } // users: %4, %5, %5 + %3a = project_box %3 : $<τ_0_0> { var τ_0_0 } , 0 + copy_addr %0 to [initialization] %3a : $*T // id: %4 + %5 = partial_apply %2(%3) : $@convention(thin) <τ_0_0 where τ_0_0 : P> (Int32, @owned <τ_0_0> { var τ_0_0 } <τ_0_0>) -> Int32 // user: %7 + destroy_addr %0 : $*T // id: %6 + return %5 : $@callee_owned (Int32) -> Int32 // id: %7 +} + +// test4.(gen1 (A) -> (Swift.Int32) -> Swift.Int32).(closure #1) +sil shared [ossa] [noinline] @gen1_closure : $@convention(thin) (Int32, @owned <τ_0_0> { var τ_0_0 } ) -> Int32 { +bb0(%0 : $Int32, %1 : @owned $<τ_0_0> { var τ_0_0 } ): + %2 = project_box %1 : $<τ_0_0> { var τ_0_0 } , 0 + debug_value %0 : $Int32 , let, name "$0" // id: %3 + %4 = witness_method $T, #P.get : $@convention(witness_method: P) <τ_0_0 where τ_0_0 : P> (@in_guaranteed τ_0_0) -> Int32 // user: %5 + %5 = apply %4(%2) : $@convention(witness_method: P) <τ_0_0 where τ_0_0 : P> (@in_guaranteed τ_0_0) -> Int32 // user: %6 + %6 = struct_extract %5 : $Int32, #Int32._value // user: %9 + %7 = struct_extract %0 : $Int32, #Int32._value // user: %9 + %8 = integer_literal $Builtin.Int1, -1 // user: %9 + %9 = builtin "sadd_with_overflow_Int32"(%6 : $Builtin.Int32, %7 : $Builtin.Int32, %8 : $Builtin.Int1) : $(Builtin.Int32, Builtin.Int1) // users: %10, %11 + %10 = tuple_extract %9 : $(Builtin.Int32, Builtin.Int1), 0 // user: %13 + %11 = tuple_extract %9 : $(Builtin.Int32, Builtin.Int1), 1 // user: %12 + cond_fail %11 : $Builtin.Int1 // id: %12 + %13 = struct $Int32 (%10 : $Builtin.Int32) // user: %15 + destroy_value %1 : $<τ_0_0> { var τ_0_0 } // id: %14 + return %13 : $Int32 // id: %15 +} + +// check that there is a generic specialization of boo +// CHECK-LABEL: sil shared [noinline] [ossa] @$s3booxs5Int32VSfACIexyid_4main1PRzSfRs_r0_lIetio_Tp5AD1CV_Tg5 : $@convention(thin) (C) -> @owned @callee_owned (Int32, @in Float) -> Int32 +// CHECK: [[CLOSURE_SPECIALIZATION:%[0-9]+]] = function_ref @$s11boo_closures5Int32VSfxz_x_lXXAC4main1PRzSfRs_r0_lIetyyxd_TP5AD1CV_TG5 +// CHECK: partial_apply [[CLOSURE_SPECIALIZATION:%[0-9]+]] +// CHECK: return + +// Check that there is a generic specialization of a closure from boo +// CHECK-LABEL: sil shared [noinline] [ossa] @$s11boo_closures5Int32VSfxz_x_lXXAC4main1PRzSfRs_r0_lIetyyxd_Tp5AD1CV_Tg5 +// CHECK: return + +// Check that there is a generic specialization of foo +// CHECK-LABEL: sil shared [noinline] [ossa] @$s3foo4main1CV_ADTg5 : $@convention(thin) (C, C) -> @owned @callee_owned (Int32, Float) -> Int32 +// CHECK: function_ref @$s3booxs5Int32VSfACIexyid_4main1PRzSfRs_r0_lIetio_Tp5AD1CV_Tg5 +// check that it invokes a generic specialization of the reabstraction thunk helper which invokes a specialization boo +// CHECK: [[THUNK_SPECIALIZATION:%[0-9]+]] = function_ref @$s053_TTRG1_RPq_P5test41P_Pq0_PS0___XFo_dVs5Int32iSf_dS1__f2_dj2_di2_dJ2__4main1CV_ADTg5 +// CHECK-NOT: apply +// CHECK: partial_apply [[THUNK_SPECIALIZATION]] +// CHECK-NOT: apply +// CHECK: return + + +// Check that there is a generic specialization of gen1 +// CHECK-LABEL: sil shared [noinline] [ossa] @$s4gen14main1CV_Tg5 : $@convention(thin) (C) -> @owned @callee_owned (Int32) -> Int32 +// check that it invokes a generic specialization of the closure by mean of partial_apply +// CHECK: [[CLOSURE_SPECIALIZATION:%[0-9]+]] = function_ref @$s12gen1_closure4main1CV_Tg5 +// CHECK-NOT: apply +// CHECK: partial_apply [[CLOSURE_SPECIALIZATION]] +// CHECK-NOT: apply +// CHECK: return + +// Check that there is a generic specialization of a closure from gen1 +// CHECK-LABEL: sil shared [noinline] [ossa] @$s12gen1_closure4main1CV_Tg5 : $@convention(thin) (Int32, @owned <τ_0_0> { var τ_0_0 } ) -> Int32 +// CHECK: return + + + +// test4.bar () -> Swift.Int32 +// CHECK-LABEL: sil hidden [ossa] @bar +// check that it does not invoke a generic specialization of foo +// CHECK-NOT: function_ref @foo +// check that it invokes a generic specialization of foo +// CHECK: function_ref @$s3foo4main1CV_ADTg5 +sil hidden [ossa] @bar : $@convention(thin) () -> Int32 { +bb0: + %0 = alloc_stack $@callee_owned (Int32, Float) -> Int32, var, name "f" // users: %11, %22 + // function_ref test4.C.init (test4.C.Type)() -> test4.C + %1 = function_ref @C_init : $@convention(thin) (@thin C.Type) -> C // user: %3 + %2 = metatype $@thin C.Type // user: %3 + %3 = apply %1(%2) : $@convention(thin) (@thin C.Type) -> C // users: %4, %7, %9 + debug_value %3 : $C, let, name "c" // id: %4 + // function_ref test4.foo (A, B) -> (Swift.Int32, Swift.Float) -> Swift.Int32 + %5 = function_ref @foo : $@convention(thin) <τ_0_0, τ_0_1 where τ_0_0 : P, τ_0_1 : P> (@in τ_0_0, @in τ_0_1) -> @owned @callee_owned (Int32, Float) -> Int32 // user: %10 + %6 = alloc_stack $C // users: %7, %10, %13 + store %3 to [trivial] %6 : $*C // id: %7 + %8 = alloc_stack $C // users: %9, %10, %12 + store %3 to [trivial] %8 : $*C // id: %9 + %10 = apply %5(%6, %8) : $@convention(thin) <τ_0_0, τ_0_1 where τ_0_0 : P, τ_0_1 : P> (@in τ_0_0, @in τ_0_1) -> @owned @callee_owned (Int32, Float) -> Int32 // users: %11, %14, %20, %21 + store %10 to [init] %0 : $*@callee_owned (Int32, Float) -> Int32 // id: %11 + dealloc_stack %8 : $*C // id: %12 + dealloc_stack %6 : $*C // id: %13 + %11 = load [take] %0 : $*@callee_owned (Int32, Float) -> Int32 // id: %14 + %15 = integer_literal $Builtin.Int32, 3 // user: %16 + %16 = struct $Int32 (%15 : $Builtin.Int32) // user: %20 + %17 = float_literal $Builtin.FPIEEE80, 0x4000C8F5C28F5C28F5C3 // 3.1400000000000000001 // user: %18 + %18 = builtin "fptrunc_FPIEEE80_FPIEEE32"(%17 : $Builtin.FPIEEE80) : $Builtin.FPIEEE32 // user: %19 + %19 = struct $Float (%18 : $Builtin.FPIEEE32) // user: %20 + %20 = apply %11(%16, %19) : $@callee_owned (Int32, Float) -> Int32 // user: %23 + dealloc_stack %0 : $*@callee_owned (Int32, Float) -> Int32 // id: %22 + return %20 : $Int32 // id: %23 +} + +// test4.testBar () -> Swift.Int32 +sil [ossa] @testBar : $@convention(thin) () -> Int32 { +bb0: + // function_ref test4.bar () -> Swift.Int32 + %0 = function_ref @bar : $@convention(thin) () -> Int32 // user: %1 + %1 = apply %0() : $@convention(thin) () -> Int32 // user: %2 + return %1 : $Int32 // id: %2 +} + +// CHECK-LABEL: sil [ossa] @testGen1 +// Call of C_init +// CHECK: function_ref @C_init +// CHECK: apply +// Reference to the generic specialization of gen1 +// CHECK-NOT: function_ref @gen1 +// CHECK: function_ref @$s4gen14main1CV_Tg5 : $@convention(thin) (C) -> @owned @callee_owned (Int32) -> Int32 +sil [ossa] @testGen1 : $@convention(thin) () -> Int32 { +bb0: + %0 = alloc_stack $@callee_owned (Int32) -> Int32, var, name "f" // users: %9, %16 + // function_ref test4.C.init (test4.C.Type)() -> test4.C + %1 = function_ref @C_init : $@convention(thin) (@thin C.Type) -> C // user: %3 + %2 = metatype $@thin C.Type // user: %3 + %3 = apply %1(%2) : $@convention(thin) (@thin C.Type) -> C // users: %4, %7 + debug_value %3 : $C, let, name "c" // id: %4 + // function_ref test4.gen1 (A) -> (Swift.Int32) -> Swift.Int32 + %5 = function_ref @gen1 : $@convention(thin) <τ_0_0 where τ_0_0 : P> (@in τ_0_0) -> @owned @callee_owned (Int32) -> Int32 // user: %8 + %6 = alloc_stack $C // users: %7, %8, %10 + store %3 to [trivial] %6 : $*C // id: %7 + %8 = apply %5(%6) : $@convention(thin) <τ_0_0 where τ_0_0 : P> (@in τ_0_0) -> @owned @callee_owned (Int32) -> Int32 // users: %9, %11, %14, %15 + store %8 to [init] %0 : $*@callee_owned (Int32) -> Int32 // id: %9 + dealloc_stack %6 : $*C // id: %10 + %8a = load [take] %0 : $*@callee_owned (Int32) -> Int32 // id: %11 + %12 = integer_literal $Builtin.Int32, 3 // user: %13 + %13 = struct $Int32 (%12 : $Builtin.Int32) // user: %14 + %14 = apply %8a(%13) : $@callee_owned (Int32) -> Int32 // user: %17 + dealloc_stack %0 : $*@callee_owned (Int32) -> Int32 // id: %16 + return %14 : $Int32 // id: %17 +} + +// test_bind (Builtin.RawPointer, A.Type) -> () +// Check that this is specialized as T=Int. +// CHECK-LABEL: sil shared [ossa] @$s9test_bindSi_Tg5 : $@convention(thin) (Builtin.RawPointer, @thick Int.Type) -> () +// CHECK: bind_memory %0 : $Builtin.RawPointer, {{%.*}} : $Builtin.Word to $*Int +// CHECK: return +sil hidden [ossa] @test_bind : $@convention(thin) (Builtin.RawPointer, @thick T.Type) -> () { +bb0(%0 : $Builtin.RawPointer, %1 : $@thick T.Type): + %4 = integer_literal $Builtin.Word, 1 + %5 = metatype $@thick T.Type + bind_memory %0 : $Builtin.RawPointer, %4 : $Builtin.Word to $*T + %7 = tuple () + %8 = tuple () + return %8 : $() +} + +// Invoke test_bind with T=Int. +sil [ossa] @call_bind : $@convention(thin) (Builtin.RawPointer) -> () { +bb0(%0 : $Builtin.RawPointer): + // function_ref test_bind (Builtin.RawPointer, A.Type) -> () + %2 = function_ref @test_bind : $@convention(thin) <τ_0_0> (Builtin.RawPointer, @thick τ_0_0.Type) -> () + %3 = metatype $@thick Int.Type + %4 = apply %2(%0, %3) : $@convention(thin) <τ_0_0> (Builtin.RawPointer, @thick τ_0_0.Type) -> () + %5 = tuple () + return %5 : $() +} + +// invokeGenericClosure(todo:) +sil [ossa] [noinline] @invokeGenericClosure : $@convention(thin) (@owned @callee_owned () -> (@out R, @error Error)) -> (@out R, @error Error) { +bb0(%0 : $*R, %1 : @owned $@callee_owned () -> (@out R, @error Error)): + debug_value %1 : $@callee_owned () -> (@out R, @error Error), let, name "todo", argno 1 // id: %2 + debug_value undef : $Error, var, name "$error", argno 2 // id: %3 + %1a = copy_value %1 : $@callee_owned () -> (@out R, @error Error) // id: %4 + try_apply %1a(%0) : $@callee_owned () -> (@out R, @error Error), normal bb1, error bb2 // id: %5 + +bb1(%6 : $()): // Preds: bb0 + destroy_value %1 : $@callee_owned () -> (@out R, @error Error) // id: %7 + %8 = tuple () // user: %9 + return %8 : $() // id: %9 + +// %10 // user: %12 +bb2(%10 : @owned $Error): // Preds: bb0 + destroy_value %1 : $@callee_owned () -> (@out R, @error Error) // id: %11 + throw %10 : $Error // id: %12 +} // end sil function 'invokeGenericClosure' + +sil public_external @error : $@convention(thin) () -> Never + +// action() +sil @action : $@convention(thin) () -> Never + +// thunk for @callee_owned () -> (@unowned Never, @error @owned Error) +sil @action_thunk : $@convention(thin) (@owned @callee_owned () -> (Never, @error Error)) -> (@out Never, @error Error) + +// Check that in a case where a generic specialization is a non-return function, +// the return value is not stored after the call and an unreachable instruction +// is inserted as a terminator of a basic block. +// +// CHECK-LABEL: sil [ossa] @testGenericClosureSpecialization +// Call of the generic specialization of invokeGenericClosure +// CHECK: function_ref @$s20invokeGenericClosures5NeverO_Tg5 : $@convention(thin) (@owned @callee_owned () -> (@out Never, @error Error)) -> (Never, @error Error) +// CHECK: apply [nothrow] +// CHECK: unreachable +// CHECK: end sil function 'testGenericClosureSpecialization' +sil [ossa] @testGenericClosureSpecialization : $@convention(thin) () -> @error Error { +bb0: + // function_ref invokeGenericClosure(todo:) + %1 = function_ref @invokeGenericClosure : $@convention(thin) <τ_0_0> (@owned @callee_owned () -> (@out τ_0_0, @error Error)) -> (@out τ_0_0, @error Error) + %2 = alloc_stack $Never + // function_ref action() + %3 = function_ref @action : $@convention(thin) () -> Never + %4 = thin_to_thick_function %3 : $@convention(thin) () -> Never to $@callee_owned () -> Never + %5 = convert_function %4 : $@callee_owned () -> Never to $@callee_owned () -> (Never, @error Error) + // function_ref thunk for @callee_owned () -> (@unowned Never, @error @owned Error) + %6 = function_ref @action_thunk : $@convention(thin) (@owned @callee_owned () -> (Never, @error Error)) -> (@out Never, @error Error) + %7 = partial_apply %6(%5) : $@convention(thin) (@owned @callee_owned () -> (Never, @error Error)) -> (@out Never, @error Error) + %8 = apply [nothrow] %1(%2, %7) : $@convention(thin) <τ_0_0> (@owned @callee_owned () -> (@out τ_0_0, @error Error)) -> (@out τ_0_0, @error Error) + unreachable +} // end sil function 'testGenericClosureSpecialization' + +// Test a specialization of a self-recursive generic closure. + +// CHECK-LABEL: sil shared [ossa] @$s27selfReferringGenericClosurexBi64_Bi64_Bi64_Rs_r0_lIetnyy_Tp5 : $@convention(thin) <τ_0_0, τ_0_1 where τ_0_1 == Builtin.Int64> (@in_guaranteed τ_0_0, Builtin.Int64, Builtin.Int64) -> () { +// CHECK: [[SPECIALIZED_FN:%[0-9]+]] = function_ref @$s27selfReferringGenericClosurexBi64_Bi64_Bi64_Rs_r0_lIetnyy_Tp5 +// CHECK: partial_apply [[SPECIALIZED_FN]]{{.*}}({{.*}}) : $@convention(thin) <τ_0_0, τ_0_1 where τ_0_1 == Builtin.Int64> (@in_guaranteed τ_0_0, Builtin.Int64, Builtin.Int64) -> () + +// CHECK-LABEL: sil [ossa] @selfReferringGenericClosure : $@convention(thin) (@in_guaranteed R, @in_guaranteed S, Builtin.Int64) -> () +// Refer to the specialized version of the function +// CHECK: [[SPECIALIZED_FN:%[0-9]+]] = function_ref @$s27selfReferringGenericClosurexBi64_Bi64_Bi64_Rs_r0_lIetnyy_Tp5 +// CHECK: partial_apply [[SPECIALIZED_FN]]({{.*}}) : $@convention(thin) <τ_0_0, τ_0_1 where τ_0_1 == Builtin.Int64> (@in_guaranteed τ_0_0, Builtin.Int64, Builtin.Int64) -> () +sil [ossa] @selfReferringGenericClosure : $@convention(thin) (@in_guaranteed R, @in_guaranteed S, Builtin.Int64) -> () { +bb0(%0 : $*R, %1 : $*S, %2 : $Builtin.Int64): + %4 = integer_literal $Builtin.Int64, 100 + %5 = builtin "cmp_eq_Int64"(%2 : $Builtin.Int64, %4 : $Builtin.Int64) : $Builtin.Int1 + cond_br %5, bb2, bb1 + +bb1: + %val_storage = alloc_stack $Builtin.Int64 + %val = integer_literal $Builtin.Int64, 4 + store %val to [trivial] %val_storage : $*Builtin.Int64 + %fn = function_ref @selfReferringGenericClosure : $@convention(thin) (@in_guaranteed U, @in_guaranteed V, Builtin.Int64) -> () + %7 = partial_apply %fn(%0, %val_storage, %4) : $@convention(thin) (@in_guaranteed U, @in_guaranteed V, Builtin.Int64) -> () + dealloc_stack %val_storage : $*Builtin.Int64 + destroy_value %7 : $@callee_owned () -> () + br bb3 + +bb2: + br bb3 + +bb3: + %8 = tuple () + return %8 : $() +} + +sil [ossa] @selfReferringGenericClosure_nontrivial_guaranteed : $@convention(thin) (@in_guaranteed R, @in_guaranteed S, @guaranteed Builtin.NativeObject) -> () { +bb0(%0 : $*R, %1 : $*S, %2 : @guaranteed $Builtin.NativeObject): + cond_br undef, bb2, bb1 + +bb1: + %val_storage = alloc_stack $Builtin.NativeObject + %val = copy_value %2 : $Builtin.NativeObject + %val2 = copy_value %2 : $Builtin.NativeObject + store %val to [init] %val_storage : $*Builtin.NativeObject + %fn = function_ref @selfReferringGenericClosure_nontrivial_guaranteed : $@convention(thin) (@in_guaranteed U, @in_guaranteed V, @guaranteed Builtin.NativeObject) -> () + %7 = partial_apply %fn(%0, %val_storage, %val2) : $@convention(thin) (@in_guaranteed U, @in_guaranteed V, @guaranteed Builtin.NativeObject) -> () + dealloc_stack %val_storage : $*Builtin.NativeObject + destroy_value %7 : $@callee_owned () -> () + br bb3 + +bb2: + br bb3 + +bb3: + %8 = tuple () + return %8 : $() +} + +sil [ossa] @selfReferringGenericClosure_nontrivial_guaranteed_applied : $@convention(thin) (@in_guaranteed R, @in_guaranteed S, @guaranteed Builtin.NativeObject) -> () { +bb0(%0 : $*R, %1 : $*S, %2 : @guaranteed $Builtin.NativeObject): + cond_br undef, bb2, bb1 + +bb1: + %val_storage = alloc_stack $Builtin.NativeObject + %val = copy_value %2 : $Builtin.NativeObject + %val2 = copy_value %2 : $Builtin.NativeObject + store %val to [init] %val_storage : $*Builtin.NativeObject + %fn = function_ref @selfReferringGenericClosure_nontrivial_guaranteed_applied : $@convention(thin) (@in_guaranteed U, @in_guaranteed V, @guaranteed Builtin.NativeObject) -> () + %7 = partial_apply %fn(%0, %val_storage, %val2) : $@convention(thin) (@in_guaranteed U, @in_guaranteed V, @guaranteed Builtin.NativeObject) -> () + apply %7() :$@callee_owned () -> () + dealloc_stack %val_storage : $*Builtin.NativeObject + br bb3 + +bb2: + br bb3 + +bb3: + %8 = tuple () + return %8 : $() +} + +//---- + +// CHECK-LABEL: sil [ossa] @selfReferringGenericClosure_nontrivial_owned : $@convention(thin) (@in R, @in S, @owned Builtin.NativeObject) -> () { +// CHECK: [[FUNC:%.*]] = function_ref @$s44selfReferringGenericClosure_nontrivial_ownedxBoBoBoRs_r0_lIetixx_Tp5 : $@convention(thin) <τ_0_0, τ_0_1 where τ_0_1 == Builtin.NativeObject> (@in τ_0_0, @owned Builtin.NativeObject, @owned Builtin.NativeObject) -> () +// CHECK: [[PAI:%.*]] = partial_apply [[FUNC]]< +// CHECK: destroy_value [[PAI]] +// CHECK: } // end sil function 'selfReferringGenericClosure_nontrivial_owned' +sil [ossa] @selfReferringGenericClosure_nontrivial_owned : $@convention(thin) (@in R, @in S, @owned Builtin.NativeObject) -> () { +bb0(%0 : $*R, %1 : $*S, %2 : @owned $Builtin.NativeObject): + cond_br undef, bb2, bb1 + +bb1: + %val_storage = alloc_stack $Builtin.NativeObject + %val = copy_value %2 : $Builtin.NativeObject + store %val to [init] %val_storage : $*Builtin.NativeObject + %fn = function_ref @selfReferringGenericClosure_nontrivial_owned : $@convention(thin) (@in U, @in V, @owned Builtin.NativeObject) -> () + %7 = partial_apply %fn(%0, %val_storage, %2) : $@convention(thin) (@in U, @in V, @owned Builtin.NativeObject) -> () + dealloc_stack %val_storage : $*Builtin.NativeObject + destroy_value %7 : $@callee_owned () -> () + br bb3 + +bb2: + destroy_value %2 : $Builtin.NativeObject + destroy_addr %0 : $*R + br bb3 + +bb3: + destroy_addr %1 : $*S + %8 = tuple () + return %8 : $() +} + +sil [ossa] @selfReferringGenericClosure_nontrivial_owned_applied : $@convention(thin) (@in R, @in S, @owned Builtin.NativeObject) -> () { +bb0(%0 : $*R, %1 : $*S, %2 : @owned $Builtin.NativeObject): + cond_br undef, bb2, bb1 + +bb1: + %val_storage = alloc_stack $Builtin.NativeObject + %val = copy_value %2 : $Builtin.NativeObject + store %val to [init] %val_storage : $*Builtin.NativeObject + %fn = function_ref @selfReferringGenericClosure_nontrivial_owned_applied : $@convention(thin) (@in U, @in V, @owned Builtin.NativeObject) -> () + %7 = partial_apply %fn(%0, %val_storage, %2) : $@convention(thin) (@in U, @in V, @owned Builtin.NativeObject) -> () + apply %7() :$@callee_owned () -> () + dealloc_stack %val_storage : $*Builtin.NativeObject + br bb3 + +bb2: + destroy_value %2 : $Builtin.NativeObject + destroy_addr %0 : $*R + br bb3 + +bb3: + destroy_addr %1 : $*S + %8 = tuple () + return %8 : $() +} + +struct YYY { +} + +enum MyOptional { + case none + case some(T) +} + +// Check that a specialization of a self-recursive function is produced +// and it is not crashing the compiler. +// CHECK-LABEL: sil shared [ossa] @$s25testSelfRecursiveFunction4main10MyOptionalOyAB3YYYVyypGG_Tg5 : $@convention(thin) (MyOptional>) -> () +sil [ossa] @testSelfRecursiveFunction : $@convention(thin) (@in T) -> () { +bb0(%0 : $*T): + %2 = function_ref @testSelfRecursiveFunction : $@convention(thin) <τ_0_0> (@in τ_0_0) -> () + %3 = alloc_stack $MyOptional> + inject_enum_addr %3 : $*MyOptional>, #MyOptional.none!enumelt + %5 = tuple () + %6 = load [trivial] %3 : $*MyOptional> + %7 = alloc_stack $MyOptional> + store %6 to [trivial] %7 : $*MyOptional> + %9 = apply %2>>(%7) : $@convention(thin) <τ_0_0> (@in τ_0_0) -> () + dealloc_stack %7 : $*MyOptional> + dealloc_stack %3 : $*MyOptional> + destroy_addr %0 : $*T + %13 = tuple () + return %13 : $() +} // end sil function 'testSelfRecursiveFunction' + +sil [ossa] @id : $@convention(thin) (@in T) -> @out T { +bb0(%0 : $*T, %1 :$*T): + copy_addr [take] %1 to [initialization] %0 : $*T + %t = tuple () + return %t : $() +} + +// This should not assert. +// CHECK-LABEL: sil shared [ossa] @$s26specialize_no_return_applys5NeverO_Tg5 +// CHECK: apply +// CHECK-NEXT: unreachable + +sil [ossa] @specialize_no_return_apply: $@convention(thin) (@thick T.Type) -> () { +bb0(%0 : $@thick T.Type): + %in = alloc_stack $T + copy_addr [take] undef to [initialization] %in : $*T + %out = alloc_stack $T + %f = function_ref @id : $@convention(thin) (@in T) -> @out T + %r = apply %f(%out, %in) : $@convention(thin) (@in T) -> @out T + destroy_addr %out : $*T + dealloc_stack %out : $*T + dealloc_stack %in : $*T + %t = tuple () + return %t : $() +} + +sil [ossa] @test_specialize_noreturn_apply : $@convention(thin) () -> () { +bb0: + %f = function_ref @specialize_no_return_apply : $@convention(thin) (@thick T.Type) -> () + %m = metatype $@thick Never.Type + %r = apply %f(%m) : $@convention(thin) (@thick T.Type) -> () + %t = tuple () + return %t : $() +} + +//////////////////// +// TryApply Tests // +//////////////////// + +sil @getError : $@convention(thin) () -> @owned Error + +sil [ossa] @generic_try_apply_callee2 : $@convention(thin) (@in_guaranteed T) -> @error Error { +bb0(%0 : $*T): + cond_br undef, bb1, bb2 + +bb1: + %f = function_ref @getError : $@convention(thin) () -> @owned Error + %e = apply %f() : $@convention(thin) () -> @owned Error + throw %e : $Error + +bb2: + %9999 = tuple() + return %9999 : $() +} + +sil [ossa] @generic_try_apply_callee : $@convention(thin) (@in_guaranteed T) -> @error Error { +bb0(%0 : $*T): + %f = function_ref @generic_try_apply_callee2 : $@convention(thin) (@in_guaranteed T) -> @error Error + try_apply %f(%0) : $@convention(thin) (@in_guaranteed T) -> @error Error, normal bb1, error bb2 + +bb1(%result : $()): + %9999 = tuple() + return %9999 : $() + +bb2(%e : @owned $Error): + throw %e : $Error +} + +sil [ossa] @generic_try_apply_callee2_out_param : $@convention(thin) (@in_guaranteed T) -> (@out T, @error Error) { +bb0(%0 : $*T, %1 : $*T): + cond_br undef, bb1, bb2 + +bb1: + %f = function_ref @getError : $@convention(thin) () -> @owned Error + %e = apply %f() : $@convention(thin) () -> @owned Error + throw %e : $Error + +bb2: + copy_addr %1 to [initialization] %0 : $*T + %9999 = tuple() + return %9999 : $() +} + + +sil [ossa] @generic_try_apply_callee_out_param : $@convention(thin) (@in_guaranteed T) -> (@out T, @error Error) { +bb0(%0 : $*T, %1 : $*T): + %f = function_ref @generic_try_apply_callee2_out_param : $@convention(thin) (@in_guaranteed T) -> (@out T, @error Error) + try_apply %f(%0, %1) : $@convention(thin) (@in_guaranteed T) -> (@out T, @error Error), normal bb1, error bb2 + +bb1(%result : $()): + %9999 = tuple() + return %9999 : $() + +bb2(%e : @owned $Error): + throw %e : $Error +} + +// Just make sure we pass the verifiers. +// +// CHECK-LABEL: sil [ossa] @test_try_apply : $@convention(thin) (Builtin.Int32, @guaranteed Builtin.NativeObject) -> () { +// CHECK: try_apply {{%.*}}({{%.*}}) : $@convention(thin) (Builtin.Int32) -> @error Error, normal bb1, error bb2 +// CHECK: try_apply {{%.*}}({{%.*}}) : $@convention(thin) (@guaranteed Builtin.NativeObject) -> @error Error, normal bb4, error bb5 +// CHECK: } // end sil function 'test_try_apply' +sil [ossa] @test_try_apply : $@convention(thin) (Builtin.Int32, @guaranteed Builtin.NativeObject) -> () { +bb0(%0 : $Builtin.Int32, %1 : @guaranteed $Builtin.NativeObject): + %f = function_ref @generic_try_apply_callee : $@convention(thin) (@in_guaranteed T) -> @error Error + + %0a = alloc_stack $Builtin.Int32 + store %0 to [trivial] %0a : $*Builtin.Int32 + try_apply %f(%0a) : $@convention(thin) (@in_guaranteed T) -> @error Error, normal bb1, error bb2 + +bb1(%result : $()): + br bb3 + +bb2(%e : @owned $Error): + destroy_value %e : $Error + br bb3 + +bb3: + dealloc_stack %0a : $*Builtin.Int32 + + %0b = alloc_stack $Builtin.NativeObject + store_borrow %1 to %0b : $*Builtin.NativeObject + try_apply %f(%0b) : $@convention(thin) (@in_guaranteed T) -> @error Error, normal bb4, error bb5 + +bb4(%result2 : $()): + br bb6 + +bb5(%e2 : @owned $Error): + destroy_value %e2 : $Error + br bb6 + +bb6: + dealloc_stack %0b : $*Builtin.NativeObject + + %0c = alloc_stack $Builtin.NativeObject + store_borrow %1 to %0c : $*Builtin.NativeObject + %outParam = alloc_stack $Builtin.NativeObject + %f2 = function_ref @generic_try_apply_callee_out_param : $@convention(thin) (@in_guaranteed T) -> (@out T, @error Error) + try_apply %f2(%outParam, %0c) : $@convention(thin) (@in_guaranteed T) -> (@out T, @error Error), normal bb7, error bb8 + +bb7(%result3 : $()): + destroy_addr %outParam : $*Builtin.NativeObject + br bb9 + +bb8(%error4 : @owned $Error): + destroy_value %error4 : $Error + br bb9 + +bb9: + dealloc_stack %outParam : $*Builtin.NativeObject + dealloc_stack %0c : $*Builtin.NativeObject + %9999 = tuple() + return %9999 : $() +} + +// Test cases where we throw instead of catch. +sil [ossa] @test_try_apply_throw_error : $@convention(thin) (Builtin.Int32, @guaranteed Builtin.NativeObject) -> @error Error { +bb0(%0 : $Builtin.Int32, %1 : @guaranteed $Builtin.NativeObject): + %f = function_ref @generic_try_apply_callee : $@convention(thin) (@in_guaranteed T) -> @error Error + + %0a = alloc_stack $Builtin.Int32 + store %0 to [trivial] %0a : $*Builtin.Int32 + try_apply %f(%0a) : $@convention(thin) (@in_guaranteed T) -> @error Error, normal bb1, error bb2 + +bb1(%result : $()): + br bb3 + +bb2(%e : @owned $Error): + dealloc_stack %0a : $*Builtin.Int32 + br bbError(%e : $Error) + +bb3: + dealloc_stack %0a : $*Builtin.Int32 + %0b = alloc_stack $Builtin.NativeObject + store_borrow %1 to %0b : $*Builtin.NativeObject + try_apply %f(%0b) : $@convention(thin) (@in_guaranteed T) -> @error Error, normal bb4, error bb5 + +bb4(%result2 : $()): + br bb6 + +bb5(%e2 : @owned $Error): + dealloc_stack %0b : $*Builtin.NativeObject + br bbError(%e2 : $Error) + +bbError(%eOut : @owned $Error): + throw %eOut : $Error + +bb6: + dealloc_stack %0b : $*Builtin.NativeObject + %9999 = tuple() + return %9999 : $() +} + +sil [ossa] @generic_try_apply_callee_loadable_2 : $@convention(thin) (@inout T, @guaranteed T) -> @error Error { +bb0(%0 : $*T, %1 : @guaranteed $T +): + cond_br undef, bb1, bb2 + +bb1: + %f = function_ref @getError : $@convention(thin) () -> @owned Error + %e = apply %f() : $@convention(thin) () -> @owned Error + throw %e : $Error + +bb2: + %9999 = tuple() + return %9999 : $() +} + +sil [ossa] @generic_try_apply_callee_loadable_1 : $@convention(thin) (@inout T, @in_guaranteed T) -> @error Error { +bb0(%0 : $*T, %1 : $*T): + %f = function_ref @generic_try_apply_callee_loadable_2 : $@convention(thin) (@inout T, @guaranteed T) -> @error Error + %1b = load_borrow %1 : $*T + try_apply %f(%0, %1b) : $@convention(thin) (@inout T, @guaranteed T) -> @error Error, normal bb1, error bb2 + +bb1(%result : $()): + end_borrow %1b : $T + %9999 = tuple() + return %9999 : $() + +bb2(%e : @owned $Error): + end_borrow %1b : $T + throw %e : $Error +} + +sil [ossa] @test_try_apply_loadable : $@convention(thin) (@inout Klass, @guaranteed Klass) -> () { +bb0(%0 : $*Klass, %1 : @guaranteed $Klass): + %f = function_ref @generic_try_apply_callee_loadable_1 : $@convention(thin) (@inout T, @in_guaranteed T) -> @error Error + %1b = alloc_stack $Klass + store_borrow %1 to %1b : $*Klass + try_apply %f(%0, %1b) : $@convention(thin) (@inout T, @in_guaranteed T) -> @error Error, normal bb4, error bb5 + +bb4(%result2 : $()): + br bb6 + +bb5(%e2 : @owned $Error): + destroy_value %e2 : $Error + br bb6 + +bb6: + dealloc_stack %1b : $*Klass + %9999 = tuple() + return %9999 : $() +} + +sil [ossa] @loadable_partial_apply_user : $@convention(thin) (@guaranteed @callee_guaranteed (@inout Klass) -> @error Error) -> () { +bb0(%0 : @guaranteed $@callee_guaranteed (@inout Klass) -> @error Error): + %9999 = tuple() + return %9999 : $() +} + +sil [ossa] @test_try_apply_loadable_partial_apply : $@convention(thin) (@inout Klass, @guaranteed Klass) -> () { +bb0(%0 : $*Klass, %1 : @guaranteed $Klass): + %f = function_ref @generic_try_apply_callee_loadable_1 : $@convention(thin) (@inout T, @in_guaranteed T) -> @error Error + %1b = alloc_stack $Klass + %1a = copy_value %1 : $Klass + store %1a to [init] %1b : $*Klass + %f2 = partial_apply [callee_guaranteed] %f(%1b) : $@convention(thin) (@inout T, @in_guaranteed T) -> @error Error + %f3 = function_ref @loadable_partial_apply_user : $@convention(thin) (@guaranteed @callee_guaranteed (@inout Klass) -> @error Error) -> () + apply %f3(%f2) : $@convention(thin) (@guaranteed @callee_guaranteed (@inout Klass) -> @error Error) -> () + destroy_value %f2 : $@callee_guaranteed (@inout Klass) -> @error Error + dealloc_stack %1b : $*Klass + %9999 = tuple() + return %9999 : $() +} + +////////////////////// +// BeginApply Tests // +////////////////////// + +sil [ossa] @generic_begin_apply_callee_inguaranteed : $@yield_once @convention(thin) (@in_guaranteed T) -> @yields @in_guaranteed T { +bb0(%0 : $*T): + %1 = alloc_stack $*T + copy_addr %0 to [initialization] %1 : $*T + yield %1 : $*T, resume bb1, unwind bb2 + +bb1: + destroy_addr %1 : $*T + dealloc_stack %1 : $*T + %9999 = tuple() + return %9999 : $() + +bb2: + destroy_addr %1 : $*T + dealloc_stack %1 : $*T + unwind +} + +sil [ossa] @generic_begin_apply_callee_in : $@yield_once @convention(thin) (@in_guaranteed T) -> @yields @in T { +bb0(%0 : $*T): + %1 = alloc_stack $*T + copy_addr %0 to [initialization] %1 : $*T + yield %1 : $*T, resume bb1, unwind bb2 + +bb1: + dealloc_stack %1 : $*T + %9999 = tuple() + return %9999 : $() + +bb2: + dealloc_stack %1 : $*T + unwind +} + +sil [ossa] @generic_begin_apply_callee_inout : $@yield_once @convention(thin) (@in_guaranteed T) -> @yields @inout T { +bb0(%0 : $*T): + %1 = alloc_stack $*T + copy_addr %0 to [initialization] %1 : $*T + yield %1 : $*T, resume bb1, unwind bb2 + +bb1: + destroy_addr %1 : $*T + dealloc_stack %1 : $*T + %9999 = tuple() + return %9999 : $() + +bb2: + destroy_addr %1 : $*T + dealloc_stack %1 : $*T + unwind +} + +// Just make sure we pass the verifiers. +// +// CHECK-LABEL: sil [ossa] @test_begin_apply_inguaranteed : $@convention(thin) (Builtin.Int32, @guaranteed Builtin.NativeObject) -> () { +// CHECK: begin_apply {{%.*}}({{%.*}}) : $@yield_once @convention(thin) (Builtin.Int32) -> @yields @in_guaranteed Builtin.Int32 +// CHECK: begin_apply {{%.*}}({{%.*}}) : $@yield_once @convention(thin) (@guaranteed Builtin.NativeObject) -> @yields @in_guaranteed Builtin.NativeObject +// CHECK: } // end sil function 'test_begin_apply_inguaranteed' +sil [ossa] @test_begin_apply_inguaranteed : $@convention(thin) (Builtin.Int32, @guaranteed Builtin.NativeObject) -> () { +bb0(%0 : $Builtin.Int32, %1 : @guaranteed $Builtin.NativeObject): + %f = function_ref @generic_begin_apply_callee_inguaranteed : $@yield_once @convention(thin) (@in_guaranteed T) -> @yields @in_guaranteed T + + %0a = alloc_stack $Builtin.Int32 + store %0 to [trivial] %0a : $*Builtin.Int32 + (%0r, %0token) = begin_apply %f(%0a) : $@yield_once @convention(thin) (@in_guaranteed T) -> @yields @in_guaranteed T + end_apply %0token + dealloc_stack %0a : $*Builtin.Int32 + + %1b = alloc_stack $Builtin.NativeObject + %1c = copy_value %1 : $Builtin.NativeObject + store %1c to [init] %1b : $*Builtin.NativeObject + (%1result, %1token) = begin_apply %f(%1b) : $@yield_once @convention(thin) (@in_guaranteed T) -> @yields @in_guaranteed T + + end_apply %1token + destroy_addr %1b : $*Builtin.NativeObject + dealloc_stack %1b : $*Builtin.NativeObject + + %9999 = tuple() + return %9999 : $() +} + +// CHECK-LABEL: sil [ossa] @test_begin_apply_in : $@convention(thin) (Builtin.Int32, @guaranteed Builtin.NativeObject) -> () { +// CHECK: begin_apply {{%.*}}({{%.*}}) : $@yield_once @convention(thin) (Builtin.Int32) -> @yields @in Builtin.Int32 +// CHECK: begin_apply {{%.*}}({{%.*}}) : $@yield_once @convention(thin) (@guaranteed Builtin.NativeObject) -> @yields @in Builtin.NativeObject +// CHECK: } // end sil function 'test_begin_apply_in' +sil [ossa] @test_begin_apply_in : $@convention(thin) (Builtin.Int32, @guaranteed Builtin.NativeObject) -> () { +bb0(%0 : $Builtin.Int32, %1 : @guaranteed $Builtin.NativeObject): + %f = function_ref @generic_begin_apply_callee_in : $@yield_once @convention(thin) (@in_guaranteed T) -> @yields @in T + + %0a = alloc_stack $Builtin.Int32 + store %0 to [trivial] %0a : $*Builtin.Int32 + (%0r, %0token) = begin_apply %f(%0a) : $@yield_once @convention(thin) (@in_guaranteed T) -> @yields @in T + end_apply %0token + dealloc_stack %0a : $*Builtin.Int32 + + %1b = alloc_stack $Builtin.NativeObject + %1c = copy_value %1 : $Builtin.NativeObject + store %1c to [init] %1b : $*Builtin.NativeObject + (%1result, %1token) = begin_apply %f(%1b) : $@yield_once @convention(thin) (@in_guaranteed T) -> @yields @in T + + end_apply %1token + destroy_addr %1b : $*Builtin.NativeObject + dealloc_stack %1b : $*Builtin.NativeObject + + %9999 = tuple() + return %9999 : $() +} + +// CHECK-LABEL: sil [ossa] @test_begin_apply_inout : $@convention(thin) (Builtin.Int32, @guaranteed Builtin.NativeObject) -> () { +// CHECK: begin_apply {{%.*}}({{%.*}}) : $@yield_once @convention(thin) (Builtin.Int32) -> @yields @inout Builtin.Int32 +// CHECK: begin_apply {{%.*}}({{%.*}}) : $@yield_once @convention(thin) (@guaranteed Builtin.NativeObject) -> @yields @inout Builtin.NativeObject +// CHECK: } // end sil function 'test_begin_apply_inout' +sil [ossa] @test_begin_apply_inout : $@convention(thin) (Builtin.Int32, @guaranteed Builtin.NativeObject) -> () { +bb0(%0 : $Builtin.Int32, %1 : @guaranteed $Builtin.NativeObject): + %f = function_ref @generic_begin_apply_callee_inout : $@yield_once @convention(thin) (@in_guaranteed T) -> @yields @inout T + + %0a = alloc_stack $Builtin.Int32 + store %0 to [trivial] %0a : $*Builtin.Int32 + (%0r, %0token) = begin_apply %f(%0a) : $@yield_once @convention(thin) (@in_guaranteed T) -> @yields @inout T + end_apply %0token + dealloc_stack %0a : $*Builtin.Int32 + + %1b = alloc_stack $Builtin.NativeObject + %1c = copy_value %1 : $Builtin.NativeObject + store %1c to [init] %1b : $*Builtin.NativeObject + (%1result, %1token) = begin_apply %f(%1b) : $@yield_once @convention(thin) (@in_guaranteed T) -> @yields @inout T + + end_apply %1token + destroy_addr %1b : $*Builtin.NativeObject + dealloc_stack %1b : $*Builtin.NativeObject + + %9999 = tuple() + return %9999 : $() +} diff --git a/test/SILOptimizer/specialize_reabstraction_ossa.sil b/test/SILOptimizer/specialize_reabstraction_ossa.sil new file mode 100644 index 0000000000000..916bc1797e5e0 --- /dev/null +++ b/test/SILOptimizer/specialize_reabstraction_ossa.sil @@ -0,0 +1,132 @@ +// RUN: %target-sil-opt -enable-sil-verify-all -generic-specializer -sil-generic-specializer-enable-ownership %s | %FileCheck %s + +sil_stage canonical + +import Builtin +import Swift + +public protocol RefProto { + associatedtype T + var me: Ref { get } +} + +public final class Ref : RefProto { + public final var me: Ref { get } + deinit + init() +} + +extension RefProto { + public func merge(other: Ref) -> Ref<(Self.T, U)> +} + +public protocol ValProto { + associatedtype T + var me: Val { get } +} + +extension ValProto { + public func merge(other: Val) -> Val<(Self.T, U)> +} + +public struct Val : ValProto { + public var me: Val { get } + init() +} + +sil @coerce : $@convention(thin) (@owned @callee_owned (@owned Ref) -> @owned @callee_owned (@owned Ref) -> @owned Ref) -> @owned @callee_owned (Val) -> Val + +sil [ossa] @merge : $@convention(method) (@owned Ref, @in_guaranteed Self) -> @owned Ref<(Self.T, U)> { +bb0(%0 : @owned $Ref, %1 : $*Self): + %2 = alloc_ref $Ref<(Self.T, U)> + destroy_value %0 : $Ref + return %2 : $Ref<(Self.T, U)> +} + +sil [ossa] @merge_curried : $@convention(thin) (@in Self) -> @owned @callee_owned (@owned Ref) -> @owned Ref<(Self.T, U)> { +bb0(%0 : $*Self): + %1 = function_ref @merge : $@convention(method) <τ_0_0 where τ_0_0 : RefProto><τ_1_0> (@owned Ref<τ_1_0>, @in_guaranteed τ_0_0) -> @owned Ref<(τ_0_0.T, τ_1_0)> + %2 = partial_apply %1(%0) : $@convention(method) <τ_0_0 where τ_0_0 : RefProto><τ_1_0> (@owned Ref<τ_1_0>, @in_guaranteed τ_0_0) -> @owned Ref<(τ_0_0.T, τ_1_0)> + return %2 : $@callee_owned (@owned Ref) -> @owned Ref<(Self.T, U)> +} + +sil [ossa] [reabstraction_thunk] @reabstract : $@convention(thin) (@owned Ref, @owned @callee_owned (@in Ref) -> @owned @callee_owned (@owned Ref) -> @owned Ref<(Self.T, U)>) -> @owned @callee_owned (@owned Ref) -> @owned Ref<(Self.T, U)> { +bb0(%0 : @owned $Ref, %1 : @owned $@callee_owned (@in Ref) -> @owned @callee_owned (@owned Ref) -> @owned Ref<(Self.T, U)>): + %2 = alloc_stack $Ref + store %0 to [init] %2 : $*Ref + %4 = apply %1(%2) : $@callee_owned (@in Ref) -> @owned @callee_owned (@owned Ref) -> @owned Ref<(Self.T, U)> + dealloc_stack %2 : $*Ref + return %4 : $@callee_owned (@owned Ref) -> @owned Ref<(Self.T, U)> +} + +// CHECK-LABEL: sil [ossa] @test +sil [ossa] @test : $@convention(thin) (Val, Val) -> Val<(Bool, Int)> { +// CHECK: bb0 +bb0(%0 : $Val, %1 : $Val): + // CHECK: [[COERCE:%.*]] = function_ref @coerce + %2 = function_ref @coerce : $@convention(thin) <τ_0_0, τ_0_1, τ_0_2> (@owned @callee_owned (@owned Ref<τ_0_0>) -> @owned @callee_owned (@owned Ref<τ_0_1>) -> @owned Ref<τ_0_2>) -> @owned @callee_owned (Val<τ_0_1>) -> Val<τ_0_2> + // CHECK: [[MERGE:%.*]] = function_ref @$s13merge_curried4main3RefCySbG_SiTg5 + %3 = function_ref @merge_curried : $@convention(thin) <τ_0_0 where τ_0_0 : RefProto><τ_1_0> (@in τ_0_0) -> @owned @callee_owned (@owned Ref<τ_1_0>) -> @owned Ref<(τ_0_0.T, τ_1_0)> + // CHECK: [[PARTIAL:%.*]] = partial_apply [[MERGE]]() + %4 = partial_apply %3, Int>() : $@convention(thin) <τ_0_0 where τ_0_0 : RefProto><τ_1_0> (@in τ_0_0) -> @owned @callee_owned (@owned Ref<τ_1_0>) -> @owned Ref<(τ_0_0.T, τ_1_0)> + // CHECK-NOT: function_ref @reabstract + %5 = function_ref @reabstract : $@convention(thin) <τ_0_0 where τ_0_0 : ValProto><τ_1_0> (@owned Ref<τ_0_0.T>, @owned @callee_owned (@in Ref<τ_0_0.T>) -> @owned @callee_owned (@owned Ref<τ_1_0>) -> @owned Ref<(τ_0_0.T, τ_1_0)>) -> @owned @callee_owned (@owned Ref<τ_1_0>) -> @owned Ref<(τ_0_0.T, τ_1_0)> + // CHECK-NOT: partial_apply + %6 = partial_apply %5, Int>(%4) : $@convention(thin) <τ_0_0 where τ_0_0 : ValProto><τ_1_0> (@owned Ref<τ_0_0.T>, @owned @callee_owned (@in Ref<τ_0_0.T>) -> @owned @callee_owned (@owned Ref<τ_1_0>) -> @owned Ref<(τ_0_0.T, τ_1_0)>) -> @owned @callee_owned (@owned Ref<τ_1_0>) -> @owned Ref<(τ_0_0.T, τ_1_0)> + // CHECK: apply [[COERCE]]([[PARTIAL]]) + %7 = apply %2(%6) : $@convention(thin) <τ_0_0, τ_0_1, τ_0_2> (@owned @callee_owned (@owned Ref<τ_0_0>) -> @owned @callee_owned (@owned Ref<τ_0_1>) -> @owned Ref<τ_0_2>) -> @owned @callee_owned (Val<τ_0_1>) -> Val<τ_0_2> + %8 = apply %7(%1) : $@callee_owned (Val) -> Val<(Bool, Int)> + return %8 : $Val<(Bool, Int)> +} + +// CHECK-LABEL: sil shared [ossa] @$s9coroutineSb_Tg5 : $@yield_once @convention(thin) (Bool) -> @yields @inout Bool { +// CHECK: bb0(%0 : $Bool): +// CHECK-NEXT: [[TEMP:%.*]] = alloc_stack $Bool +// CHECK-NEXT: store %0 to [trivial] [[TEMP]] : $*Bool +// CHECK-NEXT: yield [[TEMP]] : $*Bool, resume bb1, unwind bb2 +// CHECK: bb1: +// CHECK-NEXT: destroy_addr [[TEMP]] : $*Bool +// CHECK-NEXT: [[RV:%.*]] = tuple () +// CHECK-NEXT: dealloc_stack [[TEMP]] : $*Bool +// CHECK-NEXT: return [[RV]] : $() +// CHECK: bb2: +// CHECK-NEXT: destroy_addr [[TEMP]] : $*Bool +// CHECK-NEXT: dealloc_stack [[TEMP]] : $*Bool +// CHECK-NEXT: unwind +// CHECK-NEXT: } +sil [ossa] @coroutine : $@yield_once @convention(thin) (@in T) -> @yields @inout T { +bb0(%0 : $*T): + yield %0 : $*T, resume bb1, unwind bb2 +bb1: + destroy_addr %0 : $*T + %rv = tuple () + return %rv : $() +bb2: + destroy_addr %0 : $*T + unwind +} + +// CHECK-LABEL: @test_coroutine : $@convention(thin) (Bool) -> () { +// CHECK: bb0(%0 : $Bool): +// CHECK-NEXT: [[TEMP:%.*]] = alloc_stack $Bool +// CHECK-NEXT: store %0 to [trivial] [[TEMP]] : $*Bool +// CHECK-NEXT: // function_ref +// CHECK-NEXT: [[CORO:%.*]] = function_ref @$s9coroutineSb_Tg5 : $@yield_once @convention(thin) (Bool) -> @yields @inout Bool +// CHECK-NEXT: [[LOAD:%.*]] = load [trivial] [[TEMP]] : $*Bool +// CHECK-NEXT: ([[ADDR:%.*]], [[TOKEN:%.*]]) = begin_apply [[CORO]]([[LOAD]]) +// CHECK-NEXT: end_apply [[TOKEN]] +// CHECK-NEXT: dealloc_stack [[TEMP]] : $*Bool +// CHECK-NEXT: [[RV:%.*]] = tuple () +// CHECK-NEXT: return [[RV]] : $() +// CHECK-NEXT: } +sil [ossa] @test_coroutine : $@convention(thin) (Bool) -> () { +bb0(%0 : $Bool): + %coro = function_ref @coroutine : $@yield_once @convention(thin) (@in T) -> @yields @inout T + %temp = alloc_stack $Bool + store %0 to [trivial] %temp : $*Bool + (%addr, %token) = begin_apply %coro(%temp) : $@yield_once @convention(thin) (@in T) -> @yields @inout T + end_apply %token + dealloc_stack %temp : $*Bool + %rv = tuple () + return %rv : $() +} diff --git a/test/SILOptimizer/specialize_recursive_generics_ossa.sil b/test/SILOptimizer/specialize_recursive_generics_ossa.sil new file mode 100644 index 0000000000000..5bb75added371 --- /dev/null +++ b/test/SILOptimizer/specialize_recursive_generics_ossa.sil @@ -0,0 +1,150 @@ +// RUN: %target-sil-opt -enable-sil-verify-all %s -generic-specializer -cse -sil-generic-specializer-enable-ownership | %FileCheck %s + +// Check that SIL cloner can correctly handle specialization of recursive +// functions with generic arguments. + +sil_stage canonical + +import Builtin +import Swift + +// Check that this recursive function is specialized only for Int32. +// CHECK-LABEL: sil shared [noinline] [ossa] @$s62_TF29specialize_recursive_generics18recursive_genericsU__FQ_T_s5Int32V_Tg5 +// CHECK: function_ref @$s62_TF29specialize_recursive_generics18recursive_genericsU__FQ_T_s5Int32V_Tg5 +// CHECK: return +sil [noinline] [ossa] @_TF29specialize_recursive_generics18recursive_genericsU__FQ_T_ : $@convention(thin) (@in T) -> () { +bb0(%0 : $*T): + debug_value_addr %0 : $*T, let, name "t" // id: %1 + // function_ref specialize_recursive_generics.recursive_generics (A) -> () + %2 = function_ref @_TF29specialize_recursive_generics18recursive_genericsU__FQ_T_ : $@convention(thin) <τ_0_0> (@in τ_0_0) -> () // user: %5 + %3 = alloc_stack $T // users: %4, %5, %6 + copy_addr %0 to [initialization] %3 : $*T // id: %4 + %5 = apply %2(%3) : $@convention(thin) <τ_0_0> (@in τ_0_0) -> () + dealloc_stack %3 : $*T // id: %6 + destroy_addr %0 : $*T // id: %7 + %8 = tuple () // user: %9 + return %8 : $() // id: %9 +} + +// Check that this recursive function is specialized twice: for (Int, Double) and for (Double, Int). + +// CHECK-LABEL: sil shared [noinline] [ossa] @$s97_TF29specialize_recursive_generics47recursive_generics_with_different_substitutionsU___FTQ_Q0__T_Sd_s5Int32VTg5 +// CHECK: function_ref @$s97_TF29specialize_recursive_generics47recursive_generics_with_different_substitutionsU___FTQ_Q0__T_s5Int32V_SdTg5 +// CHECK: return + +// CHECK-LABEL: sil shared [noinline] [ossa] @$s97_TF29specialize_recursive_generics47recursive_generics_with_different_substitutionsU___FTQ_Q0__T_s5Int32V_SdTg5 +// CHECK: function_ref @$s97_TF29specialize_recursive_generics47recursive_generics_with_different_substitutionsU___FTQ_Q0__T_Sd_s5Int32VTg5 +// CHECK: return + + +sil [noinline] [ossa] @_TF29specialize_recursive_generics47recursive_generics_with_different_substitutionsU___FTQ_Q0__T_ : $@convention(thin) (@in T, @in U) -> () { +bb0(%0 : $*T, %1 : $*U): + debug_value_addr %0 : $*T, let, name "t" // id: %2 + debug_value_addr %1 : $*U, let, name "u" // id: %3 + // function_ref specialize_recursive_generics.recursive_generics_with_different_substitutions (A, B) -> () + %4 = function_ref @_TF29specialize_recursive_generics47recursive_generics_with_different_substitutionsU___FTQ_Q0__T_ : $@convention(thin) <τ_0_0, τ_0_1> (@in τ_0_0, @in τ_0_1) -> () // user: %9 + %5 = alloc_stack $U // users: %6, %9, %11 + copy_addr %1 to [initialization] %5 : $*U // id: %6 + %7 = alloc_stack $T // users: %8, %9, %10 + copy_addr %0 to [initialization] %7 : $*T // id: %8 + %9 = apply %4(%5, %7) : $@convention(thin) <τ_0_0, τ_0_1> (@in τ_0_0, @in τ_0_1) -> () + dealloc_stack %7 : $*T // id: %10 + dealloc_stack %5 : $*U // id: %11 + destroy_addr %1 : $*U // id: %12 + destroy_addr %0 : $*T // id: %13 + %14 = tuple () // user: %15 + return %14 : $() // id: %15 +} + +sil [ossa] @$s29specialize_recursive_generics05test_b1_C0yyF : $@convention(thin) () -> () { +bb0: + // function_ref specialize_recursive_generics.recursive_generics (A) -> () + %0 = function_ref @_TF29specialize_recursive_generics18recursive_genericsU__FQ_T_ : $@convention(thin) <τ_0_0> (@in τ_0_0) -> () // user: %5 + %1 = integer_literal $Builtin.Int32, 3 // user: %2 + %2 = struct $Int32 (%1 : $Builtin.Int32) // user: %4 + %3 = alloc_stack $Int32 // users: %4, %5, %6 + store %2 to [trivial] %3 : $*Int32 // id: %4 + %5 = apply %0(%3) : $@convention(thin) <τ_0_0> (@in τ_0_0) -> () + dealloc_stack %3 : $*Int32 // id: %6 + %7 = tuple () // user: %8 + return %7 : $() // id: %8 +} + +sil [ossa] @$s29specialize_recursive_generics05test_b1_C29_with_different_substitutionsyyF : $@convention(thin) () -> () { +bb0: + // function_ref specialize_recursive_generics.recursive_generics_with_different_substitutions (A, B) -> () + %0 = function_ref @_TF29specialize_recursive_generics47recursive_generics_with_different_substitutionsU___FTQ_Q0__T_ : $@convention(thin) <τ_0_0, τ_0_1> (@in τ_0_0, @in τ_0_1) -> () // user: %10 + %1 = float_literal $Builtin.FPIEEE80, 0x3FFF999999999999999A // 1.20000000000000000004 // user: %2 + %2 = builtin "fptrunc_FPIEEE80_FPIEEE64"(%1 : $Builtin.FPIEEE80) : $Builtin.FPIEEE64 // user: %3 + %3 = struct $Double (%2 : $Builtin.FPIEEE64) // user: %5 + %4 = alloc_stack $Double // users: %5, %10, %12 + store %3 to [trivial] %4 : $*Double // id: %5 + %6 = integer_literal $Builtin.Int32, 1 // user: %7 + %7 = struct $Int32 (%6 : $Builtin.Int32) // user: %9 + %8 = alloc_stack $Int32 // users: %9, %10, %11 + store %7 to [trivial] %8 : $*Int32 // id: %9 + %10 = apply %0(%4, %8) : $@convention(thin) <τ_0_0, τ_0_1> (@in τ_0_0, @in τ_0_1) -> () + dealloc_stack %8 : $*Int32 // id: %11 + dealloc_stack %4 : $*Double // id: %12 + %13 = tuple () // user: %14 + return %13 : $() // id: %14 +} + + +public class C : P {} + +public protocol P {} + +sil hidden [ossa] [noinline] @helper : $@convention(thin) (@in T, @in P) -> @owned Optional { +bb0(%0 : $*T, %1 : $*P): + %4 = alloc_stack $P + copy_addr %1 to [initialization] %4 : $*P + %6 = alloc_stack $C + checked_cast_addr_br take_always P in %4 : $*P to C in %6 : $*C, bb1, bb2 +bb1: + %8 = load [take] %6 : $*C + %9 = enum $Optional, #Optional.some!enumelt, %8 : $C + dealloc_stack %6 : $*C + br bb3(%9 : $Optional) + +bb2: + %12 = enum $Optional, #Optional.none!enumelt + dealloc_stack %6 : $*C + br bb3(%12 : $Optional) + +bb3(%15 : @owned $Optional): + dealloc_stack %4 : $*P + destroy_addr %1 : $*P + destroy_addr %0 : $*T + return %15 : $Optional +} + +// CHECK-LABEL: sil shared [ossa] @$s6lookup4main1CC_Tg5 +sil [ossa] @lookup : $@convention(method) (@owned C, @in_guaranteed Self) -> @owned Optional { +bb0(%0 : @owned $C, %1 : $*Self): + // CHECK: [[HELPER:%.*]] = function_ref @$s6helpers5Int32V_Tg5 + %4 = function_ref @helper : $@convention(thin) <τ_0_0> (@in τ_0_0, @in P) -> @owned Optional + %5 = integer_literal $Builtin.Int32, 1 + %6 = struct $Int32 (%5 : $Builtin.Int32) + %7 = alloc_stack $Int32 + store %6 to [trivial] %7 : $*Int32 + %9 = alloc_stack $P + %10 = init_existential_addr %9 : $*P, $Self + copy_addr %1 to [initialization] %10 : $*Self + // CHECK: apply [[HELPER]] + // CHECK-NOT: apply [[HELPER]] + %12 = apply %4(%7, %9) : $@convention(thin) <τ_0_0> (@in τ_0_0, @in P) -> @owned Optional + destroy_value %12 : $Optional + dealloc_stack %9 : $*P + dealloc_stack %7 : $*Int32 + // CHECK: [[LOOKUP:%.*]] = function_ref @$s6lookup4main1CC_Tg5 + %16 = function_ref @lookup : $@convention(method) <τ_0_0 where τ_0_0 : P> (@owned C, @in_guaranteed τ_0_0) -> @owned Optional + %17 = alloc_stack $C + %0c = copy_value %0 : $C + store %0c to [init] %17 : $*C + // CHECK: apply [[LOOKUP]] + %20 = apply %16(%0, %17) : $@convention(method) <τ_0_0 where τ_0_0 : P> (@owned C, @in_guaranteed τ_0_0) -> @owned Optional + destroy_addr %17 : $*C + dealloc_stack %17 : $*C + return %20 : $Optional +} diff --git a/test/Sema/Inputs/availability_multi_other.swift b/test/Sema/Inputs/availability_multi_other.swift index 193cd27acac1b..ccd1c58e88f25 100644 --- a/test/Sema/Inputs/availability_multi_other.swift +++ b/test/Sema/Inputs/availability_multi_other.swift @@ -3,88 +3,88 @@ // validate declarations when resolving declaration signatures. // This file relies on the minimum deployment target for OS X being 10.9. -@available(OSX, introduced: 10.52) -private class PrivateIntroduced10_52 { } +@available(OSX, introduced: 99.52) +private class PrivateIntroduced99_52 { } class OtherIntroduced10_9 { } -@available(OSX, introduced: 10.51) -class OtherIntroduced10_51 { - func uses10_52() { +@available(OSX, introduced: 99.51) +class OtherIntroduced99_51 { + func uses99_52() { // If this were the primary file then the below would emit an error, because - // PrivateIntroduced10_53 is not available on 10.52. But since we only + // PrivateIntroduced99_53 is not available on 99.52. But since we only // run the first pass of the type checker on these declarations, // the body is not checked. - _ = PrivateIntroduced10_52() + _ = PrivateIntroduced99_52() } - // This method uses a 10_52 only type in its signature, so validating + // This method uses a 99_52 only type in its signature, so validating // the declaration should produce an availability error - func returns10_52() -> OtherIntroduced10_52 { // expected-error {{'OtherIntroduced10_52' is only available in macOS 10.52 or newer}} + func returns99_52() -> OtherIntroduced99_52 { // expected-error {{'OtherIntroduced99_52' is only available in macOS 99.52 or newer}} // expected-note@-1 {{add @available attribute to enclosing instance method}} // Body is not type checked (by design) so no error is expected for unavailable type used in return. - return OtherIntroduced10_52() + return OtherIntroduced99_52() } - @available(OSX, introduced: 10.52) - func returns10_52Introduced10_52() -> OtherIntroduced10_52 { - return OtherIntroduced10_52() + @available(OSX, introduced: 99.52) + func returns99_52Introduced99_52() -> OtherIntroduced99_52 { + return OtherIntroduced99_52() } - func takes10_52(o: OtherIntroduced10_52) { + func takes99_52(o: OtherIntroduced99_52) { } - @available(OSX, introduced: 10.52) - func takes10_52Introduced10_52(o: OtherIntroduced10_52) { + @available(OSX, introduced: 99.52) + func takes99_52Introduced99_52(o: OtherIntroduced99_52) { } - var propOf10_52: OtherIntroduced10_52 = + var propOf99_52: OtherIntroduced99_52 = - OtherIntroduced10_52() // We don't expect an error here because the initializer is not type checked (by design). + OtherIntroduced99_52() // We don't expect an error here because the initializer is not type checked (by design). - @available(OSX, introduced: 10.52) - var propOf10_52Introduced10_52: OtherIntroduced10_52 = OtherIntroduced10_52() + @available(OSX, introduced: 99.52) + var propOf99_52Introduced99_52: OtherIntroduced99_52 = OtherIntroduced99_52() - @available(OSX, introduced: 10.52) - class NestedIntroduced10_52 : OtherIntroduced10_52 { - override func returns10_52() -> OtherIntroduced10_52 { + @available(OSX, introduced: 99.52) + class NestedIntroduced99_52 : OtherIntroduced99_52 { + override func returns99_52() -> OtherIntroduced99_52 { } - @available(OSX, introduced: 10.53) - func returns10_53() -> OtherIntroduced10_53 { + @available(OSX, introduced: 99.53) + func returns99_53() -> OtherIntroduced99_53 { } } } -@available(OSX, introduced: 10.51) -class SubOtherIntroduced10_51 : OtherIntroduced10_51 { +@available(OSX, introduced: 99.51) +class SubOtherIntroduced99_51 : OtherIntroduced99_51 { } -@available(OSX, introduced: 10.52) -class OtherIntroduced10_52 : OtherIntroduced10_51 { +@available(OSX, introduced: 99.52) +class OtherIntroduced99_52 : OtherIntroduced99_51 { } -extension OtherIntroduced10_51 { +extension OtherIntroduced99_51 { } extension OtherIntroduced10_9 { - @available(OSX, introduced: 10.51) - func extensionMethodOnOtherIntroduced10_9AvailableOn10_51(_ p: OtherIntroduced10_51) { } + @available(OSX, introduced: 99.51) + func extensionMethodOnOtherIntroduced10_9AvailableOn99_51(_ p: OtherIntroduced99_51) { } } -@available(OSX, introduced: 10.51) -extension OtherIntroduced10_51 { - func extensionMethodOnOtherIntroduced10_51() { } +@available(OSX, introduced: 99.51) +extension OtherIntroduced99_51 { + func extensionMethodOnOtherIntroduced99_51() { } - @available(OSX, introduced: 10.52) - func extensionMethodOnOtherIntroduced10_51AvailableOn10_52() { } + @available(OSX, introduced: 99.52) + func extensionMethodOnOtherIntroduced99_51AvailableOn99_52() { } } -@available(OSX, introduced: 10.53) -class OtherIntroduced10_53 { +@available(OSX, introduced: 99.53) +class OtherIntroduced99_53 { } -var globalFromOtherOn10_52 : OtherIntroduced10_52? = nil // expected-error {{'OtherIntroduced10_52' is only available in macOS 10.52 or newer}} +var globalFromOtherOn99_52 : OtherIntroduced99_52? = nil // expected-error {{'OtherIntroduced99_52' is only available in macOS 99.52 or newer}} // expected-note@-1 {{add @available attribute to enclosing var}} diff --git a/test/Sema/availability_versions.swift b/test/Sema/availability_versions.swift index f757798b86b5a..e3adcb811d4cc 100644 --- a/test/Sema/availability_versions.swift +++ b/test/Sema/availability_versions.swift @@ -1,8 +1,8 @@ -// RUN: %target-typecheck-verify-swift -target x86_64-apple-macosx10.50 -disable-objc-attr-requires-foundation-module -// RUN: not %target-swift-frontend -target x86_64-apple-macosx10.50 -disable-objc-attr-requires-foundation-module -typecheck %s 2>&1 | %FileCheck %s '--implicit-check-not=:0' +// RUN: %target-typecheck-verify-swift -target %target-cpu-apple-macosx10.50 -disable-objc-attr-requires-foundation-module +// RUN: not %target-swift-frontend -target %target-cpu-apple-macosx10.50 -disable-objc-attr-requires-foundation-module -typecheck %s 2>&1 | %FileCheck %s '--implicit-check-not=:0' // Make sure we do not emit availability errors or warnings when -disable-availability-checking is passed -// RUN: not %target-swift-frontend -target x86_64-apple-macosx10.50 -typecheck -disable-objc-attr-requires-foundation-module -disable-availability-checking %s 2>&1 | %FileCheck %s '--implicit-check-not=error:' '--implicit-check-not=warning:' +// RUN: not %target-swift-frontend -target %target-cpu-apple-macosx10.50 -typecheck -disable-objc-attr-requires-foundation-module -disable-availability-checking %s 2>&1 | %FileCheck %s '--implicit-check-not=error:' '--implicit-check-not=warning:' // REQUIRES: OS=macosx diff --git a/test/Sema/availability_versions_canonical_macos.swift b/test/Sema/availability_versions_canonical_macos.swift new file mode 100644 index 0000000000000..fb18d412aa22f --- /dev/null +++ b/test/Sema/availability_versions_canonical_macos.swift @@ -0,0 +1,14 @@ +// RUN: %target-typecheck-verify-swift -target %target-cpu-apple-macosx10.15 -disable-objc-attr-requires-foundation-module + +// REQUIRES: OS=macosx + +func markUsed(_ t: T) {} + +@available(OSX 10.16, *) +func introducedOn10_16() { } + +func useUnderPoundAvailable() { + if #available(OSX 10.16, *) { + introducedOn10_16() // no-error + } +} diff --git a/test/Sema/availability_versions_multi.swift b/test/Sema/availability_versions_multi.swift index d471eaa5014d9..89e61cbb7528b 100644 --- a/test/Sema/availability_versions_multi.swift +++ b/test/Sema/availability_versions_multi.swift @@ -8,54 +8,54 @@ callToEnsureNotInScriptMode() // expected-error {{expressions are not allowed at @available(OSX, introduced: 10.9) var globalAvailableOn10_9: Int = 9 -@available(OSX, introduced: 10.51) -var globalAvailableOn10_51: Int = 10 +@available(OSX, introduced: 99.51) +var globalAvailableOn99_51: Int = 10 -@available(OSX, introduced: 10.52) -var globalAvailableOn10_52: Int = 11 +@available(OSX, introduced: 99.52) +var globalAvailableOn99_52: Int = 11 // Top level should reflect the minimum deployment target. let ignored1: Int = globalAvailableOn10_9 -let ignored2: Int = globalAvailableOn10_51 // expected-error {{'globalAvailableOn10_51' is only available in macOS 10.51 or newer}} +let ignored2: Int = globalAvailableOn99_51 // expected-error {{'globalAvailableOn99_51' is only available in macOS 99.51 or newer}} // expected-note@-1 {{add @available attribute to enclosing let}} -let ignored3: Int = globalAvailableOn10_52 // expected-error {{'globalAvailableOn10_52' is only available in macOS 10.52 or newer}} +let ignored3: Int = globalAvailableOn99_52 // expected-error {{'globalAvailableOn99_52' is only available in macOS 99.52 or newer}} // expected-note@-1 {{add @available attribute to enclosing let}} -@available(OSX, introduced: 10.51) -func useFromOtherOn10_51() { - // This will trigger validation of OtherIntroduced10_51 in +@available(OSX, introduced: 99.51) +func useFromOtherOn99_51() { + // This will trigger validation of OtherIntroduced99_51 in // in availability_multi_other.swift - let o10_51 = OtherIntroduced10_51() - o10_51.extensionMethodOnOtherIntroduced10_51() + let o99_51 = OtherIntroduced99_51() + o99_51.extensionMethodOnOtherIntroduced99_51() let o10_9 = OtherIntroduced10_9() - o10_9.extensionMethodOnOtherIntroduced10_9AvailableOn10_51(o10_51) - _ = o10_51.returns10_52Introduced10_52() // expected-error {{'returns10_52Introduced10_52()' is only available in macOS 10.52 or newer}} + o10_9.extensionMethodOnOtherIntroduced10_9AvailableOn99_51(o99_51) + _ = o99_51.returns99_52Introduced99_52() // expected-error {{'returns99_52Introduced99_52()' is only available in macOS 99.52 or newer}} // expected-note@-1 {{add 'if #available' version check}} - _ = OtherIntroduced10_52() - // expected-error@-1 {{'OtherIntroduced10_52' is only available in macOS 10.52 or newer}} + _ = OtherIntroduced99_52() + // expected-error@-1 {{'OtherIntroduced99_52' is only available in macOS 99.52 or newer}} // expected-note@-2 {{add 'if #available' version check}} - o10_51.extensionMethodOnOtherIntroduced10_51AvailableOn10_52() // expected-error {{'extensionMethodOnOtherIntroduced10_51AvailableOn10_52()' is only available in macOS 10.52 or newer}} + o99_51.extensionMethodOnOtherIntroduced99_51AvailableOn99_52() // expected-error {{'extensionMethodOnOtherIntroduced99_51AvailableOn99_52()' is only available in macOS 99.52 or newer}} // expected-note@-1 {{add 'if #available' version check}} - _ = OtherIntroduced10_51.NestedIntroduced10_52() - // expected-error@-1 {{'NestedIntroduced10_52' is only available in macOS 10.52 or newer}} + _ = OtherIntroduced99_51.NestedIntroduced99_52() + // expected-error@-1 {{'NestedIntroduced99_52' is only available in macOS 99.52 or newer}} // expected-note@-2 {{add 'if #available' version check}} } -@available(OSX, introduced: 10.52) -func useFromOtherOn10_52() { - _ = OtherIntroduced10_52() +@available(OSX, introduced: 99.52) +func useFromOtherOn99_52() { + _ = OtherIntroduced99_52() - let n10_52 = OtherIntroduced10_51.NestedIntroduced10_52() - _ = n10_52.returns10_52() - _ = n10_52.returns10_53() // expected-error {{'returns10_53()' is only available in macOS 10.53 or newer}} + let n99_52 = OtherIntroduced99_51.NestedIntroduced99_52() + _ = n99_52.returns99_52() + _ = n99_52.returns99_53() // expected-error {{'returns99_53()' is only available in macOS 99.53 or newer}} // expected-note@-1 {{add 'if #available' version check}} // This will trigger validation of the global in availability_in_multi_other.swift - _ = globalFromOtherOn10_52 + _ = globalFromOtherOn99_52 } diff --git a/test/Sema/deprecation_osx.swift b/test/Sema/deprecation_osx.swift index d25f8ab7c5e5b..84a48bd81325e 100644 --- a/test/Sema/deprecation_osx.swift +++ b/test/Sema/deprecation_osx.swift @@ -1,5 +1,5 @@ -// RUN: %swift -typecheck -parse-as-library -target x86_64-apple-macosx10.51 %clang-importer-sdk -I %S/Inputs/custom-modules %s -verify -// RUN: %swift -typecheck -parse-as-library -target x86_64-apple-macosx10.51 %clang-importer-sdk -I %S/Inputs/custom-modules %s 2>&1 | %FileCheck %s '--implicit-check-not=:0' +// RUN: %swift -typecheck -parse-as-library -target %target-cpu-apple-macosx10.51 %clang-importer-sdk -I %S/Inputs/custom-modules %s -verify +// RUN: %swift -typecheck -parse-as-library -target %target-cpu-apple-macosx10.51 %clang-importer-sdk -I %S/Inputs/custom-modules %s 2>&1 | %FileCheck %s '--implicit-check-not=:0' // // This test requires a target of OS X 10.51 or later to test deprecation // diagnostics because (1) we only emit deprecation warnings if a symbol is diff --git a/test/Serialization/target-too-new.swift b/test/Serialization/target-too-new.swift index d2cd2633941f2..62c0916a9a0ab 100644 --- a/test/Serialization/target-too-new.swift +++ b/test/Serialization/target-too-new.swift @@ -1,16 +1,16 @@ // RUN: %empty-directory(%t) -// RUN: %target-swift-frontend -target x86_64-apple-macosx10.50 -emit-module -parse-stdlib %S/../Inputs/empty.swift -o %t -// RUN: not %target-swift-frontend -I %t -target x86_64-apple-macosx10.9 -typecheck %s 2>&1 | %FileCheck %s -// RUN: not %target-swift-frontend -I %t -target x86_64-apple-darwin13 -typecheck %s 2>&1 | %FileCheck %s +// RUN: %target-swift-frontend -target %target-cpu-apple-macosx10.50 -emit-module -parse-stdlib %S/../Inputs/empty.swift -o %t +// RUN: not %target-swift-frontend -I %t -target %target-cpu-apple-macosx10.9 -typecheck %s 2>&1 | %FileCheck %s +// RUN: not %target-swift-frontend -I %t -target %target-cpu-apple-darwin13 -typecheck %s 2>&1 | %FileCheck %s // RUN: %target-swift-frontend -I %t -typecheck %s -disable-target-os-checking -// RUN: %target-swift-frontend -target x86_64-apple-macosx10.50 -I %t -typecheck %s -// RUN: %target-swift-frontend -target x86_64-apple-macosx10.50.1 -I %t -typecheck %s +// RUN: %target-swift-frontend -target %target-cpu-apple-macosx10.50 -I %t -typecheck %s +// RUN: %target-swift-frontend -target %target-cpu-apple-macosx10.50.1 -I %t -typecheck %s // Allow any version when built with resilience. (Really we should encode a // "minimum supported OS", but we don't have that information today.) -// RUN: %target-swift-frontend -target x86_64-apple-macosx10.50 -emit-module -parse-stdlib %S/../Inputs/empty.swift -enable-library-evolution -o %t -// RUN: %target-swift-frontend -I %t -target x86_64-apple-macosx10.9 -typecheck %s -// RUN: %target-swift-frontend -I %t -target x86_64-apple-darwin13 -typecheck %s +// RUN: %target-swift-frontend -target %target-cpu-apple-macosx10.50 -emit-module -parse-stdlib %S/../Inputs/empty.swift -enable-library-evolution -o %t +// RUN: %target-swift-frontend -I %t -target %target-cpu-apple-macosx10.9 -typecheck %s +// RUN: %target-swift-frontend -I %t -target %target-cpu-apple-darwin13 -typecheck %s // REQUIRES: OS=macosx diff --git a/test/SourceKit/InterfaceGen/gen_clang_module.swift b/test/SourceKit/InterfaceGen/gen_clang_module.swift index 7c92eb4fe74ad..d97fc0b498eed 100644 --- a/test/SourceKit/InterfaceGen/gen_clang_module.swift +++ b/test/SourceKit/InterfaceGen/gen_clang_module.swift @@ -69,7 +69,7 @@ var x: FooClassBase // RUN: -target %target-triple %clang-importer-sdk-nosource -I %t | %FileCheck -check-prefix=CHECK-IFACE %s // CHECK-IFACE: DOC: (/) -// CHECK-IFACE: ARGS: [-target x86_64-{{.*}} -sdk {{.*}} -F {{.*}}/libIDE-mock-sdk -I {{.*}}.overlays {{.*}} -module-cache-path {{.*}} ] +// CHECK-IFACE: ARGS: [-target {{.*}}-{{.*}} -sdk {{.*}} -F {{.*}}/libIDE-mock-sdk -I {{.*}}.overlays {{.*}} -module-cache-path {{.*}} ] // RUN: %sourcekitd-test -req=interface-gen-open -module Foo -- -I %t.overlays -F %S/../Inputs/libIDE-mock-sdk \ // RUN: -target %target-triple %clang-importer-sdk-nosource -I %t \ diff --git a/test/SourceKit/Misc/resource-dir-handling.swift b/test/SourceKit/Misc/resource-dir-handling.swift index a4a1f66d5b87e..74d70cb82398d 100644 --- a/test/SourceKit/Misc/resource-dir-handling.swift +++ b/test/SourceKit/Misc/resource-dir-handling.swift @@ -5,8 +5,8 @@ var p: CoolInt // RUN: %empty-directory(%t) // RUN: %empty-directory(%t/custom-resource-dir/macosx/Swift.swiftmodule) -// RUN: %target-swift-frontend -emit-module -module-name Swift -parse-stdlib -target x86_64-apple-macosx10.12 %S/Inputs/custom-resource-stdlib.swift -o %t/custom-resource-dir/macosx/Swift.swiftmodule/%target-swiftmodule-name -// RUN: %sourcekitd-test -req=cursor -pos=3:8 %s -- -resource-dir %t/custom-resource-dir -target x86_64-apple-macosx10.12 %s | %FileCheck %s +// RUN: %target-swift-frontend -emit-module -module-name Swift -parse-stdlib -target %target-cpu-apple-macosx10.12 %S/Inputs/custom-resource-stdlib.swift -o %t/custom-resource-dir/macosx/Swift.swiftmodule/%target-swiftmodule-name +// RUN: %sourcekitd-test -req=cursor -pos=3:8 %s -- -resource-dir %t/custom-resource-dir -target %target-cpu-apple-macosx10.12 %s | %FileCheck %s // CHECK: source.lang.swift.ref.struct // CHECK-NEXT: CoolInt diff --git a/test/TBD/app-extension.swift b/test/TBD/app-extension.swift index 9fe43bb68ac99..8bdf74b852d51 100644 --- a/test/TBD/app-extension.swift +++ b/test/TBD/app-extension.swift @@ -9,7 +9,7 @@ // EXTENSIONSAFE-NOT: not_app_extension_safe // NOTEXTENSIONSAFE: not_app_extension_safe -// RUN: %target-swift-frontend -target-variant x86_64-apple-ios13.0-macabi -typecheck %s -application-extension -emit-tbd -emit-tbd-path %t/target-variant.tbd +// RUN: %target-swift-frontend -target-variant %target-cpu-apple-ios13.0-macabi -typecheck %s -application-extension -emit-tbd -emit-tbd-path %t/target-variant.tbd // RUN: %FileCheck %s --check-prefix MACABI < %t/target-variant.tbd // MACABI: targets: [ {{.*}}macos{{.*}}maccatalyst{{.*}} ] diff --git a/test/api-digester/Inputs/mock-sdk-baseline.sdk/System/Library/Frameworks/SwiftFoo.framework/Modules/SwiftFoo.swiftmodule/arm64-apple-macos.swiftinterface b/test/api-digester/Inputs/mock-sdk-baseline.sdk/System/Library/Frameworks/SwiftFoo.framework/Modules/SwiftFoo.swiftmodule/arm64-apple-macos.swiftinterface new file mode 100644 index 0000000000000..04fba0eeed4da --- /dev/null +++ b/test/api-digester/Inputs/mock-sdk-baseline.sdk/System/Library/Frameworks/SwiftFoo.framework/Modules/SwiftFoo.swiftmodule/arm64-apple-macos.swiftinterface @@ -0,0 +1,7 @@ +// swift-interface-format-version: 1.0 +// swift-tools-version: Apple Swift version 5.1 (swiftlang-1100.0.38 clang-1100.0.20.14) +// swift-module-flags: -target arm64-apple-macos10.14 -enable-objc-interop -enable-library-evolution -swift-version 5 -enforce-exclusivity=checked -O -module-name SwiftFoo +import Swift +public class RemovedClass { + @objc deinit +} diff --git a/test/api-digester/Inputs/mock-sdk.sdk/System/Library/Frameworks/SwiftFoo.framework/Modules/SwiftFoo.swiftmodule/arm64-apple-macos.swiftinterface b/test/api-digester/Inputs/mock-sdk.sdk/System/Library/Frameworks/SwiftFoo.framework/Modules/SwiftFoo.swiftmodule/arm64-apple-macos.swiftinterface new file mode 100644 index 0000000000000..606b8bd222422 --- /dev/null +++ b/test/api-digester/Inputs/mock-sdk.sdk/System/Library/Frameworks/SwiftFoo.framework/Modules/SwiftFoo.swiftmodule/arm64-apple-macos.swiftinterface @@ -0,0 +1,7 @@ +// swift-interface-format-version: 1.0 +// swift-tools-version: Apple Swift version 5.1 (swiftlang-1100.0.38 clang-1100.0.20.14) +// swift-module-flags: -target arm64-apple-macos10.14 -enable-objc-interop -enable-library-evolution -swift-version 5 -enforce-exclusivity=checked -O -module-name SwiftFoo +import Swift +public class AddedClass { + @objc deinit +} diff --git a/test/api-digester/Outputs/stability-stdlib-source-arm64.swift.expected b/test/api-digester/Outputs/stability-stdlib-source-arm64.swift.expected new file mode 100644 index 0000000000000..902afdfd72c19 --- /dev/null +++ b/test/api-digester/Outputs/stability-stdlib-source-arm64.swift.expected @@ -0,0 +1,27 @@ +Constructor BinaryFloatingPoint.init(_:) has been removed +Constructor Double.init(_:) has parameter 0 type change from Swift.Float80 to Swift.Float16 +Constructor Double.init(exactly:) has parameter 0 type change from Swift.Float80 to Swift.Float16 +Constructor Float.init(_:) has parameter 0 type change from Swift.Float80 to Swift.Float16 +Constructor Float.init(exactly:) has parameter 0 type change from Swift.Float80 to Swift.Float16 +Constructor Int.init(_:) has parameter 0 type change from Swift.Float80 to Swift.Float16 +Constructor Int.init(exactly:) has parameter 0 type change from Swift.Float80 to Swift.Float16 +Constructor Int16.init(_:) has parameter 0 type change from Swift.Float80 to Swift.Float16 +Constructor Int16.init(exactly:) has parameter 0 type change from Swift.Float80 to Swift.Float16 +Constructor Int32.init(_:) has parameter 0 type change from Swift.Float80 to Swift.Float16 +Constructor Int32.init(exactly:) has parameter 0 type change from Swift.Float80 to Swift.Float16 +Constructor Int64.init(_:) has parameter 0 type change from Swift.Float80 to Swift.Float16 +Constructor Int64.init(exactly:) has parameter 0 type change from Swift.Float80 to Swift.Float16 +Constructor Int8.init(_:) has parameter 0 type change from Swift.Float80 to Swift.Float16 +Constructor Int8.init(exactly:) has parameter 0 type change from Swift.Float80 to Swift.Float16 +Constructor UInt.init(_:) has parameter 0 type change from Swift.Float80 to Swift.Float16 +Constructor UInt.init(exactly:) has parameter 0 type change from Swift.Float80 to Swift.Float16 +Constructor UInt16.init(_:) has parameter 0 type change from Swift.Float80 to Swift.Float16 +Constructor UInt16.init(exactly:) has parameter 0 type change from Swift.Float80 to Swift.Float16 +Constructor UInt32.init(_:) has parameter 0 type change from Swift.Float80 to Swift.Float16 +Constructor UInt32.init(exactly:) has parameter 0 type change from Swift.Float80 to Swift.Float16 +Constructor UInt64.init(_:) has parameter 0 type change from Swift.Float80 to Swift.Float16 +Constructor UInt64.init(exactly:) has parameter 0 type change from Swift.Float80 to Swift.Float16 +Constructor UInt8.init(_:) has parameter 0 type change from Swift.Float80 to Swift.Float16 +Constructor UInt8.init(exactly:) has parameter 0 type change from Swift.Float80 to Swift.Float16 +Struct Float80 has been removed +TypeAlias CLongDouble has underlying type change from Swift.Float80 to Swift.Double diff --git a/test/api-digester/Outputs/stability-stdlib-source.swift.expected b/test/api-digester/Outputs/stability-stdlib-source-x86_64.swift.expected similarity index 100% rename from test/api-digester/Outputs/stability-stdlib-source.swift.expected rename to test/api-digester/Outputs/stability-stdlib-source-x86_64.swift.expected diff --git a/test/api-digester/stability-stdlib-source.swift b/test/api-digester/stability-stdlib-source.swift index 32934342910d4..f0e383a5cc2c2 100644 --- a/test/api-digester/stability-stdlib-source.swift +++ b/test/api-digester/stability-stdlib-source.swift @@ -2,6 +2,6 @@ // RUN: %empty-directory(%t.tmp) // mkdir %t.tmp/module-cache && mkdir %t.tmp/dummy.sdk // RUN: %api-digester -diagnose-sdk -module Swift -o %t.tmp/changes.txt -module-cache-path %t.tmp/module-cache -sdk %t.tmp/dummy.sdk -avoid-location -// RUN: %clang -E -P -x c %S/Outputs/stability-stdlib-source.swift.expected -o - | sed '/^\s*$/d' | sort > %t.tmp/stability-stdlib-source.swift.expected +// RUN: %clang -E -P -x c %S/Outputs/stability-stdlib-source-%target-cpu.swift.expected -o - | sed '/^\s*$/d' | sort > %t.tmp/stability-stdlib-source.swift.expected // RUN: %clang -E -P -x c %t.tmp/changes.txt -o - | sed '/^\s*$/d' | sort > %t.tmp/changes.txt.tmp // RUN: diff -u %t.tmp/stability-stdlib-source.swift.expected %t.tmp/changes.txt.tmp diff --git a/test/attr/attr_availability_canonical_macos_version.swift b/test/attr/attr_availability_canonical_macos_version.swift new file mode 100644 index 0000000000000..10cf92286e255 --- /dev/null +++ b/test/attr/attr_availability_canonical_macos_version.swift @@ -0,0 +1,41 @@ +// RUN: %swift -typecheck -verify -parse-stdlib -module-name Swift -target x86_64-apple-macosx11.0 %s + + +@available(OSX, introduced: 10.5, deprecated: 10.8, obsoleted: 11.0, + message: "you don't want to do that anyway") +func obsoletedIn11() { } +// expected-note @-1{{'obsoletedIn11()' was obsoleted in macOS 11.0}} + +obsoletedIn11() // expected-error{{'obsoletedIn11()' is unavailable in macOS: you don't want to do that anyway}} + + +@available(OSX, introduced: 10.5, deprecated: 10.8, obsoleted: 10.16, + message: "you don't want to do that anyway") +func obsoletedIn10_16() { } +// expected-note @-1{{'obsoletedIn10_16()' was obsoleted in macOS 11.0}} + +obsoletedIn10_16() // expected-error{{'obsoletedIn10_16()' is unavailable in macOS: you don't want to do that anyway}} + + +@available(OSX, deprecated: 10.16) +func deprecatedIn10_16() { } + +@available(OSX, deprecated: 10.18) +func deprecatedIn10_18() { } + +@available(OSX, deprecated: 11.0) +func deprecatedIn11_0() { } + +@available(OSX, deprecated: 13.0) +func deprecatedIn13_0() { } + +@available(OSXApplicationExtension, deprecated: 10.16) +func deprecatedIn10_16AppExtension() { } + +func useDeprecated() { + deprecatedIn10_16() // expected-warning {{deprecatedIn10_16()' was deprecated in macOS 11.0}} + deprecatedIn10_18() // expected-warning {{'deprecatedIn10_18()' was deprecated in macOS 10.18}} + deprecatedIn11_0() // expected-warning {{'deprecatedIn11_0()' was deprecated in macOS 11.0}} + + deprecatedIn13_0() // no-warning +} diff --git a/test/attr/attr_availability_canonical_macos_version_introduction.swift b/test/attr/attr_availability_canonical_macos_version_introduction.swift new file mode 100644 index 0000000000000..69409ec882144 --- /dev/null +++ b/test/attr/attr_availability_canonical_macos_version_introduction.swift @@ -0,0 +1,61 @@ +// RUN: %swift -typecheck -verify -parse-stdlib -module-name Swift -target x86_64-apple-macosx10.15 %s + +@available(OSX, introduced: 10.16) +func longFormIntroducedIn10_16() { } + +@available(OSX, introduced: 10.18) +func longFormIntroducedIn10_18() { } + +@available(OSX, introduced: 11.0) +func longFormIntroducedIn11_0() { } + +@available(OSX, introduced: 13.0) +func longFormIntroducedIn13_0() { } + +// expected-note@+1 *{{add @available attribute to enclosing global function}} +func useLongFromIntroduced() { + longFormIntroducedIn10_16() + // expected-error@-1{{'longFormIntroducedIn10_16()' is only available in macOS 11.0 or newer}} + // expected-note@-2{{add 'if #available' version check}} + + longFormIntroducedIn10_18() + // expected-error@-1{{'longFormIntroducedIn10_18()' is only available in macOS 10.18 or newer}} + // expected-note@-2{{add 'if #available' version check}} + + longFormIntroducedIn11_0() + // expected-error@-1{{'longFormIntroducedIn11_0()' is only available in macOS 11.0 or newer}} + // expected-note@-2{{add 'if #available' version check}} + + longFormIntroducedIn13_0() + // expected-error@-1{{'longFormIntroducedIn13_0()' is only available in macOS 13.0 or newer}} + // expected-note@-2{{add 'if #available' version check}} +} + +@available(OSX 10.16, *) +func shortFormIntroducedIn10_16() { } + +@available(OSX 10.18, *) +func shortFormIntroducedIn10_18() { } + +@available(OSX 11.0, *) +func shortFormIntroducedIn11_0() { } + +@available(OSX 13.0, *) +func shortFormIntroducedIn13_0() { } + +// expected-note@+1 *{{add @available attribute to enclosing global function}} +func useShortIntroduced() { + shortFormIntroducedIn10_16() + // expected-error@-1{{'shortFormIntroducedIn10_16()' is only available in macOS 11.0 or newer}} + // expected-note@-2{{add 'if #available' version check}} + shortFormIntroducedIn10_18() + // expected-error@-1{{'shortFormIntroducedIn10_18()' is only available in macOS 10.18 or newer}} + // expected-note@-2{{add 'if #available' version check}} + shortFormIntroducedIn11_0() + // expected-error@-1{{'shortFormIntroducedIn11_0()' is only available in macOS 11.0 or newer}} + // expected-note@-2{{add 'if #available' version check}} + + shortFormIntroducedIn13_0() + // expected-error@-1{{'shortFormIntroducedIn13_0()' is only available in macOS 13.0 or newer}} + // expected-note@-2{{add 'if #available' version check}} +} diff --git a/test/attr/attr_availability_canonical_macos_version_introduction_appext.swift b/test/attr/attr_availability_canonical_macos_version_introduction_appext.swift new file mode 100644 index 0000000000000..fa4ff5ad960f0 --- /dev/null +++ b/test/attr/attr_availability_canonical_macos_version_introduction_appext.swift @@ -0,0 +1,9 @@ +// RUN: %swift -typecheck -verify -parse-stdlib -module-name Swift -target x86_64-apple-macosx10.15 %s -application-extension + +@available(OSXApplicationExtension 11, *) +func introducedInAppExtension11_0() { } + +@available(OSXApplicationExtension 10.16, *) +func useAppExtension() { + introducedInAppExtension11_0() // no-warning +} diff --git a/test/decl/protocol/conforms/nscoding_availability_osx.swift b/test/decl/protocol/conforms/nscoding_availability_osx.swift index 90fced355f7cc..31fb24e90eb6c 100644 --- a/test/decl/protocol/conforms/nscoding_availability_osx.swift +++ b/test/decl/protocol/conforms/nscoding_availability_osx.swift @@ -1,6 +1,6 @@ -// RUN: %target-swift-frontend(mock-sdk: %clang-importer-sdk) -typecheck -parse-as-library -swift-version 4 %s -target x86_64-apple-macosx10.50 -verify +// RUN: %target-swift-frontend(mock-sdk: %clang-importer-sdk) -typecheck -parse-as-library -swift-version 4 %s -target %target-cpu-apple-macosx10.50 -verify -// RUN: %target-swift-frontend(mock-sdk: %clang-importer-sdk) -typecheck -parse-as-library -swift-version 4 %s -target x86_64-apple-macosx10.50 -dump-ast > %t.ast +// RUN: %target-swift-frontend(mock-sdk: %clang-importer-sdk) -typecheck -parse-as-library -swift-version 4 %s -target %target-cpu-apple-macosx10.50 -dump-ast > %t.ast // RUN: %FileCheck %s < %t.ast // REQUIRES: objc_interop diff --git a/test/lit.cfg b/test/lit.cfg index 9e0ece5f4fb31..c47b481dc3bf6 100644 --- a/test/lit.cfg +++ b/test/lit.cfg @@ -821,7 +821,7 @@ if run_vendor == 'apple': 'the swift_test_mode is "only_non_executable". Current ' 'swift_test_mode is {}.'.format(swift_test_mode)) - if 'arm' in run_cpu: + if 'arm' in run_cpu and not (run_os == 'macosx' or run_os == 'maccatalyst'): # iOS/tvOS/watchOS device if run_os == 'ios': lit_config.note('Testing iOS ' + config.variant_triple) @@ -953,7 +953,7 @@ if run_vendor == 'apple': sourcekitd_framework_dir)) config.target_run = "" - target_future_version = "10.99" + target_future_version = "99.99" if 'interpret' in lit_config.params: use_interpreter_for_simple_runs() diff --git a/test/stdlib/DispatchDeprecationMacOS.swift b/test/stdlib/DispatchDeprecationMacOS.swift index 04440f6f316d7..834a50f303ca3 100644 --- a/test/stdlib/DispatchDeprecationMacOS.swift +++ b/test/stdlib/DispatchDeprecationMacOS.swift @@ -1,4 +1,4 @@ -// RUN: %swift -typecheck -target x86_64-apple-macosx10.9 -verify -sdk %sdk %s +// RUN: %swift -typecheck -target %target-cpu-apple-macosx10.9 -verify -sdk %sdk %s // REQUIRES: OS=macosx // REQUIRES: libdispatch diff --git a/tools/swift-reflection-dump/swift-reflection-dump.cpp b/tools/swift-reflection-dump/swift-reflection-dump.cpp index 999f467b06da8..c06ec35de5f81 100644 --- a/tools/swift-reflection-dump/swift-reflection-dump.cpp +++ b/tools/swift-reflection-dump/swift-reflection-dump.cpp @@ -458,7 +458,7 @@ class ObjectMemoryReader : public MemoryReader { #else auto applePlatform = false; #endif -#if defined(__APPLE__) && __APPLE__ && ((defined(TARGET_OS_IOS) && TARGET_OS_IOS) || (defined(TARGET_OS_IOS) && TARGET_OS_WATCH) || (defined(TARGET_OS_TV) && TARGET_OS_TV)) +#if defined(__APPLE__) && __APPLE__ && ((defined(TARGET_OS_IOS) && TARGET_OS_IOS) || (defined(TARGET_OS_IOS) && TARGET_OS_WATCH) || (defined(TARGET_OS_TV) && TARGET_OS_TV) || defined(__arm64__)) auto iosDerivedPlatform = true; #else auto iosDerivedPlatform = false; diff --git a/tools/swift-reflection-fuzzer/swift-reflection-fuzzer.cpp b/tools/swift-reflection-fuzzer/swift-reflection-fuzzer.cpp index 80aaf7d4ca6fd..a47ac394e3561 100644 --- a/tools/swift-reflection-fuzzer/swift-reflection-fuzzer.cpp +++ b/tools/swift-reflection-fuzzer/swift-reflection-fuzzer.cpp @@ -61,7 +61,7 @@ class ObjectMemoryReader : public MemoryReader { #else auto applePlatform = false; #endif -#if defined(__APPLE__) && __APPLE__ && ((defined(TARGET_OS_IOS) && TARGET_OS_IOS) || (defined(TARGET_OS_IOS) && TARGET_OS_WATCH) || (defined(TARGET_OS_TV) && TARGET_OS_TV)) +#if defined(__APPLE__) && __APPLE__ && ((defined(TARGET_OS_IOS) && TARGET_OS_IOS) || (defined(TARGET_OS_IOS) && TARGET_OS_WATCH) || (defined(TARGET_OS_TV) && TARGET_OS_TV) || defined(__arm64__)) auto iosDerivedPlatform = true; #else auto iosDerivedPlatform = false; diff --git a/utils/build-script b/utils/build-script index bd2e4d6144594..86972ee9b1182 100755 --- a/utils/build-script +++ b/utils/build-script @@ -358,6 +358,18 @@ def apply_default_arguments(toolchain, args): target.arch in supported_archs) ] + # Filter out any macOS stdlib deployment targets that are not supported + # by the macOS SDK. + targets = StdlibDeploymentTarget.get_targets_by_name( + args.stdlib_deployment_targets) + args.stdlib_deployment_targets = [ + target.name + for target in targets + if (not target.platform.is_darwin or + target.platform.sdk_supports_architecture( + target.arch, args.darwin_xcrun_toolchain)) + ] + # Include the Darwin module-only architectures in the CMake options. if args.swift_darwin_module_archs: args.extra_cmake_options.append( diff --git a/utils/build-script-impl b/utils/build-script-impl index 921d5ad5ed6bc..998e623848e0c 100755 --- a/utils/build-script-impl +++ b/utils/build-script-impl @@ -423,15 +423,20 @@ function verify_host_is_supported() { | linux-powerpc64le \ | linux-s390x \ | macosx-x86_64 \ + | macosx-arm64 \ + | macosx-arm64e \ | iphonesimulator-i386 \ | iphonesimulator-x86_64 \ + | iphonesimulator-arm64 \ | iphoneos-armv7 \ | iphoneos-armv7s \ | iphoneos-arm64 \ | iphoneos-arm64e \ | appletvsimulator-x86_64 \ + | appletvsimulator-arm64 \ | appletvos-arm64 \ | watchsimulator-i386 \ + | watchsimulator-arm64 \ | watchos-armv7k \ | android-armv7 \ | android-aarch64 \ @@ -501,6 +506,24 @@ function set_build_options_for_host() { SWIFT_HOST_VARIANT_SDK="OSX" cmake_osx_deployment_target="${DARWIN_DEPLOYMENT_VERSION_OSX}" ;; + macosx-arm64) + xcrun_sdk_name="macosx" + llvm_target_arch="AArch64" + SWIFT_HOST_TRIPLE="arm64-apple-macosx${DARWIN_DEPLOYMENT_VERSION_OSX}" + SWIFT_HOST_VARIANT="macosx" + SWIFT_HOST_VARIANT_SDK="OSX" + SWIFT_HOST_VARIANT_ARCH="arm64" + cmake_osx_deployment_target="${DARWIN_DEPLOYMENT_VERSION_OSX}" + ;; + macosx-arm64e) + xcrun_sdk_name="macosx" + llvm_target_arch="AArch64" + SWIFT_HOST_TRIPLE="arm64e-apple-macosx${DARWIN_DEPLOYMENT_VERSION_OSX}" + SWIFT_HOST_VARIANT="macosx" + SWIFT_HOST_VARIANT_SDK="OSX" + SWIFT_HOST_VARIANT_ARCH="arm64e" + cmake_osx_deployment_target="${DARWIN_DEPLOYMENT_VERSION_OSX}" + ;; iphonesimulator-i386) SWIFT_HOST_TRIPLE="i386-apple-ios${DARWIN_DEPLOYMENT_VERSION_IOS}-simulator" llvm_target_arch="X86" @@ -515,6 +538,21 @@ function set_build_options_for_host() { SWIFT_HOST_VARIANT_SDK="IOS_SIMULATOR" cmake_osx_deployment_target="" ;; + iphonesimulator-arm64) + xcrun_sdk_name="iphonesimulator" + llvm_target_arch="AArch64" + SWIFT_HOST_TRIPLE="arm64-apple-ios${DARWIN_DEPLOYMENT_VERSION_IOS}-simulator" + SWIFT_HOST_VARIANT="iphonesimulator" + SWIFT_HOST_VARIANT_SDK="IOS_SIMULATOR" + SWIFT_HOST_VARIANT_ARCH="arm64" + + cmake_osx_deployment_target="" + cmark_cmake_options=( + -DCMAKE_C_FLAGS="$(cmark_c_flags ${host})" + -DCMAKE_CXX_FLAGS="$(cmark_c_flags ${host})" + -DCMAKE_OSX_SYSROOT:PATH="$(xcrun --sdk ${xcrun_sdk_name} --show-sdk-path)" + ) + ;; iphoneos-armv7) SWIFT_HOST_TRIPLE="armv7-apple-ios${DARWIN_DEPLOYMENT_VERSION_IOS}" llvm_target_arch="ARM" @@ -550,6 +588,21 @@ function set_build_options_for_host() { SWIFT_HOST_VARIANT_SDK="TVOS_SIMULATOR" cmake_osx_deployment_target="" ;; + appletvsimulator-arm64) + xcrun_sdk_name="appletvsimulator" + llvm_target_arch="AArch64" + SWIFT_HOST_TRIPLE="arm64-apple-tvos${DARWIN_DEPLOYMENT_VERSION_IOS}-simulator" + SWIFT_HOST_VARIANT="appletvsimulator" + SWIFT_HOST_VARIANT_SDK="TVOS_SIMULATOR" + SWIFT_HOST_VARIANT_ARCH="arm64" + + cmake_osx_deployment_target="" + cmark_cmake_options=( + -DCMAKE_C_FLAGS="$(cmark_c_flags ${host})" + -DCMAKE_CXX_FLAGS="$(cmark_c_flags ${host})" + -DCMAKE_OSX_SYSROOT:PATH="$(xcrun --sdk ${xcrun_sdk_name} --show-sdk-path)" + ) + ;; appletvos-arm64) SWIFT_HOST_TRIPLE="arm64-apple-tvos${DARWIN_DEPLOYMENT_VERSION_TVOS}" llvm_target_arch="AArch64" @@ -564,6 +617,21 @@ function set_build_options_for_host() { SWIFT_HOST_VARIANT_SDK="WATCHOS_SIMULATOR" cmake_osx_deployment_target="" ;; + watchsimulator-arm64) + xcrun_sdk_name="watchsimulator" + llvm_target_arch="AArch64" + SWIFT_HOST_TRIPLE="arm64-apple-watchos${DARWIN_DEPLOYMENT_VERSION_IOS}-simulator" + SWIFT_HOST_VARIANT="watchsimulator" + SWIFT_HOST_VARIANT_SDK="WATCHOS_SIMULATOR" + SWIFT_HOST_VARIANT_ARCH="arm64" + + cmake_osx_deployment_target="" + cmark_cmake_options=( + -DCMAKE_C_FLAGS="$(cmark_c_flags ${host})" + -DCMAKE_CXX_FLAGS="$(cmark_c_flags ${host})" + -DCMAKE_OSX_SYSROOT:PATH="$(xcrun --sdk ${xcrun_sdk_name} --show-sdk-path)" + ) + ;; watchos-armv7k) SWIFT_HOST_TRIPLE="armv7k-apple-watchos${DARWIN_DEPLOYMENT_VERSION_WATCHOS}" llvm_target_arch="ARM" @@ -648,10 +716,19 @@ function set_build_options_for_host() { esac - llvm_cmake_options+=( - -DLLVM_TOOL_COMPILER_RT_BUILD:BOOL="$(false_true ${SKIP_BUILD_COMPILER_RT})" - -DLLVM_BUILD_EXTERNAL_COMPILER_RT:BOOL="$(false_true ${SKIP_BUILD_COMPILER_RT})" - ) + # We don't currently support building compiler-rt for cross-compile targets. + # It's not clear that's useful anyway. + if [[ $(is_cross_tools_host "${host}") ]] ; then + llvm_cmake_options+=( + -DLLVM_TOOL_COMPILER_RT_BUILD:BOOL=FALSE + -DLLVM_BUILD_EXTERNAL_COMPILER_RT:BOOL=FALSE + ) + else + llvm_cmake_options+=( + -DLLVM_TOOL_COMPILER_RT_BUILD:BOOL="$(false_true ${SKIP_BUILD_COMPILER_RT})" + -DLLVM_BUILD_EXTERNAL_COMPILER_RT:BOOL="$(false_true ${SKIP_BUILD_COMPILER_RT})" + ) + fi # If we are asked to not generate test targets for LLVM and or Swift, # disable as many LLVM tools as we can. This improves compile time when @@ -860,11 +937,6 @@ if [[ "${CMAKE_GENERATOR}" == "Xcode" ]]; then SKIP_BUILD_COMPILER_RT=1 fi -# FIXME: We currently do not support cross-compiling swift with compiler-rt. -if [[ "${CROSS_COMPILE_HOSTS}" ]]; then - SKIP_BUILD_COMPILER_RT=1 -fi - if [[ "${SKIP_RECONFIGURE}" ]]; then RECONFIGURE="" fi @@ -939,7 +1011,7 @@ function false_true() { CROSS_COMPILE_HOSTS=($CROSS_COMPILE_HOSTS) for t in "${CROSS_COMPILE_HOSTS[@]}"; do case ${t} in - iphone* | appletv* | watch* | linux-armv6 | linux-armv7 | android-* ) + macosx-arm64* | iphone* | appletv* | watch* | linux-armv6 | linux-armv7 | android-* ) ;; *) echo "Unknown host to cross-compile for: ${t}" @@ -970,6 +1042,9 @@ function get_host_install_destdir() { if [[ $(should_include_host_in_lipo ${host}) ]]; then # If this is one of the hosts we should lipo, install in to a temporary subdirectory. local host_install_destdir="${BUILD_DIR}/intermediate-install/${host}" + elif [[ "${host}" == "merged-hosts" ]]; then + # This assumes that all hosts are merged to the lipo. + local host_install_destdir="${INSTALL_DESTDIR}" else local host_install_destdir="${INSTALL_DESTDIR}/${host}" fi @@ -1031,7 +1106,7 @@ function should_include_host_in_lipo() { local host="$1" if [[ $(has_cross_compile_hosts) ]] && [[ -z "${SKIP_MERGE_LIPO_CROSS_COMPILE_TOOLS}" ]]; then case ${host} in - iphone* | appletv* | watch* ) + macosx* | iphone* | appletv* | watch* ) echo 1 ;; esac @@ -1048,6 +1123,10 @@ function host_has_darwin_symbols() { } function get_stdlib_targets_for_host() { + # Don't build the stdlib in the Xcode train for host and cross-compilations host. + if [[ "${STDLIB_DEPLOYMENT_TARGETS[@]}" == "" ]]; then + return 0 + fi # FIXME: STDLIB_DEPLOYMENT_TARGETS argument assumed to apply when Host == Build # Cross-compile Hosts are only built with their native standard libraries. @@ -1206,6 +1285,9 @@ function common_cross_c_flags() { local arch=${host##*-} case $host in + macosx-*) + echo -n " -arch ${arch} " + ;; iphonesimulator-*) echo -n " -arch ${arch} -mios-simulator-version-min=${DARWIN_DEPLOYMENT_VERSION_IOS}" ;; @@ -2839,6 +2921,15 @@ for host in "${ALL_HOSTS[@]}"; do if [[ "${DARWIN_INSTALL_EXTRACT_SYMBOLS}" ]] && [[ $(host_has_darwin_symbols ${host}) ]]; then echo "--- Extracting symbols ---" + # The usage for this script says that lipo happens before + # dsym extraction but that's not really what happens. At this point, + # we're processing an individual host (eg macosx-x86_64) but targeting + # the (shared) SYMROOT which can cause mutliple hosts to stomp on each + # other. As a hack, I'm segregating the hosts in the symroot but it + # would probably be better to make the script behave as the usage + # descibes + host_symroot="${INSTALL_SYMROOT}/${host}" + # FIXME: Since it's hard to trace output pipe call, # For now, We don't support dry-run trace for this block # Instead, just echo we do "darwin_intall_extract_symbols". @@ -2853,7 +2944,7 @@ for host in "${ALL_HOSTS[@]}"; do # Copy executables and shared libraries from the `host_install_destdir` to # INSTALL_SYMROOT and run dsymutil on them. (cd "${CURRENT_INSTALL_DIR}" && - find ./"${CURRENT_PREFIX}" -perm -0111 -type f -print | cpio --insecure -pdm "${INSTALL_SYMROOT}") + find ./"${CURRENT_PREFIX}" -perm -0111 -type f -print | cpio --insecure -pdm "${host_symroot}") dsymutil_path= if [[ -n "${DARWIN_INSTALL_EXTRACT_SYMBOLS_USE_JUST_BUILT_DSYMUTIL}" ]]; then @@ -2866,7 +2957,7 @@ for host in "${ALL_HOSTS[@]}"; do # # Exclude shell scripts and static archives. # Exclude swift-api-digester dSYM to reduce debug toolchain size. - (cd "${INSTALL_SYMROOT}" && + (cd "${host_symroot}" && find ./"${CURRENT_PREFIX}" -perm -0111 -type f -print | \ grep -v '.py$' | \ grep -v '.a$' | \ @@ -3019,21 +3110,21 @@ done # Lipo those products which require it, optionally build and test an installable package. mergedHost="merged-hosts" -if [[ ${#LIPO_SRC_DIRS[@]} -gt 0 ]] && [[ $(should_execute_action "${mergedHost}-lipo") ]]; then +if [[ ${#LIPO_SRC_DIRS[@]} -gt 0 ]]; then # This is from multiple hosts; Which host should we say it is? # Let's call it 'merged-hosts' so that we can identify it. - echo "--- Merging and running lipo ---" + if [[ $(should_execute_action "${mergedHost}-lipo") ]]; then + # Allow passing lipo with --host-lipo + if [[ -z "${HOST_LIPO}" ]] ; then + LIPO_PATH=$(xcrun_find_tool lipo) + else + LIPO_PATH="${HOST_LIPO}" + fi + call "${SWIFT_SOURCE_DIR}"/utils/recursive-lipo --lipo=${LIPO_PATH} --copy-subdirs="$(get_host_install_prefix ${host})lib/swift $(get_host_install_prefix ${host})lib/swift_static" --destination="$(get_host_install_destdir ${mergedHost})" ${LIPO_SRC_DIRS[@]} - # Allow passing lipo with --host-lipo - if [[ -z "${HOST_LIPO}" ]] ; then - LIPO_PATH=$(xcrun_find_tool lipo) - else - LIPO_PATH="${HOST_LIPO}" + # Build and test the lipo-ed package. + build_and_test_installable_package ${mergedHost} fi - call "${SWIFT_SOURCE_DIR}"/utils/recursive-lipo --lipo=${LIPO_PATH} --copy-subdirs="$(get_host_install_prefix ${host})lib/swift $(get_host_install_prefix ${host})lib/swift_static" --destination="$(get_host_install_destdir ${mergedHost})" ${LIPO_SRC_DIRS[@]} - - # Build and test the lipo-ed package. - build_and_test_installable_package ${mergedHost} fi # END diff --git a/utils/incrparse/validate_parse.py b/utils/incrparse/validate_parse.py index 6d62d90fb5a18..8f69591fb8aaa 100755 --- a/utils/incrparse/validate_parse.py +++ b/utils/incrparse/validate_parse.py @@ -4,6 +4,7 @@ import argparse import difflib +import io import os import sys @@ -108,8 +109,10 @@ def main(): sys.exit(1) # Check if the two syntax trees are the same - lines = difflib.unified_diff(open(incremental_serialized_file).readlines(), - open(post_edit_serialized_file).readlines(), + lines = difflib.unified_diff(io.open(incremental_serialized_file, 'r', + encoding='utf-8', errors='ignore').readlines(), + io.open(post_edit_serialized_file, 'r', + encoding='utf-8', errors='ignore').readlines(), fromfile=incremental_serialized_file, tofile=post_edit_serialized_file) diff = '\n'.join(line for line in lines) diff --git a/utils/swift_build_support/swift_build_support/host_specific_configuration.py b/utils/swift_build_support/swift_build_support/host_specific_configuration.py index ae04998414b25..5bc89ef9cc09f 100644 --- a/utils/swift_build_support/swift_build_support/host_specific_configuration.py +++ b/utils/swift_build_support/swift_build_support/host_specific_configuration.py @@ -10,6 +10,7 @@ # # ---------------------------------------------------------------------------- +import re import sys from argparse import ArgumentError @@ -40,6 +41,11 @@ def __init__(self, host_target, args): stdlib_targets_to_configure = [host_target] stdlib_targets_to_build = set(stdlib_targets_to_configure) + if (hasattr(args, 'stdlib_deployment_targets') and + args.stdlib_deployment_targets == []): + stdlib_targets_to_configure = [] + stdlib_targets_to_build = [] + # Compute derived information from the arguments. # # FIXME: We should move the platform-derived arguments to be entirely @@ -155,11 +161,13 @@ def __init__(self, host_target, args): # Support for running the macCatalyst tests with # the iOS-like target triple. - if name == "macosx-x86_64" and args.maccatalyst \ + macosx_platform_match = re.search("macosx-(.*)", name) + if macosx_platform_match and args.maccatalyst \ and args.maccatalyst_ios_tests: (self.swift_test_run_targets - .append("check-swift{}{}-{}".format( - subset_suffix, suffix, "macosx-maccatalyst-x86_64"))) + .append("check-swift{}{}-{}-{}".format( + subset_suffix, suffix, "macosx-maccatalyst", + macosx_platform_match.group(1)))) else: (self.swift_test_run_targets .append("check-swift{}{}-{}".format( diff --git a/utils/swift_build_support/swift_build_support/targets.py b/utils/swift_build_support/swift_build_support/targets.py index fdac58137bb75..64ed0485edabb 100644 --- a/utils/swift_build_support/swift_build_support/targets.py +++ b/utils/swift_build_support/swift_build_support/targets.py @@ -11,6 +11,13 @@ import os import platform +from . import shell + +try: + from build_swift.build_swift.wrappers import xcrun +except ImportError: + from build_swift.wrappers import xcrun + class Platform(object): """ @@ -86,6 +93,39 @@ def uses_host_tests(self): """ return self.is_embedded and not self.is_simulator + def sdk_supports_architecture(self, arch, toolchain): + """ + Convenience function for checking whether the SDK supports the + target architecture. + """ + + # The names match up with the xcrun SDK names. + xcrun_sdk_name = self.name + + # 32-bit iOS and iOS simulator are supported, but are not covered + # by the SDK settings. Handle this special case here. + if (xcrun_sdk_name == 'iphoneos' and + (arch == 'armv7' or arch == 'armv7s')): + return True + + if (xcrun_sdk_name == 'iphonesimulator' and arch == 'i386'): + return True + + sdk_path = xcrun.sdk_path(sdk=xcrun_sdk_name, toolchain=toolchain) + if not sdk_path: + raise RuntimeError('Cannot find SDK path for %s' % xcrun_sdk_name) + + # Find the SDKSettings.plist for this sdK + plistCommand = [ + '/usr/libexec/PlistBuddy', + '-c', + 'Print :SupportedTargets:%s:Archs' % (self.name), + '%s/SDKSettings.plist' % (sdk_path) + ] + + sdk_archs = shell.capture(plistCommand, dry_run=False, echo=True) + return arch in sdk_archs + class AndroidPlatform(Platform): @property @@ -114,12 +154,12 @@ def name(self): class StdlibDeploymentTarget(object): - OSX = DarwinPlatform("macosx", archs=["x86_64"], + OSX = DarwinPlatform("macosx", archs=["x86_64", "arm64", "arm64e"], sdk_name="OSX") iOS = DarwinPlatform("iphoneos", archs=["armv7", "armv7s", "arm64", "arm64e"], sdk_name="IOS") - iOSSimulator = DarwinPlatform("iphonesimulator", archs=["i386", "x86_64"], + iOSSimulator = DarwinPlatform("iphonesimulator", archs=["i386", "x86_64", "arm64"], sdk_name="IOS_SIMULATOR", is_simulator=True) @@ -128,13 +168,14 @@ class StdlibDeploymentTarget(object): AppleTV = DarwinPlatform("appletvos", archs=["arm64"], sdk_name="TVOS") - AppleTVSimulator = DarwinPlatform("appletvsimulator", archs=["x86_64"], + AppleTVSimulator = DarwinPlatform("appletvsimulator", archs=["x86_64", "arm64"], sdk_name="TVOS_SIMULATOR", is_simulator=True) AppleWatch = DarwinPlatform("watchos", archs=["armv7k"], sdk_name="WATCHOS") - AppleWatchSimulator = DarwinPlatform("watchsimulator", archs=["i386"], + + AppleWatchSimulator = DarwinPlatform("watchsimulator", archs=["i386", "arm64"], sdk_name="WATCHOS_SIMULATOR", is_simulator=True) @@ -222,6 +263,10 @@ def host_target(): elif system == 'Darwin': if machine == 'x86_64': return StdlibDeploymentTarget.OSX.x86_64 + elif machine == 'arm64': + return StdlibDeploymentTarget.OSX.arm64 + elif machine == 'arm64e': + return StdlibDeploymentTarget.OSX.arm64e elif system == 'FreeBSD': if machine == 'amd64': diff --git a/validation-test/execution/interpret-with-dependencies.swift b/validation-test/execution/interpret-with-dependencies.swift index 6e2d022d91e0b..dbec4b8684274 100644 --- a/validation-test/execution/interpret-with-dependencies.swift +++ b/validation-test/execution/interpret-with-dependencies.swift @@ -1,5 +1,6 @@ // REQUIRES: OS=macosx // RUN: %empty-directory(%t) +// REQUIRES: swift_interpreter // RUN: echo 'int abc = 42;' | %clang -x c - -dynamiclib -Xlinker -install_name -Xlinker libabc.dylib -o %t/libabc.dylib -L %sdk/usr/lib // RUN: echo 'int test() { extern int abc; return abc; }' | %clang -x c - -L%t -dynamiclib -labc -o %t/libfoo.dylib -L %sdk/usr/lib