[cfe-commits] r66040 - in /cfe/trunk: lib/Sema/SemaExprObjC.cpp test/SemaObjC/call-super-2.m test/SemaObjC/class-method-lookup.m
Fariborz Jahanian
fjahanian at apple.com
Wed Mar 4 09:50:39 PST 2009
Author: fjahanian
Date: Wed Mar 4 11:50:39 2009
New Revision: 66040
URL: http://llvm.org/viewvc/llvm-project?rev=66040&view=rev
Log:
Fix a corner case of message lookup looking for class methods.
If all else failed, find the message in class's root's
list of instacne methods!
Added:
cfe/trunk/test/SemaObjC/class-method-lookup.m
Modified:
cfe/trunk/lib/Sema/SemaExprObjC.cpp
cfe/trunk/test/SemaObjC/call-super-2.m
Modified: cfe/trunk/lib/Sema/SemaExprObjC.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaExprObjC.cpp?rev=66040&r1=66039&r2=66040&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/SemaExprObjC.cpp (original)
+++ cfe/trunk/lib/Sema/SemaExprObjC.cpp Wed Mar 4 11:50:39 2009
@@ -314,8 +314,14 @@
Method = LookupPrivateMethod(Sel, ClassDecl);
// Before we give up, check if the selector is an instance method.
- if (!Method)
- Method = ClassDecl->lookupInstanceMethod(Sel);
+ // But only in the root. This matches gcc's behaviour and what the
+ // runtime expects.
+ if (!Method) {
+ ObjCInterfaceDecl *Root = ClassDecl;
+ while (Root->getSuperClass())
+ Root = Root->getSuperClass();
+ Method = Root->lookupInstanceMethod(Sel);
+ }
if (Method && DiagnoseUseOfDecl(Method, receiverLoc))
return true;
@@ -400,6 +406,15 @@
if (!Method)
Method = LookupPrivateMethod(Sel, ClassDecl);
+ // Before we give up, check if the selector is an instance method.
+ // But only in the root. This matches gcc's behaviour and what the
+ // runtime expects.
+ if (!Method) {
+ ObjCInterfaceDecl *Root = ClassDecl;
+ while (Root->getSuperClass())
+ Root = Root->getSuperClass();
+ Method = Root->lookupInstanceMethod(Sel);
+ }
}
if (Method && DiagnoseUseOfDecl(Method, receiverLoc))
return true;
@@ -408,9 +423,12 @@
// If not messaging 'self', look for any factory method named 'Sel'.
if (!isSelfExpr(RExpr)) {
Method = FactoryMethodPool[Sel].Method;
- if (!Method)
+ if (!Method) {
Method = LookupInstanceMethodInGlobalPool(
Sel, SourceRange(lbrac,rbrac));
+ if (Method)
+ Diag(receiverLoc, diag::warn_maynot_respond) << Sel;
+ }
}
}
if (CheckMessageArgumentTypes(ArgExprs, NumArgs, Sel, Method, false,
Modified: cfe/trunk/test/SemaObjC/call-super-2.m
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/SemaObjC/call-super-2.m?rev=66040&r1=66039&r2=66040&view=diff
==============================================================================
--- cfe/trunk/test/SemaObjC/call-super-2.m (original)
+++ cfe/trunk/test/SemaObjC/call-super-2.m Wed Mar 4 11:50:39 2009
@@ -83,7 +83,7 @@
}
- (int) instance_func5
{
- int i = (size_t)[Derived instance_func1]; // GCC currently warns.
+ int i = (size_t)[Derived instance_func1]; // expected-warning {{method '+instance_func1' not found (return type defaults to 'id')}}
return i + (size_t)[Object instance_func1]; // expected-warning {{method '+instance_func1' not found (return type defaults to 'id')}}
}
- (int) instance_func6
Added: cfe/trunk/test/SemaObjC/class-method-lookup.m
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/SemaObjC/class-method-lookup.m?rev=66040&view=auto
==============================================================================
--- cfe/trunk/test/SemaObjC/class-method-lookup.m (added)
+++ cfe/trunk/test/SemaObjC/class-method-lookup.m Wed Mar 4 11:50:39 2009
@@ -0,0 +1,46 @@
+// RUN: clang -fsyntax-only -verify %s
+
+ at interface MyBase
+- (void) rootInstanceMethod;
+ at end
+
+ at interface MyIntermediate: MyBase
+ at end
+
+ at interface MyDerived: MyIntermediate
+- (void) instanceMethod;
++ (void) classMethod;
+ at end
+
+ at implementation MyDerived
+- (void) instanceMethod {
+}
+
++ (void) classMethod { /* If a class method is not found, the root */
+ [self rootInstanceMethod]; /* class is searched for an instance method */
+ [MyIntermediate rootInstanceMethod]; /* with the same name. */
+
+ [self instanceMethod];// expected-warning {{'-instanceMethod' not found (return type defaults to 'id')}}
+ [MyDerived instanceMethod];// expected-warning {{'+instanceMethod' not found (return type defaults to 'id')}}
+}
+ at end
+
+ at interface Object @end
+
+ at interface Class1
+- (void)setWindow:(Object *)wdw;
+ at end
+
+ at interface Class2
+- (void)setWindow:(Class1 *)window;
+ at end
+
+#define nil (void*)0
+
+id foo(void) {
+ Object *obj;
+ id obj2 = obj;
+ [obj setWindow:nil]; // expected-warning {{Object may not respond to 'setWindow:'}}
+
+ return obj;
+}
More information about the cfe-commits
mailing list