summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--lib/Sema/SemaPseudoObject.cpp23
-rw-r--r--test/SemaObjC/error-implicit-property.m30
2 files changed, 50 insertions, 3 deletions
diff --git a/lib/Sema/SemaPseudoObject.cpp b/lib/Sema/SemaPseudoObject.cpp
index 3a54876771..0e6632964a 100644
--- a/lib/Sema/SemaPseudoObject.cpp
+++ b/lib/Sema/SemaPseudoObject.cpp
@@ -214,6 +214,7 @@ namespace {
ObjCMethodDecl *Setter;
Selector SetterSelector;
+ Selector GetterSelector;
public:
ObjCPropertyOpBuilder(Sema &S, ObjCPropertyRefExpr *refExpr) :
@@ -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();
@@ -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();
}
diff --git a/test/SemaObjC/error-implicit-property.m b/test/SemaObjC/error-implicit-property.m
new file mode 100644
index 0000000000..ea0587a744
--- /dev/null
+++ b/test/SemaObjC/error-implicit-property.m
@@ -0,0 +1,30 @@
+// 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