Clang warning: receiver A is a forward class and corresponding @interface may not exist [-Wreceiver-forward-class] (warn_receiver_forward_class)

From emmtrix Wiki
Jump to navigation Jump to search
Text error: receiver A is a forward class and corresponding @interface may not exist
Type Warning
Category Semantic Issue
Internal Id warn_receiver_forward_class
Active by Default Yes
Flags -Wno-receiver-forward-class (2 elements)
Internal Message receiver %0 is a forward class and corresponding @interface may not exist
Regular Expression (?:warning|error|fatal error)\: receiver (.*?) is a forward class and corresponding @interface may not exist \[(?:\-Werror,)?\-Wreceiver\-forward\-class[^\]]*\]
First Commit 2009-05-09 1bd844da8057 Warn if forward class is used as a receiver.

Description

The warning is issued by the Clang compiler when an object of a forward-declared class is used as a receiver in a message-send expression, and the compiler cannot guarantee that the corresponding @interface for the class exists. This situation can lead to undefined behavior if the @interface is not found during compilation. The warning aims to alert the developer to the potential issue that the compiler cannot verify the existence of the class's interface, which is necessary for the message-send operation to be successfully compiled and linked. The compiler checks for the complete definition of the class based on its forward declaration and raises this warning if it is not found within the scope of the message-send expression.

To resolve this warning, ensure that the class is fully defined before it is used as a receiver in a message-send expression. This typically involves including the header file where the class's @interface is declared. Alternatively, if the class's methods are not required in this scope, consider removing the message-send expression or restructuring the code to avoid this pattern.

 
AI Generated

Example

In the example, a class named C is forward declared using @class C;. This means that the declaration informs the compiler about the existence of class C without providing its detailed definition. The main function tries to send a message someMethod to the class C. However, since C is only forward declared and its full interface is not defined at this point (i.e., there are no details about its methods or properties), the compiler issues a warning. This warning indicates that it cannot confirm the existence of the method someMethod on class C due to the class being only forward declared. As a result, this situation could lead to undefined behavior if the interface for C is not found during later stages of compilation. The compiler's warning about the receiver being a forward class without a definite @interface serves as a caution to ensure that the class is fully defined before it is used in message sending.  
AI Generated


Flags -xobjective-c -Wreceiver-forward-class

[Try out in Compiler Explorer]

Source
@class C;

int main() {
  [C someMethod]; // Forward declaration of C
  return 0;
}
Compiler Output
<source>:4:4: warning: receiver 'C' is a forward class and corresponding @interface may not exist [-Wreceiver-forward-class]
<source>:1:8: note: forward declaration of class here
<source>:4:6: warning: class method '+someMethod' not found (return type defaults to 'id') [-Wobjc-method-access]


Clang Internals (17.0.6)

Git Commit Message

Warn if forward class is used as a receiver.

llvm-svn: 71278

Used in Clang Sources

This section lists all occurrences of the diagnostic within the Clang's codebase. For each occurrence, an auto-extracted snipped from the source code is listed including key elements like control structures, functions, or classes. It should illustrate the conditions under which the diagnostic is activated.

clang/lib/Sema/SemaExprObjC.cpp (line 2663)

/// \param ReceiverType The type of the object receiving the
/// message. When \p ReceiverTypeInfo is non-NULL, this is the same
/// type as that refers to. For a superclass send, this is the type of
/// the superclass.
///
/// \param SuperLoc The location of the "super" keyword in a
/// superclass message.
///
/// \param Sel The selector to which the message is being sent.
///
/// \param Method The method that this class message is invoking, if
/// already known.
///
/// \param LBracLoc The location of the opening square bracket ']'.
///
/// \param RBracLoc The location of the closing square bracket ']'.
///
/// \param ArgsIn The message arguments.
ExprResult Sema::BuildClassMessage(TypeSourceInfo *ReceiverTypeInfo, QualType ReceiverType, SourceLocation SuperLoc, Selector Sel, ObjCMethodDecl *Method, SourceLocation LBracLoc, ArrayRef<SourceLocation> SelectorLocs, SourceLocation RBracLoc, MultiExprArg ArgsIn, bool isImplicit) {
  // ...
  // Find the method we are messaging.
  if (!Method) {
    // ...
    if (RequireCompleteType(Loc, Context.getObjCInterfaceType(Class), (getLangOpts().ObjCAutoRefCount ? diag::err_arc_receiver_forward_class : diag::warn_receiver_forward_class), TypeRange)) {

Triggered in Clang Tests

This section lists all internal Clang test cases that trigger the diagnostic.

clang/test/SemaObjC/forward-class-receiver.m

  • clang/test/SemaObjC/forward-class-receiver.m:12:4: warning: receiver 'NotKnown' is a forward class and corresponding @interface may not exist [-Wreceiver-forward-class]