Skip to content

ClangImporter can cause Swift to abridge Objective-C Protocol definitions depending on link order #64158

@dmaclach

Description

@dmaclach

Description
Objective-C protocols are defined in every Objective-C object file that references them.

For Swift, ClangImporter elides any methods from the protocol that use forward declared types (classes, protocols, enums) and embeds that elided protocol definition into the Swift object files as needed.

If the linker(ld64) finds an abridged "Swift" protocol definition first in the linkage it will use that as the final protocol definition for the final link.

Any code that examines the protocol at runtime using functions like protocol_copyMethodDescriptionList will end up examining the abridged protocol and will be missing methods.

A classic example of this is in OCMock (https://github.com/erikdoe/ocmock/blob/master/Source/OCMock/OCProtocolMockObject.m) that needs a full protocol definition to mock protocols correctly.

Steps to reproduce
Build and run attached project

Expected behavior
Expected:

2023-03-06 15:43:41.632110-0800 ProtocolTest[84362:21617038] Protocol: ObjCFileProtocol
2023-03-06 15:43:41.632664-0800 ProtocolTest[84362:21617038] 	aClass : @16@0:8
2023-03-06 15:43:41.632722-0800 ProtocolTest[84362:21617038] 	anEnum : i16@0:8
2023-03-06 15:43:41.632748-0800 ProtocolTest[84362:21617038] 	aProtocol : @16@0:8
2023-03-06 15:43:41.632769-0800 ProtocolTest[84362:21617038] 	getInt : i16@0:8
Program ended with exit code: 0

Actual:

2023-03-06 15:44:11.235527-0800 ProtocolTest[84446:21619329] Protocol: ObjCFileProtocol
2023-03-06 15:44:11.235958-0800 ProtocolTest[84446:21619329] 	getInt : i16@0:8
Program ended with exit code: 0

Environment
Xcode 14.2
Build version 14C18

ProtocolTest.zip

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugA deviation from expected or documented behavior. Also: expected but undesirable behavior.triage neededThis issue needs more specific labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions