[PATCH] D75574: RFC: Implement objc_direct_protocol attribute to remove protocol metadata

John McCall via Phabricator via cfe-commits cfe-commits at lists.llvm.org
Thu Sep 10 22:07:18 PDT 2020


rjmccall added a comment.

In D75574#2262622 <https://reviews.llvm.org/D75574#2262622>, @lanza wrote:

>> I don't think it'll actually error out at link time: protocol objects get emitted eagerly on use, cross-module linking is just a code-size optimization. This actually has caused longstanding problems.
>
> But if it's just a forward declaration there's nothing to emit. The above code compiles just fine as is with just a warning. Here's the result of `clang protocol.m -lobjc`
>
>   proto.m:10:31: warning: cannot find protocol definition for 'NonRuntimeProto'
>   @interface Implementer : Root<NonRuntimeProto>
>                                 ^
>   proto.m:8:11: note: protocol 'NonRuntimeProto' has no definition
>   @protocol NonRuntimeProto;
>             ^
>   1 warning generated.
>   Undefined symbols for architecture x86_64:
>     "__OBJC_PROTOCOL_$_NonRuntimeProto", referenced from:
>         __OBJC_CLASS_PROTOCOLS_$_Implementer in proto-bd4a43.o
>   ld: symbol(s) not found for architecture x86_64
>   clang-12: error: linker command failed with exit code 1 (use -v to see invocation)
>
> The protocol definition isn't actually required to compile an implementation. And if that protocol is declared as `objc_non_runtime_protocol` it won't ever see one.
>
> Simply requiring that it is annotated accordingly also isn't satisfactory for the same inheritance problem you mentioned above. Annotating a forward decl can tell clang not to emit it but won't let clang know if there's a base protocol that still needs to be emitted. e.g. if we have
>
>   // SomeHeader.h
>   @protocol Base
>   @end
>   __attribute__((objc_non_runtime_protocol))
>   @protocol NonRuntime <Base>
>   @end
>   
>   
>   // and in main.m
>   __attribute__((objc_non_runtime_protocol))
>   @protocol NonRuntime
>   @interface AClass : Root<NonRunime>
>   @end
>   @implementation AClass
>   @end
>
> we'll get a compile warning but no link error. But it will be wrong as the protocol `Base` should still be in the protocollist for `AClass`.
>
> I'm not sure how big of an issue it would be introducing a new error here for code that used to compile, but that's really the only way I see this working.

Hmm, I thought we actually just generated a bogus definition for the protocol when it was forward-declared; really, this is better behavior that I expected.  Regardless, I don't think it's worthwhile to diagnose this more strongly than a warning because of the history of not doing so.

Not really important for this PR anyway.  Was your question answered well enough to move forward?


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D75574/new/

https://reviews.llvm.org/D75574



More information about the cfe-commits mailing list