[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