]> granicus.if.org Git - clang/commitdiff
Objective-C [qoi]. Issue warning and fixit if property-dot syntax
authorFariborz Jahanian <fjahanian@apple.com>
Fri, 8 Aug 2014 22:33:24 +0000 (22:33 +0000)
committerFariborz Jahanian <fjahanian@apple.com>
Fri, 8 Aug 2014 22:33:24 +0000 (22:33 +0000)
use mis-cased property name (which is currently accepted silently
due to the way property setters are named). rdar://17911746

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

include/clang/Basic/DiagnosticGroups.td
include/clang/Basic/DiagnosticSemaKinds.td
lib/Sema/SemaExprObjC.cpp
test/FixIt/property-access-fixit.m [new file with mode: 0644]
test/SemaObjC/property-user-setter.m

index 8beff3eeb6030c9b1aee61a9793459e208198102..c737270cae3f7a655df700fdbd1eeacefdd117a3 100644 (file)
@@ -429,6 +429,7 @@ def SelectorTypeMismatch : DiagGroup<"selector-type-mismatch">;
 def Selector : DiagGroup<"selector", [SelectorTypeMismatch]>;
 def Protocol : DiagGroup<"protocol">;
 def AtProtocol : DiagGroup<"at-protocol">;
+def PropertyAccessDotSyntax: DiagGroup<"property-access-dot-syntax">;
 def PropertyAttr : DiagGroup<"property-attribute-mismatch">;
 def SuperSubClassMismatch : DiagGroup<"super-class-method-mismatch">;
 def OverridingMethodMismatch : DiagGroup<"overriding-method-mismatch">;
index 800e591b4462d13ebe028827e4acd05f38a8ec21..624555c8076f0b2abe6279974e8ea1067bf4d24a 100644 (file)
@@ -6910,6 +6910,9 @@ def err_property_not_found_suggest : Error<
   "property %0 not found on object of type %1; did you mean %2?">;
 def err_ivar_access_using_property_syntax_suggest : Error<
   "property %0 not found on object of type %1; did you mean to access instance variable %2?">;
+def warn_property_access_suggest : Warning<
+"property %0 not found on object of type %1; did you mean to access property %2?">,
+InGroup<PropertyAccessDotSyntax>;
 def err_property_found_suggest : Error<
   "property %0 found on object of type %1; did you mean to access "
   "it with the \".\" operator?">;
index bed9c2f16d44cc6f80b34304e0f4076311b04aa6..8ec2c177f721c18f5e56ca82d77b13d5fe78ee62 100644 (file)
@@ -1700,6 +1700,18 @@ HandleExprPropertyRefExpr(const ObjCObjectPointerType *OPT,
   if (Setter && DiagnoseUseOfDecl(Setter, MemberLoc))
     return ExprError();
 
+  // Special warning if member name used in a property-dot for a setter accessor
+  // does not use a property with same name; e.g. obj.X = ... for a property with
+  // name 'x'.
+  if (Setter && Setter->isImplicit() && Setter->isPropertyAccessor()
+      && !IFace->FindPropertyDeclaration(Member)) {
+      if (const ObjCPropertyDecl *PDecl = Setter->findPropertyDecl())
+          Diag(MemberLoc,
+               diag::warn_property_access_suggest)
+          << MemberName << QualType(OPT, 0) << PDecl->getName()
+          << FixItHint::CreateReplacement(MemberLoc, PDecl->getName());
+  }
+
   if (Getter || Setter) {
     if (Super)
       return new (Context)
diff --git a/test/FixIt/property-access-fixit.m b/test/FixIt/property-access-fixit.m
new file mode 100644 (file)
index 0000000..8623d29
--- /dev/null
@@ -0,0 +1,31 @@
+// RUN: cp %s %t
+// RUN: %clang_cc1 -x objective-c -fixit %t
+// RUN: %clang_cc1 -x objective-c -Werror %t
+//rdar://17911746
+
+@class BridgeFormatter;
+
+@interface NSObject 
++ (id)new;
+@end
+
+@interface X : NSObject
+@property int x;
+@property int Y;
+@property(assign, readwrite, getter=formatter, setter=setFormatter:) BridgeFormatter* cppFormatter;
+@end
+
+@implementation X
+- (void) endit
+{
+ self.formatter = 0;
+}
+@end
+int main()
+{
+    X *obj = [X new];
+    obj.X = 3;
+    obj.y = 4;
+    return obj.x + obj.Y;
+}
index e84fad2394aba96183919866fbf07a07fb05d891..5d2a3a21e1ac835dc03ed1096acb657f63978a15 100644 (file)
@@ -124,15 +124,16 @@ int main (void) {
 @synthesize t, T;
 @synthesize Pxyz, pxyz;
 - (id) Meth {
-  self.P = 0;
-  self.q = 0;
+  self.P = 0; // expected-warning {{property 'P' not found on object of type 'rdar11363363 *'; did you mean to access property p?}}
+  self.q = 0; // expected-warning {{property 'q' not found on object of type 'rdar11363363 *'; did you mean to access property Q?}}
 // rdar://11528439
   self.t = 0; // expected-error {{synthesized properties 't' and 'T' both claim setter 'setT:'}}
   self.T = 0; // expected-error {{synthesized properties 'T' and 't' both claim setter 'setT:'}}
   self.Pxyz = 0; // expected-error {{synthesized properties 'Pxyz' and 'pxyz' both claim setter 'setPxyz:'}}
   self.pxyz = 0; // expected-error {{synthesized properties 'pxyz' and 'Pxyz' both claim setter 'setPxyz:'}}
-  self.R = 0;
-  return self.R; // expected-error {{no getter method for read from property}}
+  self.r = 0;
+  return self.R; // expected-error {{no getter method for read from property}} \
+                 // expected-warning {{property 'R' not found on object of type 'rdar11363363 *'; did you mean to access property r?}}
 }
 @end
 
@@ -150,7 +151,7 @@ int main (void) {
 
 - (void) dealloc
 {
- self.formatter = 0;
+ self.formatter = 0; // expected-warning {{property 'formatter' not found on object of type 'FMXBridgeFormatter *'; did you mean to access property cppFormatter?}}
 }
 @end