]> granicus.if.org Git - clang/commitdiff
Complain on missing property getter method only
authorFariborz Jahanian <fjahanian@apple.com>
Wed, 22 Dec 2010 19:46:35 +0000 (19:46 +0000)
committerFariborz Jahanian <fjahanian@apple.com>
Wed, 22 Dec 2010 19:46:35 +0000 (19:46 +0000)
if property-dot expression is decidedly
an rvalue. // rdar://8155806.

git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@122430 91177308-0d34-0410-b5e6-96231b3b80d8

include/clang/Basic/DiagnosticSemaKinds.td
lib/AST/StmtDumper.cpp
lib/Sema/SemaExpr.cpp
lib/Sema/SemaExprObjC.cpp
test/SemaObjC/error-missing-getter.m [new file with mode: 0644]
test/SemaObjC/property-user-setter.m

index adc005bcd62da8d0252ca84bedaaa06495db019e..974250108889f9a62c8511234dd841939fb324b9 100644 (file)
@@ -2450,6 +2450,8 @@ def err_ref_array_type : Error<
   "cannot refer to declaration with an array type inside block">;
 def err_property_not_found : Error<
   "property %0 not found on object of type %1">;
+def err_getter_not_found : Error<
+  "expected getter method not found on object of type %0">;
 def err_property_not_found_forward_class : Error<
   "property %0 cannot be found in forward class object %1">;
 def note_forward_class : Note<
index 56bfa35425d9ae0ab233598c4e4471d25cb24e6c..8b62dcc940b19d6217b6dafc7d174b0cddd55966 100644 (file)
@@ -598,9 +598,13 @@ void StmtDumper::VisitObjCProtocolExpr(ObjCProtocolExpr *Node) {
 void StmtDumper::VisitObjCPropertyRefExpr(ObjCPropertyRefExpr *Node) {
   DumpExpr(Node);
   if (Node->isImplicitProperty()) {
-    OS << " Kind=MethodRef Getter=\""
-       << Node->getImplicitPropertyGetter()->getSelector().getAsString()
-       << "\" Setter=\"";
+    OS << " Kind=MethodRef Getter=\"";
+    if (Node->getImplicitPropertyGetter())
+      OS << Node->getImplicitPropertyGetter()->getSelector().getAsString();
+    else
+      OS << "(null)";
+
+    OS << "\" Setter=\"";
     if (ObjCMethodDecl *Setter = Node->getImplicitPropertySetter())
       OS << Setter->getSelector().getAsString();
     else
index 56ad9b4241065c6738917a1f53aedf81f9ee8535..e2a6d3461640a6f8326ff967b7158a05d38bd648 100644 (file)
@@ -7097,8 +7097,15 @@ void Sema::ConvertPropertyForRValue(Expr *&E) {
 
   ExprValueKind VK = VK_RValue;
   if (PRE->isImplicitProperty()) {
-    QualType Result = PRE->getImplicitPropertyGetter()->getResultType();
-    VK = Expr::getValueKindForType(Result);
+    if (const ObjCMethodDecl *GetterMethod = 
+          PRE->getImplicitPropertyGetter()) {
+      QualType Result = GetterMethod->getResultType();
+      VK = Expr::getValueKindForType(Result);
+    }
+    else {
+      Diag(PRE->getLocation(), diag::err_getter_not_found)
+            << PRE->getBase()->getType();
+    }
   }
 
   E = ImplicitCastExpr::Create(Context, E->getType(), CK_GetObjCProperty,
index bbb047990bb75555a12961be90e9551838a0dcb6..f4c593b0daee0a7920e5515d4309cf413116fbd3 100644 (file)
@@ -439,8 +439,15 @@ HandleExprPropertyRefExpr(const ObjCObjectPointerType *OPT,
   if (Setter && DiagnoseUseOfDecl(Setter, MemberLoc))
     return ExprError();
 
-  if (Getter) {
-    QualType PType = Getter->getSendResultType();
+  if (Getter || Setter) {
+    QualType PType;
+    if (Getter)
+      PType = Getter->getSendResultType();
+    else {
+      ParmVarDecl *ArgDecl = *Setter->param_begin();
+      PType = ArgDecl->getType();
+    }
+    
     ExprValueKind VK = VK_LValue;
     ExprObjectKind OK = OK_ObjCProperty;
     if (!getLangOptions().CPlusPlus && !PType.hasQualifiers() &&
@@ -476,9 +483,9 @@ HandleExprPropertyRefExpr(const ObjCObjectPointerType *OPT,
   
   Diag(MemberLoc, diag::err_property_not_found)
     << MemberName << QualType(OPT, 0);
-  if (Setter && !Getter)
+  if (Setter)
     Diag(Setter->getLocation(), diag::note_getter_unavailable)
-      << MemberName << BaseExpr->getSourceRange();
+          << MemberName << BaseExpr->getSourceRange();
   return ExprError();
 }
 
diff --git a/test/SemaObjC/error-missing-getter.m b/test/SemaObjC/error-missing-getter.m
new file mode 100644 (file)
index 0000000..3c91ab2
--- /dev/null
@@ -0,0 +1,19 @@
+// RUN: %clang_cc1  -fsyntax-only -verify %s
+// rdar://8155806
+
+@interface Subclass 
+{
+    int setterOnly;
+}
+- (void) setSetterOnly : (int) arg;
+@end
+
+int func (int arg, Subclass *x) {
+    if (x.setterOnly) { // expected-error {{expected getter method not found on object of type 'Subclass *'}}
+      x.setterOnly = 1;
+    }
+    func(x.setterOnly + 1, x); // expected-error {{expected getter method not found on object of type 'Subclass *'}} 
+    int i = x.setterOnly + 1;  // expected-error {{expected getter method not found on object of type 'Subclass *'}} 
+    return x.setterOnly + 1;   // expected-error {{expected getter method not found on object of type 'Subclass *'}} 
+}
+
index 9479bc6a73b29d553b94b9c77c71926d8127c079..2f1e19727a88863c3a0645eba29b9e8420fa593a 100644 (file)
@@ -70,7 +70,7 @@ static int g_val;
 {
     int setterOnly;
 }
-- (void) setSetterOnly:(int)value;     // expected-note {{or because setter is declared here, but no getter method 'setterOnly' is found}}
+- (void) setSetterOnly:(int)value;
 @end
 
 @implementation Subclass
@@ -82,14 +82,14 @@ static int g_val;
 
 @interface C {}
 // - (int)Foo;
-- (void)setFoo:(int)value;     // expected-note 2 {{or because setter is declared here, but no getter method 'Foo' is found}}
+- (void)setFoo:(int)value;
 @end
 
 void g(int);
 
 void f(C *c) {
-    c.Foo = 17; // expected-error {{property 'Foo' not found on object of type 'C *'}}
-    g(c.Foo); // expected-error {{property 'Foo' not found on object of type 'C *'}}
+    c.Foo = 17; // OK 
+    g(c.Foo); // expected-error {{expected getter method not found on object of type 'C *'}}
 }
 
 
@@ -97,7 +97,7 @@ void abort(void);
 int main (void) {
     Subclass *x = [[Subclass alloc] init];
 
-    x.setterOnly = 4;  // expected-error {{property 'setterOnly' not found on object of type 'Subclass *'}}
+    x.setterOnly = 4;   // OK
     if (g_val != 4)
       abort ();
     return 0;