[SR-15612] Initializing NSObject inheritant with default parameter values sometimes results in crash. #57908
Labels
bug
A deviation from expected or documented behavior. Also: expected but undesirable behavior.
compiler
The Swift compiler in itself
crash
Bug: A crash, i.e., an abnormal termination of software
run-time crash
Bug → crash: Swift code crashed during execution
Environment
Configuration 1 that generated dynamic init for PhoneNumberKit class in PhoneNumberKit:
MacBook Pro (Retina, 15-inch, Mid 2015)
macOS 12.1 (21C52)
Xcode 13.2 (13C90)
Apple Swift version 5.5.2 (swiftlang-1300.0.47.5 clang-1300.0.29.30)
Configuration 2 that generated dynamic init for SessionDelegate class in Alamofire:
MacBook Pro (16-inch, 2019)
macOS 11.4 (20F71)
Xcode 13.0 (13A233)
Apple Swift version 5.4 (swiftlang-1205.0.26.9 clang-1205.0.19.55)
Additional Detail from JIRA
md5: ab097cb122fe08360ca130db3553a09b
Issue Description:
If a class inheriting NSObject declares their own inits without overriding super's parameter-less init, and any one of these inits has default values for all parameters, calling the init with default parameter values may result in a runtime crash.
Basically, if I have:
Somewhere the app crashes at a call site SomeObject() with:
Many third-party libraries do this, for example:
Alamofire: SessionDelegate.swift @ Line 38
PhoneNumberKit: PhoneNumberKit.swift @ Line 24
I cannot reproduce this in a brand-new project, but at least two iOS apps I wrote had encountered this problem. The same project that is compiled several times on different machines may get different results. I think I've found some clues to why this is happening, and a way to reproduce it although not entirely straightforward.
When BUILD_LIBRARY_FOR_DISTRIBUTION is turned on for Alamofire, build that crashes has the following Swift Interface generated:
While the build that doesn't crash is missing the dynamic init in Swift Interface:
So to reproduce, download or write a framework that has a class with all-default-values init. Then archive and generate an XCFramework of it. For Alamofire 5.5.0 the command to create XCFramework from its source directory is:
(Note that you need to turn Build Library for Distribution ON and Skip Intall OFF first for the intended Alamofire target.)
Observe if any *.swiftinterface has
for SessionDelegate declaration. If it does, integrating this framework and call
somewhere in the app will crash at runtime.
If the generated framework doesn't have that line, try running the command again on another machine (or at some other time). I have not found exactly what is causing this and how to reproduce it consistently. But since the exactly same code generates different interfaces, I'm fairly certain this is compiler's wrong-doing.
The text was updated successfully, but these errors were encountered: