mirror of
https://github.com/apple/swift.git
synced 2025-12-14 20:36:38 +01:00
Update the branch to build with Xcode 12.5 (#37046)
This commit is contained in:
@@ -22,8 +22,18 @@ namespace bincompat {
|
||||
|
||||
/// Whether protocol conformance iteration should be reversed, to prefer
|
||||
/// conformances from images that are later in the list over earlier ones.
|
||||
/// Default is false starting with Swift 5.4.
|
||||
bool workaroundProtocolConformanceReverseIteration();
|
||||
|
||||
/// Whether we should crash when we encounter a non-nullable Obj-C
|
||||
/// reference with a null value as the source of a cast.
|
||||
/// Default is true starting with Swift 5.4.
|
||||
bool unexpectedObjCNullWhileCastingIsFatal();
|
||||
|
||||
/// Whether we should use the legacy semantics for casting nil optionals
|
||||
/// to nested optionals
|
||||
bool useLegacyOptionalNilInjection();
|
||||
|
||||
} // namespace bincompat
|
||||
|
||||
} // namespace runtime
|
||||
|
||||
@@ -15,6 +15,17 @@
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#include "swift/Runtime/Bincompat.h"
|
||||
#include <stdint.h>
|
||||
|
||||
// If this is an Apple OS, use the Apple binary compatibility rules
|
||||
#if __has_include(<mach-o/dyld_priv.h>)
|
||||
#include <mach-o/dyld_priv.h>
|
||||
#ifndef BINARY_COMPATIBILITY_APPLE
|
||||
#define BINARY_COMPATIBILITY_APPLE 1
|
||||
#endif
|
||||
#else
|
||||
#undef BINARY_COMPATIBILITY_APPLE
|
||||
#endif
|
||||
|
||||
namespace swift {
|
||||
|
||||
@@ -22,7 +33,74 @@ namespace runtime {
|
||||
|
||||
namespace bincompat {
|
||||
|
||||
bool workaroundProtocolConformanceReverseIteration() { return false; }
|
||||
// Should we mimic the old override behavior when scanning protocol conformance records?
|
||||
|
||||
// Old apps expect protocol conformances to override each other in a particular
|
||||
// order. Starting with Swift 5.4, that order has changed as a result of
|
||||
// significant performance improvements to protocol conformance scanning. If
|
||||
// this returns `true`, the protocol conformance scan will do extra work to
|
||||
// mimic the old override behavior.
|
||||
bool workaroundProtocolConformanceReverseIteration() {
|
||||
#if BINARY_COMPATIBILITY_APPLE
|
||||
// If this is a newer Apple OS ...
|
||||
if (__builtin_available(macOS 11.3, iOS 14.5, tvOS 14.5, watchOS 7.4, *)) {
|
||||
const dyld_build_version_t spring_2021_os_versions = {0xffffffff, 0x007e50301};
|
||||
// ... but the app was compiled before Spring 2021, use the legacy behavior.
|
||||
return !dyld_program_sdk_at_least(spring_2021_os_versions);
|
||||
} else {
|
||||
return false; // Use new (non-legacy) behavior on old Apple OSes
|
||||
}
|
||||
#else
|
||||
return false; // Never use the legacy behavior on non-Apple OSes
|
||||
#endif
|
||||
}
|
||||
|
||||
// Should the dynamic cast operation crash when it sees
|
||||
// a non-nullable Obj-C pointer with a null value?
|
||||
|
||||
// Obj-C does not strictly enforce non-nullability in all cases, so it is
|
||||
// possible for Obj-C code to pass null pointers into Swift code even when
|
||||
// declared non-nullable. Such null pointers can lead to undefined behavior
|
||||
// later on. Starting in Swift 5.4, these unexpected null pointers are fatal
|
||||
// runtime errors, but this is selectively disabled for old apps.
|
||||
bool unexpectedObjCNullWhileCastingIsFatal() {
|
||||
#if BINARY_COMPATIBILITY_APPLE
|
||||
// If this is a new enough Apple OS ...
|
||||
if (__builtin_available(macOS 11.3, iOS 14.5, tvOS 14.5, watchOS 7.4, *)) {
|
||||
const dyld_build_version_t spring_2021_os_versions = {0xffffffff, 0x007e50301};
|
||||
// ... use strict behavior for apps compiled on or after Spring 2021.
|
||||
return dyld_program_sdk_at_least(spring_2021_os_versions);
|
||||
} else {
|
||||
return false; // Use permissive behavior on old Apple OS
|
||||
}
|
||||
#else
|
||||
return true; // Always use the strict behavior on non-Apple OSes
|
||||
#endif
|
||||
}
|
||||
|
||||
// Should casting a nil optional to another optional
|
||||
// use the legacy semantics?
|
||||
|
||||
// For consistency, starting with Swift 5.4, casting Optional<Int> to
|
||||
// Optional<Optional<Int>> always wraps the source in another layer
|
||||
// of Optional.
|
||||
// Earlier versions of the Swift runtime did not do this if the source
|
||||
// optional was nil. In that case, the outer target optional would be
|
||||
// set to nil.
|
||||
bool useLegacyOptionalNilInjection() {
|
||||
#if BINARY_COMPATIBILITY_APPLE
|
||||
// If this is a new enough Apple OS ...
|
||||
if (__builtin_available(macOS 11.3, iOS 14.5, tvOS 14.5, watchOS 7.4, *)) {
|
||||
const dyld_build_version_t spring_2021_os_versions = {0xffffffff, 0x007e50301};
|
||||
// It's using Spring 2021 or later SDK, so don't use the legacy behavior.
|
||||
return !dyld_program_sdk_at_least(spring_2021_os_versions);
|
||||
} else {
|
||||
return true; // Use the legacy behavior on old Apple OS
|
||||
}
|
||||
#else
|
||||
return false; // Always use the 5.4 behavior on non-Apple OSes
|
||||
#endif
|
||||
}
|
||||
|
||||
} // namespace bincompat
|
||||
|
||||
|
||||
@@ -20,6 +20,7 @@
|
||||
#include "SwiftHashableSupport.h"
|
||||
#include "swift/ABI/MetadataValues.h"
|
||||
#include "swift/Basic/Lazy.h"
|
||||
#include "swift/Runtime/Bincompat.h"
|
||||
#include "swift/Runtime/Casting.h"
|
||||
#include "swift/Runtime/Config.h"
|
||||
#include "swift/Runtime/ExistentialContainer.h"
|
||||
@@ -110,12 +111,6 @@ extern "C" const StructDescriptor NOMINAL_TYPE_DESCR_SYM(Sh);
|
||||
/// Nominal type descriptor for Swift.String.
|
||||
extern "C" const StructDescriptor NOMINAL_TYPE_DESCR_SYM(SS);
|
||||
|
||||
// If this returns `true`, then we will call `fatalError` when we encounter a
|
||||
// null reference in a storage locaation whose type does not allow null.
|
||||
static bool unexpectedNullIsFatal() {
|
||||
return true; // Placeholder for an upcoming check.
|
||||
}
|
||||
|
||||
/// This issues a fatal error or warning if the srcValue contains a null object
|
||||
/// reference. It is used when the srcType is a non-nullable reference type, in
|
||||
/// which case it is dangerous to continue with a null reference. The null
|
||||
@@ -134,7 +129,7 @@ static HeapObject * getNonNullSrcObject(OpaqueValue *srcValue,
|
||||
const char *msg = "Found unexpected null pointer value"
|
||||
" while trying to cast value of type '%s' (%p)"
|
||||
" to '%s' (%p)%s\n";
|
||||
if (unexpectedNullIsFatal()) {
|
||||
if (runtime::bincompat::unexpectedObjCNullWhileCastingIsFatal()) {
|
||||
// By default, Swift 5.4 and later issue a fatal error.
|
||||
swift::fatalError(/* flags = */ 0, msg,
|
||||
srcTypeName.c_str(), srcType,
|
||||
@@ -1044,7 +1039,7 @@ initializeToNilAtDepth(OpaqueValue *destLocation, const Metadata *destType, int
|
||||
}
|
||||
|
||||
static void
|
||||
copyNil(OpaqueValue *destLocation, const Metadata *destType, const Metadata *srcType)
|
||||
copyNilPreservingDepth(OpaqueValue *destLocation, const Metadata *destType, const Metadata *srcType)
|
||||
{
|
||||
assert(srcType->getKind() == MetadataKind::Optional);
|
||||
assert(destType->getKind() == MetadataKind::Optional);
|
||||
@@ -1087,7 +1082,13 @@ tryCastUnwrappingOptionalBoth(
|
||||
srcValue, /*emptyCases=*/1);
|
||||
auto sourceIsNil = (sourceEnumCase != 0);
|
||||
if (sourceIsNil) {
|
||||
copyNil(destLocation, destType, srcType);
|
||||
if (runtime::bincompat::useLegacyOptionalNilInjection()) {
|
||||
auto destInnerType = cast<EnumMetadata>(destType)->getGenericArgs()[0];
|
||||
// Set .none at the outer level
|
||||
destInnerType->vw_storeEnumTagSinglePayload(destLocation, 1, 1);
|
||||
} else {
|
||||
copyNilPreservingDepth(destLocation, destType, srcType);
|
||||
}
|
||||
return DynamicCastResult::SuccessViaCopy; // nil was essentially copied to dest
|
||||
} else {
|
||||
auto destEnumType = cast<EnumMetadata>(destType);
|
||||
|
||||
@@ -343,7 +343,7 @@ CastsTests.test("Dynamic cast to ObjC protocol") {
|
||||
#endif
|
||||
|
||||
// SR-6126
|
||||
if #available(macOS 9999, iOS 9999, watchOS 9999, tvOS 9999, *) {
|
||||
if #available(macOS 11.3, iOS 14.5, tvOS 14.5, watchOS 7.4, *) {
|
||||
CastsTests.test("Nil handling for Optionals and Arrays (SR-6126)") {
|
||||
func check(_ arg: Int??) -> String {
|
||||
switch arg {
|
||||
@@ -622,6 +622,7 @@ CastsTests.test("NSNull?.none -> Any? should set outer nil") {
|
||||
}
|
||||
#endif
|
||||
|
||||
if #available(macOS 11.3, iOS 14.5, tvOS 14.5, watchOS 7.4, *) {
|
||||
CastsTests.test("Int??.some(nil) => Int??? should inject naturally") {
|
||||
let a: Int?? = .some(nil)
|
||||
let b = a as? Int???
|
||||
@@ -630,7 +631,9 @@ CastsTests.test("Int??.some(nil) => Int??? should inject naturally") {
|
||||
let e = d!
|
||||
expectNil(e)
|
||||
}
|
||||
}
|
||||
|
||||
if #available(macOS 11.3, iOS 14.5, tvOS 14.5, watchOS 7.4, *) {
|
||||
CastsTests.test("Int??.some(nil) => String??? should inject naturally") {
|
||||
let a: Int?? = .some(nil)
|
||||
let b = runtimeCast(a, to: String???.self)
|
||||
@@ -639,7 +642,9 @@ CastsTests.test("Int??.some(nil) => String??? should inject naturally") {
|
||||
let e = d!
|
||||
expectNil(e)
|
||||
}
|
||||
}
|
||||
|
||||
if #available(macOS 11.3, iOS 14.5, tvOS 14.5, watchOS 7.4, *) {
|
||||
CastsTests.test("Int??.some(nil) => Any??? should inject naturally") {
|
||||
let a: Int?? = .some(nil)
|
||||
let b = a as? Any???
|
||||
@@ -648,6 +653,7 @@ CastsTests.test("Int??.some(nil) => Any??? should inject naturally") {
|
||||
let e = d!
|
||||
expectNil(e)
|
||||
}
|
||||
}
|
||||
|
||||
#if _runtime(_ObjC)
|
||||
CastsTests.test("NSString -> String fast path") {
|
||||
|
||||
@@ -47,10 +47,7 @@ func firstHashValue(_ x: P) -> Int {
|
||||
}
|
||||
|
||||
let osHasWorkaround: Bool
|
||||
// These are deliberately NOT version 9999, as we don't want to hit the special
|
||||
// case where development runtimes always return true for 9999. This check needs
|
||||
// to be false until real version numbers are put in.
|
||||
if #available(macOS 99990, iOS 99990, tvOS 99990, watchOS 99990, *) {
|
||||
if #available(macOS 11.3, iOS 14.5, tvOS 14.5, watchOS 7.4, *) {
|
||||
osHasWorkaround = true
|
||||
} else {
|
||||
osHasWorkaround = false
|
||||
|
||||
@@ -15,7 +15,7 @@
|
||||
set -o pipefail
|
||||
set -e
|
||||
|
||||
OVERLAY_NAME_ALTERNATION="AppKit|AssetsLibrary|AVFoundation|CallKit|CloudKit|Compression|Contacts|CoreAudio|CoreData|CoreGraphics|CoreImage|CoreLocation|CoreMedia|CryptoTokenKit|dispatch|Foundation|GameplayKit|GLKit|HomeKit|IOKit|Intents|MapKit|objc|OpenCL|os|Photos|QuartzCore|SafariServices|SceneKit|simd|SpriteKit|UIKit|WatchKit|XCTest|xpc"
|
||||
OVERLAY_NAME_ALTERNATION="AppKit|AssetsLibrary|AVFoundation|CallKit|CloudKit|Compression|Contacts|CoreAudio|CoreData|CoreGraphics|CoreImage|CoreLocation|CoreMedia|CoreML|CryptoTokenKit|dispatch|Foundation|GameplayKit|GLKit|HomeKit|IOKit|Intents|MapKit|objc|OpenCL|os|Photos|QuartzCore|SafariServices|SceneKit|simd|SpriteKit|UIKit|WatchKit|XCTest|xpc"
|
||||
|
||||
function find_deps() {
|
||||
local OVERLAY_ARG=$1
|
||||
|
||||
Reference in New Issue
Block a user