[cfe-commits] r66658 - in /cfe/trunk: lib/Sema/SemaExpr.cpp test/SemaObjC/property-user-setter.m

Steve Naroff snaroff at apple.com
Wed Mar 11 06:48:17 PDT 2009


Author: snaroff
Date: Wed Mar 11 08:48:17 2009
New Revision: 66658

URL: http://llvm.org/viewvc/llvm-project?rev=66658&view=rev
Log:
Fix <rdar://problem/6578665> user declared setter method should be used when using property syntx.

Modified:
    cfe/trunk/lib/Sema/SemaExpr.cpp
    cfe/trunk/test/SemaObjC/property-user-setter.m

Modified: cfe/trunk/lib/Sema/SemaExpr.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaExpr.cpp?rev=66658&r1=66657&r2=66658&view=diff

==============================================================================
--- cfe/trunk/lib/Sema/SemaExpr.cpp (original)
+++ cfe/trunk/lib/Sema/SemaExpr.cpp Wed Mar 11 08:48:17 2009
@@ -1883,38 +1883,47 @@
       // Check if we can reference this property.
       if (DiagnoseUseOfDecl(Getter, MemberLoc))
         return ExprError();
-
-      // If we found a getter then this may be a valid dot-reference, we
-      // will look for the matching setter, in case it is needed.
-      Selector SetterSel = 
-        SelectorTable::constructSetterName(PP.getIdentifierTable(), 
-                                           PP.getSelectorTable(), &Member);
-      ObjCMethodDecl *Setter = IFace->lookupInstanceMethod(SetterSel);
-      if (!Setter) {
-        // If this reference is in an @implementation, also check for 'private'
-        // methods.
-        if (ObjCMethodDecl *CurMeth = getCurMethodDecl())
-          if (ObjCInterfaceDecl *ClassDecl = CurMeth->getClassInterface())
-            if (ObjCImplementationDecl *ImpDecl =
-                  ObjCImplementations[ClassDecl->getIdentifier()])
-              Setter = ImpDecl->getInstanceMethod(SetterSel);
-      }
-      // Look through local category implementations associated with the class.
-      if (!Setter) {
-        for (unsigned i = 0; i < ObjCCategoryImpls.size() && !Setter; i++) {
-          if (ObjCCategoryImpls[i]->getClassInterface() == IFace)
-            Setter = ObjCCategoryImpls[i]->getInstanceMethod(SetterSel);
-        }
+    }
+    // If we found a getter then this may be a valid dot-reference, we
+    // will look for the matching setter, in case it is needed.
+    Selector SetterSel = 
+      SelectorTable::constructSetterName(PP.getIdentifierTable(), 
+                                         PP.getSelectorTable(), &Member);
+    ObjCMethodDecl *Setter = IFace->lookupInstanceMethod(SetterSel);
+    if (!Setter) {
+      // If this reference is in an @implementation, also check for 'private'
+      // methods.
+      if (ObjCMethodDecl *CurMeth = getCurMethodDecl())
+        if (ObjCInterfaceDecl *ClassDecl = CurMeth->getClassInterface())
+          if (ObjCImplementationDecl *ImpDecl =
+                ObjCImplementations[ClassDecl->getIdentifier()])
+            Setter = ImpDecl->getInstanceMethod(SetterSel);
+    }
+    // Look through local category implementations associated with the class.
+    if (!Setter) {
+      for (unsigned i = 0; i < ObjCCategoryImpls.size() && !Setter; i++) {
+        if (ObjCCategoryImpls[i]->getClassInterface() == IFace)
+          Setter = ObjCCategoryImpls[i]->getInstanceMethod(SetterSel);
       }
+    }
 
-      if (Setter && DiagnoseUseOfDecl(Setter, MemberLoc))
-        return ExprError();
+    if (Setter && DiagnoseUseOfDecl(Setter, MemberLoc))
+      return ExprError();
+
+    if (Getter || Setter) {
+      QualType PType;
 
+      if (Getter)
+        PType = Getter->getResultType();
+      else {
+        for (ObjCMethodDecl::param_iterator PI = Setter->param_begin(),
+             E = Setter->param_end(); PI != E; ++PI)
+          PType = (*PI)->getType();
+      }
       // FIXME: we must check that the setter has property type.
-      return Owned(new (Context) ObjCKVCRefExpr(Getter, Getter->getResultType(),
+      return Owned(new (Context) ObjCKVCRefExpr(Getter, PType,
                                       Setter, MemberLoc, BaseExpr));
     }
-
     return ExprError(Diag(MemberLoc, diag::err_property_not_found)
       << &Member << BaseType);
   }

Modified: cfe/trunk/test/SemaObjC/property-user-setter.m
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/SemaObjC/property-user-setter.m?rev=66658&r1=66657&r2=66658&view=diff

==============================================================================
--- cfe/trunk/test/SemaObjC/property-user-setter.m (original)
+++ cfe/trunk/test/SemaObjC/property-user-setter.m Wed Mar 11 08:48:17 2009
@@ -59,3 +59,32 @@
 
 @end
 
+static int g_val;
+
+ at interface Root 
++ alloc;
+- init;
+ at end
+
+ at interface Subclass : Root
+{
+    int setterOnly;
+}
+- (void) setSetterOnly:(int)value;
+ at end
+
+ at implementation Subclass
+- (void) setSetterOnly:(int)value {
+    setterOnly = value;
+    g_val = setterOnly;
+}
+ at end
+
+int main (void) {
+    Subclass *x = [[Subclass alloc] init];
+
+    x.setterOnly = 4;
+    if (g_val != 4)
+      abort ();
+    return 0;
+}





More information about the cfe-commits mailing list