Description
Describe the bug
We found out that compiling our app with -O
and a specific linker arguments ordering breaks synthesized equatable if an xcframework dependency was compile with an older swift version (Xcode 13.4 in this case), on a case like:
// Main App
struct SomeStruct: Equatable {
let abc: Data
}
func doStuff() {
let requests: [SomeStruct] = [
SomeStruct(abc: "a".data(using: .ascii)!)
]
print("First", requests.firstIndex(of: requests[0]))
}
// BrokenLibrary.xcframework
import Foundation
@frozen
public enum ExampleEnum: Equatable {
case exampleCase(data: Data)
}
In this condition, if the .o files of the main module are passed at the end of the clang ...
linking call (as opposed to before the other xcframework arguments), the final linked binary points the data equality of both cases to the same routine
_$s10Foundation4DataV2eeoiySbAC_ACtFZTf4nnd_n [function signature specialization <Arg[2] = Dead> of static Foundation.Data.== infix(Foundation.Data, Foundation.Data) -> Swift.Bool]
Which ends up with the wrong equality result in runtime.
Steps To Reproduce
Steps to reproduce the behavior:
- Unzip ReproAppClean.zip
- Open Xcode 14.0, and run the app on an iOS device (arm64)
- Observe the console
...
Expected behavior
The console should print First Optional(0)
, it prints instead First nil
Environment (please fill out the following information)
- OS: macOS 12.6
- Xcode Version/Tag/Branch (Main App): Version 14.0 (14A309)
- Xcode Version/Tag/Branch (xcframework): Version 13.4 (13F17a)
Additional context
It's important to notice that the LD
environment variable is set on Xcode to an ld.py script that invokes clang but with the arguments ordering that breaks this case. It also needs -ObjC
(which is set already in the provided Xcode project).