diff --git a/clang/lib/Sema/SemaExprObjC.cpp b/clang/lib/Sema/SemaExprObjC.cpp index 5bffdd1573a6..8dd319c98bdc 100644 --- a/clang/lib/Sema/SemaExprObjC.cpp +++ b/clang/lib/Sema/SemaExprObjC.cpp @@ -1762,10 +1762,7 @@ ActOnClassPropertyRefExpr(IdentifierInfo &receiverName, // If this reference is in an @implementation, check for 'private' methods. if (!Getter) - if (ObjCMethodDecl *CurMeth = getCurMethodDecl()) - if (ObjCInterfaceDecl *ClassDecl = CurMeth->getClassInterface()) - if (ObjCImplementationDecl *ImpDecl = ClassDecl->getImplementation()) - Getter = ImpDecl->getClassMethod(Sel); + Getter = IFace->lookupPrivateClassMethod(Sel); if (Getter) { // FIXME: refactor/share with ActOnMemberReference(). @@ -1784,10 +1781,7 @@ ActOnClassPropertyRefExpr(IdentifierInfo &receiverName, 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 = ClassDecl->getImplementation()) - Setter = ImpDecl->getClassMethod(SetterSel); + Setter = IFace->lookupPrivateClassMethod(SetterSel); } // Look through local category implementations associated with the class. if (!Setter) diff --git a/clang/lib/Sema/SemaPseudoObject.cpp b/clang/lib/Sema/SemaPseudoObject.cpp index de02fa935ef6..a8463cdbd4ef 100644 --- a/clang/lib/Sema/SemaPseudoObject.cpp +++ b/clang/lib/Sema/SemaPseudoObject.cpp @@ -681,7 +681,8 @@ ExprResult ObjCPropertyOpBuilder::buildGet() { // Build a message-send. ExprResult msg; - if (Getter->isInstanceMethod() || RefExpr->isObjectReceiver()) { + if ((Getter->isInstanceMethod() && !RefExpr->isClassReceiver()) || + RefExpr->isObjectReceiver()) { assert(InstanceReceiver || RefExpr->isSuperReceiver()); msg = S.BuildInstanceMessageImplicit(InstanceReceiver, receiverType, GenericLoc, Getter->getSelector(), @@ -750,7 +751,8 @@ ExprResult ObjCPropertyOpBuilder::buildSet(Expr *op, SourceLocation opcLoc, // Build a message-send. ExprResult msg; - if (Setter->isInstanceMethod() || RefExpr->isObjectReceiver()) { + if ((Setter->isInstanceMethod() && !RefExpr->isClassReceiver()) || + RefExpr->isObjectReceiver()) { msg = S.BuildInstanceMessageImplicit(InstanceReceiver, receiverType, GenericLoc, SetterSelector, Setter, MultiExprArg(args, 1)); diff --git a/clang/test/SemaObjC/class-property-access.m b/clang/test/SemaObjC/class-property-access.m index 735b51a3c432..a4c188c434ec 100644 --- a/clang/test/SemaObjC/class-property-access.m +++ b/clang/test/SemaObjC/class-property-access.m @@ -11,3 +11,46 @@ int main () return Test.one.two; } +// rdar://16650575 +__attribute__((objc_root_class)) +@interface RootClass { + Class isa; +} + +@property int property; +-(int)method; +- (void) setMethod : (int)arg; ++(int)classMethod; +@end + +@interface Subclass : RootClass @end +void Test1() { + // now okay + (void)RootClass.property; + (void)Subclass.property; + (void)RootClass.method; + (void)Subclass.method; + + RootClass.property = 1; + Subclass.property = 2; + RootClass.method = 3; + Subclass.method = 4; + + // okay + (void)RootClass.classMethod; + (void)Subclass.classMethod; + + // also okay + [RootClass property]; + [Subclass property]; + [RootClass method]; + [Subclass method]; + [RootClass classMethod]; + [Subclass classMethod]; + + // also okay + [RootClass setProperty : 1]; + [Subclass setProperty : 2]; + [RootClass setMethod : 3]; + [Subclass setMethod : 4]; +}