Skip to content

Commit 294913e

Browse files
committed
Fix _stdlib_getErrorDefaultUserInfo to have the signature the runtime expects.
The ABI mismatch here would cause a crash in cases when the Foundation overlay wasn't available, or its implementation of swift_Foundation_getErrorDefaultUserInfo wasn't dynamically resolvable, such as in a stripped statically linked binary. Fixes rdar://problem/29173132.
1 parent 0ec27bd commit 294913e

File tree

6 files changed

+49
-4
lines changed

6 files changed

+49
-4
lines changed

stdlib/public/SDK/Foundation/NSError.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -202,7 +202,7 @@ internal let _errorDomainUserInfoProviderQueue = DispatchQueue(
202202

203203
/// Retrieve the default userInfo dictionary for a given error.
204204
@_silgen_name("swift_Foundation_getErrorDefaultUserInfo")
205-
public func _swift_Foundation_getErrorDefaultUserInfo(_ error: Error)
205+
public func _swift_Foundation_getErrorDefaultUserInfo<T: Error>(_ error: T)
206206
-> AnyObject? {
207207
let hasUserInfoValueProvider: Bool
208208

stdlib/public/core/ErrorType.swift

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,6 @@
1111
//===----------------------------------------------------------------------===//
1212
import SwiftShims
1313

14-
// TODO: API review
1514
/// A type representing an error value that can be thrown.
1615
///
1716
/// Any type that declares conformance to the `Error` protocol can be used to
@@ -167,7 +166,7 @@ public func _stdlib_getErrorEmbeddedNSError<T : Error>(_ x: T)
167166
}
168167

169168
@_silgen_name("swift_stdlib_getErrorDefaultUserInfo")
170-
public func _stdlib_getErrorDefaultUserInfo(_ error: Error) -> AnyObject?
169+
public func _stdlib_getErrorDefaultUserInfo<T: Error>(_ error: T) -> AnyObject?
171170

172171
// Known function for the compiler to use to coerce `Error` instances
173172
// to `NSError`.

stdlib/public/runtime/ErrorObject.mm

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -397,7 +397,7 @@ static Class getSwiftNativeNSErrorClass() {
397397
const WitnessTable *Error);
398398

399399
//@_silgen_name("swift_stdlib_getErrorDefaultUserInfo")
400-
//public func _stdlib_getErrorDefaultUserInfo<T : Error>(_ x: UnsafePointer<T>) -> AnyObject
400+
//public func _stdlib_getErrorDefaultUserInfo<T : Error>(_ x: T) -> AnyObject
401401
SWIFT_CC(swift) SWIFT_RT_ENTRY_VISIBILITY
402402
NSDictionary *swift_stdlib_getErrorDefaultUserInfo(
403403
OpaqueValue *error,

test/stdlib/ErrorBridgedStatic.swift

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
// RUN: rm -rf %t
2+
// RUN: mkdir -p %t
3+
// RUN: %target-clang -fmodules -c -o %t/ErrorBridgedStaticImpl.o %S/Inputs/ErrorBridgedStaticImpl.m
4+
// RUN: %target-build-swift -static-stdlib -o %t/ErrorBridgedStatic %t/ErrorBridgedStaticImpl.o %s -import-objc-header %S/Inputs/ErrorBridgedStaticImpl.h
5+
// RUN: strip %t/ErrorBridgedStatic
6+
// RUN: %t/ErrorBridgedStatic
7+
8+
// REQUIRES: executable_test
9+
// REQUIRES: objc_interop
10+
// REQUIRES: static_stdlib
11+
12+
import StdlibUnittest
13+
14+
class Bar: Foo {
15+
override func foo(_ x: Int32) throws {
16+
try super.foo(5)
17+
}
18+
}
19+
20+
var ErrorBridgingStaticTests = TestSuite("ErrorBridging with static libs")
21+
22+
ErrorBridgingStaticTests.test("round-trip Swift override of ObjC method") {
23+
do {
24+
try (Bar() as Foo).foo(5)
25+
} catch { }
26+
}
27+
28+
runAllTests()
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
@import Foundation;
2+
3+
@interface Foo: NSObject
4+
5+
- (BOOL)foo:(int)x error:(NSError**)error;
6+
7+
@end
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
#include "ErrorBridgedStaticImpl.h"
2+
3+
@implementation Foo
4+
5+
- (BOOL)foo:(int)x error:(NSError**)error {
6+
*error = nil;
7+
return NO;
8+
}
9+
10+
@end
11+

0 commit comments

Comments
 (0)