Hi,
I am fighting a strange issue in unit tests of my iOS application. I use Apple Swift version 5.3.2 (swiftlang-1200.0.45 clang-1200.0.32.28) and unfortunately I am unable to quickly verify the issue against latest Swift compiler. Sorry, I will try to verify the issue on the latest Swift version and I will try to pinpoint the minimal scenario to reproduce it, but before that I have a question regarding Swift ABI – just to make sure I took the right direction. Can anyone verify the technical details I shared right below?
My unit tests crash when I pass an Equatable enum into XCTAssertEqual. XCTAssertEqual tries to read an argument metadata, but this causes the stack pointer to be broken, which in turn causes EXC_BAD_INSTRUCTION on the nearest callq instruction.
I see an anomaly in the enum metadata:
- a value witness table pointer comes first,
- then some unexpected pointer,
- then a
kind,
- finally a nominal type descriptor.
I am not sure if I haven't missed anything reading ABI docs, but this unexpected pointer seems unusual. As far as I know kind value should appear immediately after the value witness table pointer. XCTAssertEqual tries to get a value witness table at offset -0x8 from the type metadata, but instead of value witness table – it gets a pointer to something different.

My question is: is it correct for a full type metadata to have value witness table separated from kind value by any additional data? Please help 
Looking at the runtime code (see TargetEnumMetadata and super classes) and IR generated for a toy example, that seems like a codegen bug.
1 Like
Thank you for your assistance! I managed to reproduce the issue in a sample project. I pushed it to github repo. Broken metadata is clearly visible in compiled main executable.
$ nm -n LinkingDemo | grep OMf -A 1
000000010000c0d8 s _$s6LibAAA8EnumAAA0OMf
000000010000c0e0 S _$s6LibAAA8EnumAAA0ON
--
000000010000c160 s _$s6LibAAA8EnumAAA1OMf
000000010000c168 S _$s6LibAAA8EnumAAA1ON
--
000000010000c1e8 s _$s6LibAAA8EnumAAA2OMf
000000010000c1f0 s _$s6LibBBB8EnumBBB0OWV 👈 HERE
--
000000010000c2e0 s _$s6LibBBB8EnumBBB0OMf
000000010000c2e8 S _$s6LibBBB8EnumBBB0ON
--
000000010000c2f8 s _$s6LibAAA8EnumAAA3OMf
000000010000c300 s _$s6LibBBB8EnumBBB1OWV 👈 HERE
--
000000010000c3f0 s _$s6LibBBB8EnumBBB1OMf
000000010000c3f8 S _$s6LibBBB8EnumBBB1ON
--
000000010000c408 s _$s6LibAAA8EnumAAA4OMf
000000010000c410 s _$s6LibBBB8EnumBBB2OWV 👈 HERE
--
000000010000c500 s _$s6LibBBB8EnumBBB2OMf
000000010000c508 S _$s6LibBBB8EnumBBB2ON
--
I was not able to reproduce the issue with SPM project setup. The issue disappears after linking all the libraries explicitly in the executable target settings. I am not sure if this is a linker bug or just undefined behavior. 