Commit b525b529 authored by Fariborz Jahanian's avatar Fariborz Jahanian
Browse files

objective-c: Issue diagnostic when an implicit

property accessor (getter) missing, instead of crashing.
// rdar://11273060

llvm-svn: 155036
parent bb73d197
Loading
Loading
Loading
Loading
+20 −3
Original line number Diff line number Diff line
@@ -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();
  }
+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