Loading clang/lib/Sema/SemaPseudoObject.cpp +20 −3 Original line number Diff line number Diff line Loading @@ -214,6 +214,7 @@ namespace { ObjCMethodDecl *Setter; Selector SetterSelector; Selector GetterSelector; public: ObjCPropertyOpBuilder(Sema &S, ObjCPropertyRefExpr *refExpr) : Loading Loading @@ -475,8 +476,24 @@ bool ObjCPropertyOpBuilder::findGetter() { // For implicit properties, just trust the lookup we already did. if (RefExpr->isImplicitProperty()) { Getter = RefExpr->getImplicitPropertyGetter(); return (Getter != 0); if ((Getter = RefExpr->getImplicitPropertyGetter())) { GetterSelector = Getter->getSelector(); return true; } else { // Must build the getter selector the hard way. ObjCMethodDecl *setter = RefExpr->getImplicitPropertySetter(); assert(setter && "both setter and getter are null - cannot happen"); IdentifierInfo *setterName = setter->getSelector().getIdentifierInfoForSlot(0); const char *compStr = setterName->getNameStart(); compStr += 3; IdentifierInfo *getterName = &S.Context.Idents.get(compStr); GetterSelector = S.PP.getSelectorTable().getNullarySelector(getterName); return false; } } ObjCPropertyDecl *prop = RefExpr->getExplicitProperty(); Loading Loading @@ -776,7 +793,7 @@ ObjCPropertyOpBuilder::buildIncDecOperation(Scope *Sc, SourceLocation opcLoc, assert(RefExpr->isImplicitProperty()); S.Diag(opcLoc, diag::err_nogetter_property_incdec) << unsigned(UnaryOperator::isDecrementOp(opcode)) << RefExpr->getImplicitPropertyGetter()->getSelector() // FIXME! << GetterSelector << op->getSourceRange(); return ExprError(); } Loading clang/test/SemaObjC/error-implicit-property.m 0 → 100644 +30 −0 Original line number Diff line number Diff line // RUN: %clang_cc1 -verify %s // rdar://11273060 @interface I - (void) setP : (int)arg; @end @interface J - (int) P; @end @interface K @end @interface II @end @implementation II - (void) Meth : (I*) arg { arg.P++; // expected-error {{no getter method 'P' for increment of property}} --arg.P; // expected-error {{no getter method 'P' for decrement of property}} } - (void) Meth1 : (J*) arg { arg.P++; // expected-error {{no setter method 'setP:' for increment of property}} arg.P--; // expected-error {{no setter method 'setP:' for decrement of property}} } - (void) Meth2 : (K*) arg { arg.P++; // expected-error {{property 'P' not found on object of type 'K *'}} arg.P--; // expected-error {{property 'P' not found on object of type 'K *'}} } @end Loading
clang/lib/Sema/SemaPseudoObject.cpp +20 −3 Original line number Diff line number Diff line Loading @@ -214,6 +214,7 @@ namespace { ObjCMethodDecl *Setter; Selector SetterSelector; Selector GetterSelector; public: ObjCPropertyOpBuilder(Sema &S, ObjCPropertyRefExpr *refExpr) : Loading Loading @@ -475,8 +476,24 @@ bool ObjCPropertyOpBuilder::findGetter() { // For implicit properties, just trust the lookup we already did. if (RefExpr->isImplicitProperty()) { Getter = RefExpr->getImplicitPropertyGetter(); return (Getter != 0); if ((Getter = RefExpr->getImplicitPropertyGetter())) { GetterSelector = Getter->getSelector(); return true; } else { // Must build the getter selector the hard way. ObjCMethodDecl *setter = RefExpr->getImplicitPropertySetter(); assert(setter && "both setter and getter are null - cannot happen"); IdentifierInfo *setterName = setter->getSelector().getIdentifierInfoForSlot(0); const char *compStr = setterName->getNameStart(); compStr += 3; IdentifierInfo *getterName = &S.Context.Idents.get(compStr); GetterSelector = S.PP.getSelectorTable().getNullarySelector(getterName); return false; } } ObjCPropertyDecl *prop = RefExpr->getExplicitProperty(); Loading Loading @@ -776,7 +793,7 @@ ObjCPropertyOpBuilder::buildIncDecOperation(Scope *Sc, SourceLocation opcLoc, assert(RefExpr->isImplicitProperty()); S.Diag(opcLoc, diag::err_nogetter_property_incdec) << unsigned(UnaryOperator::isDecrementOp(opcode)) << RefExpr->getImplicitPropertyGetter()->getSelector() // FIXME! << GetterSelector << op->getSourceRange(); return ExprError(); } Loading
clang/test/SemaObjC/error-implicit-property.m 0 → 100644 +30 −0 Original line number Diff line number Diff line // RUN: %clang_cc1 -verify %s // rdar://11273060 @interface I - (void) setP : (int)arg; @end @interface J - (int) P; @end @interface K @end @interface II @end @implementation II - (void) Meth : (I*) arg { arg.P++; // expected-error {{no getter method 'P' for increment of property}} --arg.P; // expected-error {{no getter method 'P' for decrement of property}} } - (void) Meth1 : (J*) arg { arg.P++; // expected-error {{no setter method 'setP:' for increment of property}} arg.P--; // expected-error {{no setter method 'setP:' for decrement of property}} } - (void) Meth2 : (K*) arg { arg.P++; // expected-error {{property 'P' not found on object of type 'K *'}} arg.P--; // expected-error {{property 'P' not found on object of type 'K *'}} } @end