You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
SR-7300 nil converted to NSNull when returned from a nonnull Objective-C method
Issue Description:
This looks like it might be related to SR-7300, but I don't see any explicit NSNull-related behavior so it could be different.
If an Objective-C API that's declared nonnull does in fact return nil, then the behavior when called from Swift is inconsistent:
Assigning such a value to a variable produces a non-optional value of that type whose underlying pointer value is 0x0 (when viewed in the debugger)
Calling a method or getting/setting a property with that variable as the receiver does not trap, but instead exhibits Objective-C-like functionality (silently succeeding, returning bit pattern 0 in non-void cases)
Trying to print the value itself, however, crashes the program/interpreter
This is of course a case where the API implementation is violating its own contract, but I would expect the first assignment above to be where Swift would trap, since there's no obvious way to guard against the unexpected nil result.
Repro case:
import Foundation
// Despite its contract, this returns nil if there is no bundle ID
// (e.g., in a command line app without an embedded Info.plist)
let center = NSUserNotificationCenter.default
print("got something for center")
let delegate = center.delegate
print("was able to call a getter, its value was (delegate)")
center.delegate = nil
print("was able to call a setter")
print("now we'll try to print the value itself")
print(center)
print("this won't print because it crashed")
When compiled and executed, the following output is produced:
got something for center
was able to call a getter, its value was nil
was able to call a setter
now we'll try to print the value itself
[1] 58342 segmentation fault ./trap
When executed under the interpreter, the backtrace gives a little more insight:
A radar has been filed separately for the NSUserNotificationCenter API's incorrect contract, although since it's deprecated it may not be a high priority fix: https://openradar.appspot.com/43645642
The text was updated successfully, but these errors were encountered:
I think for a lot of UI applications it might be worthwhile to check, esp. those with large codebases full of Obj-C/Swift interface (i.e. high probability of accidental contract violation).
Environment
Swift 4.2, Xcode 10 beta 4, macOS 10.13.16. May be present in other versions.
Additional Detail from JIRA
md5: 1fd0b53e09d10b8697bba1cbc378a479
is duplicated by:
relates to:
Issue Description:
This looks like it might be related to SR-7300, but I don't see any explicit NSNull-related behavior so it could be different.
If an Objective-C API that's declared
nonnull
does in fact return nil, then the behavior when called from Swift is inconsistent:Assigning such a value to a variable produces a non-optional value of that type whose underlying pointer value is 0x0 (when viewed in the debugger)
Calling a method or getting/setting a property with that variable as the receiver does not trap, but instead exhibits Objective-C-like functionality (silently succeeding, returning bit pattern 0 in non-void cases)
Trying to print the value itself, however, crashes the program/interpreter
This is of course a case where the API implementation is violating its own contract, but I would expect the first assignment above to be where Swift would trap, since there's no obvious way to guard against the unexpected nil result.
Repro case:
import Foundation
// Despite its contract, this returns nil if there is no bundle ID
// (e.g., in a command line app without an embedded Info.plist)
let center = NSUserNotificationCenter.default
print("got something for center")
let delegate = center.delegate
print("was able to call a getter, its value was (delegate)")
center.delegate = nil
print("was able to call a setter")
print("now we'll try to print the value itself")
print(center)
print("this won't print because it crashed")
When compiled and executed, the following output is produced:
got something for center
was able to call a getter, its value was nil
was able to call a setter
now we'll try to print the value itself
[1] 58342 segmentation fault ./trap
When executed under the interpreter, the backtrace gives a little more insight:
0 swift 0x0000000104ebbb8a PrintStackTraceSignalHandler(void*) + 42
1 swift 0x0000000104ebb32e SignalHandler(int) + 302
2 libsystem_platform.dylib 0x00007fff576fbf5a _sigtramp + 26
3 libsystem_platform.dylib 0x00007fe9b17a9238 _sigtramp + 1510658808
4 libswiftCore.dylib 0x000000010ae71f25 findDynamicValueAndType(swift::OpaqueValue*, swift::TargetMetadata<swift::InProcess> const*, swift::OpaqueValue*&, swift::TargetMetadata<swift::InProcess> const*&, bool&, bool, bool) + 245
5 libswiftCore.dylib 0x000000010ae76687 _dynamicCastToExistential(swift::OpaqueValue*, swift::OpaqueValue*, swift::TargetMetadata<swift::InProcess> const*, swift::TargetExistentialTypeMetadata<swift::InProcess> const*, swift::DynamicCastFlags) + 135
6 libswiftCore.dylib 0x000000010ac41c4a $Ss15_print_unlockedyyx_q_zts16TextOutputStreamR_r0_lF + 394
7 libswiftCore.dylib 0x000000010ae1931a $Ss6_print_9separator10terminator2toySayypG_S2Sxzts16TextOutputStreamRzlFs7_StdoutV_Tg5Tf4nxxn_nTm + 250
8 libswiftCore.dylib 0x000000010ae19c1f $Ss5print_9separator10terminatoryypd_S2StFTf4nxx_nTm + 271
9 libswiftCore.dylib 0x000000010acedba0 $Ss5print_9separator10terminatoryypd_S2StF + 16
10 libswiftCore.dylib 0x000000010882856d $Ss5print_9separator10terminatoryypd_S2StF + 4256410077
11 swift 0x0000000101efa03d llvm::MCJIT::runFunction(llvm::Function*, llvm::ArrayRef<llvm::GenericValue>) + 365
12 swift 0x0000000101f00a3c llvm::ExecutionEngine::runFunctionAsMain(llvm::Function*, std::_1::vector<std::1::basic_string<char, std::1::char_traits<char>, std::1::allocator<char> >, std::1::allocator<std::1::basic_string<char, std::1::char_traits<char>, std::_1::allocator<char> > > > const&, char const* const*) + 1004
13 swift 0x000000010117c593 performCompile(swift::CompilerInstance&, swift::CompilerInvocation&, llvm::ArrayRef<char const*>, int&, swift::FrontendObserver*, swift::UnifiedStatsReporter*) + 52659
14 swift 0x000000010116c2e5 swift::performFrontend(llvm::ArrayRef<char const*>, char const*, void*, swift::FrontendObserver*) + 7733
15 swift 0x0000000101112155 main + 1349
16 libdyld.dylib 0x00007fff573ed015 start + 1
A radar has been filed separately for the NSUserNotificationCenter API's incorrect contract, although since it's deprecated it may not be a high priority fix: https://openradar.appspot.com/43645642
The text was updated successfully, but these errors were encountered: