From 0b1d28866c369422c7be0c817ea9b9b7e0cfa12c Mon Sep 17 00:00:00 2001 From: Fariborz Jahanian Date: Fri, 8 Aug 2014 22:33:24 +0000 Subject: [PATCH] Objective-C [qoi]. Issue warning and fixit if property-dot syntax use mis-cased property name (which is currently accepted silently due to the way property setters are named). rdar://17911746 llvm-svn: 215250 --- clang/include/clang/Basic/DiagnosticGroups.td | 1 + .../clang/Basic/DiagnosticSemaKinds.td | 3 ++ clang/lib/Sema/SemaExprObjC.cpp | 12 +++++++ clang/test/FixIt/property-access-fixit.m | 31 +++++++++++++++++++ clang/test/SemaObjC/property-user-setter.m | 11 ++++--- 5 files changed, 53 insertions(+), 5 deletions(-) create mode 100644 clang/test/FixIt/property-access-fixit.m diff --git a/clang/include/clang/Basic/DiagnosticGroups.td b/clang/include/clang/Basic/DiagnosticGroups.td index 8beff3eeb603..c737270cae3f 100644 --- a/clang/include/clang/Basic/DiagnosticGroups.td +++ b/clang/include/clang/Basic/DiagnosticGroups.td @@ -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">; diff --git a/clang/include/clang/Basic/DiagnosticSemaKinds.td b/clang/include/clang/Basic/DiagnosticSemaKinds.td index 800e591b4462..624555c8076f 100644 --- a/clang/include/clang/Basic/DiagnosticSemaKinds.td +++ b/clang/include/clang/Basic/DiagnosticSemaKinds.td @@ -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; def err_property_found_suggest : Error< "property %0 found on object of type %1; did you mean to access " "it with the \".\" operator?">; diff --git a/clang/lib/Sema/SemaExprObjC.cpp b/clang/lib/Sema/SemaExprObjC.cpp index bed9c2f16d44..8ec2c177f721 100644 --- a/clang/lib/Sema/SemaExprObjC.cpp +++ b/clang/lib/Sema/SemaExprObjC.cpp @@ -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/clang/test/FixIt/property-access-fixit.m b/clang/test/FixIt/property-access-fixit.m new file mode 100644 index 000000000000..8623d29b9629 --- /dev/null +++ b/clang/test/FixIt/property-access-fixit.m @@ -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; +} diff --git a/clang/test/SemaObjC/property-user-setter.m b/clang/test/SemaObjC/property-user-setter.m index e84fad2394ab..5d2a3a21e1ac 100644 --- a/clang/test/SemaObjC/property-user-setter.m +++ b/clang/test/SemaObjC/property-user-setter.m @@ -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