]> granicus.if.org Git - clang/commitdiff
More type checking for properties, accessors and
authorFariborz Jahanian <fjahanian@apple.com>
Fri, 8 May 2009 19:36:34 +0000 (19:36 +0000)
committerFariborz Jahanian <fjahanian@apple.com>
Fri, 8 May 2009 19:36:34 +0000 (19:36 +0000)
use of dot-syntax expression. This is to match gcc's.

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

include/clang/Basic/DiagnosticSemaKinds.td
lib/Sema/SemaDeclObjC.cpp
lib/Sema/SemaExpr.cpp
test/SemaObjC/property-typecheck-1.m

index f4da72531487218cbf36cca8c3f6f0074060eb74..a8d079d720a7810149e0fb7a73f1bc0c92a5dc62 100644 (file)
@@ -174,7 +174,7 @@ def warn_conflicting_param_types : Warning<
   "conflicting parameter types in implementation of %0: %1 vs %2">;
 
 def warn_multiple_method_decl : Warning<"multiple methods named %0 found">;
-def err_accessor_property_type_mismatch : Error<
+def warn_accessor_property_type_mismatch : Warning<
   "type of property %0 does not match type of accessor %1">;
 def note_declared_at : Note<"declared at">;
 def err_setter_type_void : Error<"type of setter must be void">;
index e35b7a919b49f1e24d1b71c5ed3d78d407b66f39..34afdedba7da63c4009a059db836c28474af6c73 100644 (file)
@@ -1315,11 +1315,17 @@ void Sema::ProcessPropertyDecl(ObjCPropertyDecl *property,
   
   if (GetterMethod &&
       GetterMethod->getResultType() != property->getType()) {
-    Diag(property->getLocation(), 
-         diag::err_accessor_property_type_mismatch) 
-      << property->getDeclName()
-      << GetterMethod->getSelector();
-    Diag(GetterMethod->getLocation(), diag::note_declared_at);
+    AssignConvertType result = Incompatible;
+    if (Context.isObjCObjectPointerType(property->getType()))
+      result = CheckAssignmentConstraints(property->getType(), 
+                                          GetterMethod->getResultType());
+    if (result != Compatible) {
+      Diag(property->getLocation(), 
+           diag::warn_accessor_property_type_mismatch) 
+        << property->getDeclName()
+        << GetterMethod->getSelector();
+      Diag(GetterMethod->getLocation(), diag::note_declared_at);
+    }
   }
   
   if (SetterMethod) {
@@ -1329,7 +1335,7 @@ void Sema::ProcessPropertyDecl(ObjCPropertyDecl *property,
     if (SetterMethod->param_size() != 1 ||
         ((*SetterMethod->param_begin())->getType() != property->getType())) {
       Diag(property->getLocation(), 
-           diag::err_accessor_property_type_mismatch) 
+           diag::warn_accessor_property_type_mismatch) 
         << property->getDeclName()
         << SetterMethod->getSelector();
       Diag(SetterMethod->getLocation(), diag::note_declared_at);
index 79c471a2d485c81a5d07d7d2401251cbf1b7c931..f698620543fbb942bd8bcdbaabcef816cbe63f7a 100644 (file)
@@ -2096,8 +2096,21 @@ Sema::ActOnMemberReferenceExpr(Scope *S, ExprArg Base, SourceLocation OpLoc,
       // Check whether we can reference this property.
       if (DiagnoseUseOfDecl(PD, MemberLoc))
         return ExprError();
-
-      return Owned(new (Context) ObjCPropertyRefExpr(PD, PD->getType(),
+      QualType ResTy = PD->getType();
+      Selector Sel = PP.getSelectorTable().getNullarySelector(&Member);
+      ObjCMethodDecl *Getter = IFace->lookupInstanceMethod(Context, Sel);
+      if (Getter) {
+        AssignConvertType result =
+          CheckAssignmentConstraints(PD->getType(), Getter->getResultType());
+        if (result != Compatible) {
+          Diag(MemberLoc, diag::warn_accessor_property_type_mismatch) 
+            << PD->getDeclName() << Sel;
+          Diag(Getter->getLocation(), diag::note_declared_at);
+          ResTy = Getter->getResultType();
+        }
+      }
+      
+      return Owned(new (Context) ObjCPropertyRefExpr(PD, ResTy,
                                                      MemberLoc, BaseExpr));
     }
 
index 1795da8599b5b93626718287857929f9e7eee508..c4d7cd2448d5e1b4963b9971a1ee605ba0d72555 100644 (file)
@@ -2,7 +2,7 @@
 
 @interface A
 -(float) x;    // expected-note {{declared at}}
-@property int x; // expected-error {{type of property 'x' does not match type of accessor 'x'}}
+@property int x; // expected-warning {{type of property 'x' does not match type of accessor 'x'}}
 @end
 
 @interface A (Cat)
@@ -29,3 +29,73 @@ typedef void (F)(void);
 @end
 
 
+@class SSyncSet;
+
+@interface SPeer
+  @property(nonatomic,readonly,retain) SSyncSet* syncSet;
+@end
+
+@class SSyncSet_iDisk;
+
+@interface SPeer_iDisk_remote1 : SPeer
+- (SSyncSet_iDisk*) syncSet; // expected-note {{declared at}}
+@end
+
+@interface SPeer_iDisk_local
+- (SSyncSet_iDisk*) syncSet;
+@end
+
+@interface SSyncSet
+@end
+
+@interface SSyncSet_iDisk
+@property(nonatomic,readonly,retain) SPeer_iDisk_local* localPeer;
+@end
+
+@interface SPeer_iDisk_remote1 (protected)
+@end
+
+@implementation SPeer_iDisk_remote1 (protected)
+- (id) preferredSource1
+{
+  return self.syncSet.localPeer; // expected-warning {{type of property 'syncSet' does not match type of accessor 'syncSet'}}
+}
+@end
+
+@interface NSArray @end
+
+@interface NSMutableArray : NSArray
+@end
+
+@interface Class1 
+{
+ NSMutableArray* pieces;
+ NSArray* first;
+}
+
+@property (readonly) NSArray* pieces;
+@property (readonly) NSMutableArray* first; // expected-warning {{type of property 'first' does not match type of accessor 'first'}}
+
+- (NSMutableArray*) pieces;
+- (NSArray*) first;    // expected-note {{declared at}}  // expected-note {{declared at}}
+@end
+
+@interface Class2  {
+ Class1* container;
+}
+
+@end
+
+@implementation Class2
+
+- (id) lastPiece
+{
+ return container.pieces;
+}
+
+- (id)firstPeice
+{
+  return container.first; // expected-warning {{type of property 'first' does not match type of accessor 'first'}}
+}
+@end
+