[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