From c934de67e0c6f2b8000ecdfe66ecac37a5b78006 Mon Sep 17 00:00:00 2001 From: Fariborz Jahanian Date: Fri, 3 Feb 2012 01:02:44 +0000 Subject: [PATCH] objc: Issue diagnostic when receiver type is a forward class declaration and it is treated as of 'id' type resulting in multiple method lookup. // rdar://10686120 llvm-svn: 149653 --- .../clang/Basic/DiagnosticSemaKinds.td | 5 +++++ clang/lib/Sema/SemaExprObjC.cpp | 6 +++++- clang/test/SemaObjC/receiver-forward-class.m | 19 +++++++++++++++++++ 3 files changed, 29 insertions(+), 1 deletion(-) create mode 100644 clang/test/SemaObjC/receiver-forward-class.m diff --git a/clang/include/clang/Basic/DiagnosticSemaKinds.td b/clang/include/clang/Basic/DiagnosticSemaKinds.td index 1c48a83ba669..b94b38007a93 100644 --- a/clang/include/clang/Basic/DiagnosticSemaKinds.td +++ b/clang/include/clang/Basic/DiagnosticSemaKinds.td @@ -417,6 +417,8 @@ def note_implementation_declared : Note< "class implementation is declared here">; def note_class_declared : Note< "class is declared here">; +def note_receiver_is_id : Note< + "receiver is treated with 'id' type for purpose of method lookup">; def note_suppressed_class_declare : Note< "class with specified objc_requires_property_definitions attribute is declared here">; def warn_dup_category_def : Warning< @@ -3268,6 +3270,9 @@ def err_arc_may_not_respond : Error< "no visible @interface for %0 declares the selector %1">; def err_arc_receiver_forward_instance : Error< "receiver type %0 for instance message is a forward declaration">; +def warn_receiver_forward_instance : Warning< + "receiver type %0 for instance message is a forward declaration">, + InGroup>, DefaultIgnore; def err_arc_collection_forward : Error< "collection expression type %0 is a forward declaration">; def err_arc_multiple_method_decl : Error< diff --git a/clang/lib/Sema/SemaExprObjC.cpp b/clang/lib/Sema/SemaExprObjC.cpp index 82e8171d6661..7e2180fe0efe 100644 --- a/clang/lib/Sema/SemaExprObjC.cpp +++ b/clang/lib/Sema/SemaExprObjC.cpp @@ -1380,11 +1380,15 @@ ExprResult Sema::BuildInstanceMessage(Expr *Receiver, ? PDiag(diag::err_arc_receiver_forward_instance) << (Receiver ? Receiver->getSourceRange() : SourceRange(SuperLoc)) - : PDiag())) { + : PDiag(diag::warn_receiver_forward_instance) + << (Receiver ? Receiver->getSourceRange() + : SourceRange(SuperLoc)))) { if (getLangOptions().ObjCAutoRefCount) return ExprError(); forwardClass = OCIType->getInterfaceDecl(); + Diag(Receiver ? Receiver->getLocStart() + : SuperLoc, diag::note_receiver_is_id); Method = 0; } else { Method = ClassDecl->lookupInstanceMethod(Sel); diff --git a/clang/test/SemaObjC/receiver-forward-class.m b/clang/test/SemaObjC/receiver-forward-class.m new file mode 100644 index 000000000000..cefb5d782f99 --- /dev/null +++ b/clang/test/SemaObjC/receiver-forward-class.m @@ -0,0 +1,19 @@ +// RUN: %clang_cc1 -fsyntax-only -Wreceiver-forward-class -verify %s +// RUN: %clang_cc1 -x objective-c++ -fsyntax-only -Wreceiver-forward-class -verify %s +// rdar://10686120 + +@class A; // expected-note {{forward declaration of class here}} + +@interface B +-(int) width; // expected-note {{using}} +@end +@interface C +-(float) width; // expected-note {{also found}} +@end + +int f0(A *x) { + return [x width]; // expected-warning {{receiver type 'A' for instance message is a forward declaration}} \ + // expected-warning {{multiple methods named 'width' found}} \ + // expected-note {{receiver is treated with 'id' type for purpose of method lookup}} +} +