aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--include/clang/Basic/DiagnosticSemaKinds.td5
-rw-r--r--lib/Sema/SemaExprObjC.cpp6
-rw-r--r--test/SemaObjC/receiver-forward-class.m19
3 files changed, 29 insertions, 1 deletions
diff --git a/include/clang/Basic/DiagnosticSemaKinds.td b/include/clang/Basic/DiagnosticSemaKinds.td
index 1c48a83ba6..b94b38007a 100644
--- a/include/clang/Basic/DiagnosticSemaKinds.td
+++ b/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<DiagGroup<"receiver-forward-class">>, 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/lib/Sema/SemaExprObjC.cpp b/lib/Sema/SemaExprObjC.cpp
index 82e8171d66..7e2180fe0e 100644
--- a/lib/Sema/SemaExprObjC.cpp
+++ b/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/test/SemaObjC/receiver-forward-class.m b/test/SemaObjC/receiver-forward-class.m
new file mode 100644
index 0000000000..cefb5d782f
--- /dev/null
+++ b/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}}
+}
+