diff options
Diffstat (limited to 'lib')
-rw-r--r-- | lib/Sema/SemaExprObjC.cpp | 11 | ||||
-rw-r--r-- | lib/Sema/SemaPseudoObject.cpp | 24 |
2 files changed, 26 insertions, 9 deletions
diff --git a/lib/Sema/SemaExprObjC.cpp b/lib/Sema/SemaExprObjC.cpp index 52e093c85b..9ce0fafe3c 100644 --- a/lib/Sema/SemaExprObjC.cpp +++ b/lib/Sema/SemaExprObjC.cpp @@ -1415,8 +1415,7 @@ HandleExprPropertyRefExpr(const ObjCObjectPointerType *OPT, return ExprError(); // Search for a declared property first. - ObjCPropertyDecl *PD = IFace->FindPropertyDeclaration(Member); - if (PD) { + if (ObjCPropertyDecl *PD = IFace->FindPropertyDeclaration(Member)) { // Check whether we can reference this property. if (DiagnoseUseOfDecl(PD, MemberLoc)) return ExprError(); @@ -1484,11 +1483,11 @@ HandleExprPropertyRefExpr(const ObjCObjectPointerType *OPT, SelectorTable::constructSetterName(PP.getIdentifierTable(), PP.getSelectorTable(), Member); ObjCMethodDecl *Setter = IFace->lookupInstanceMethod(SetterSel); - // Check for corner case of: @property int p; ... self.P = 0; - // setter name is synthesized "setP" but there is no property name 'P'. - if (Setter && Setter->isSynthesized() && !PD) + if (Setter && Setter->isSynthesized()) + // Check for corner case of: @property int p; ... self.P = 0; + // setter name is synthesized "setP" but there is no property name 'P'. Setter = 0; - + // May be founf in property's qualified list. if (!Setter) Setter = LookupMethodInQualifiedType(SetterSel, OPT, true); diff --git a/lib/Sema/SemaPseudoObject.cpp b/lib/Sema/SemaPseudoObject.cpp index 5e44c9bb8b..82bf79b366 100644 --- a/lib/Sema/SemaPseudoObject.cpp +++ b/lib/Sema/SemaPseudoObject.cpp @@ -34,6 +34,7 @@ #include "clang/Sema/Initialization.h" #include "clang/AST/ExprObjC.h" #include "clang/Lex/Preprocessor.h" +#include "llvm/ADT/SmallString.h" using namespace clang; using namespace sema; @@ -232,7 +233,7 @@ namespace { Expr *op); bool tryBuildGetOfReference(Expr *op, ExprResult &result); - bool findSetter(); + bool findSetter(bool warn=true); bool findGetter(); Expr *rebuildAndCaptureObject(Expr *syntacticBase); @@ -505,7 +506,7 @@ bool ObjCPropertyOpBuilder::findGetter() { /// reference. /// /// \return true if a setter was found, in which case Setter -bool ObjCPropertyOpBuilder::findSetter() { +bool ObjCPropertyOpBuilder::findSetter(bool warn) { // For implicit properties, just trust the lookup we already did. if (RefExpr->isImplicitProperty()) { if (ObjCMethodDecl *setter = RefExpr->getImplicitPropertySetter()) { @@ -531,6 +532,23 @@ bool ObjCPropertyOpBuilder::findSetter() { // Do a normal method lookup first. if (ObjCMethodDecl *setter = LookupMethodInReceiverType(S, SetterSelector, RefExpr)) { + if (setter->isSynthesized() && warn) + if (const ObjCInterfaceDecl *IFace = + dyn_cast<ObjCInterfaceDecl>(setter->getDeclContext())) { + const StringRef thisPropertyName(prop->getName()); + char front = thisPropertyName.front(); + front = islower(front) ? toupper(front) : tolower(front); + SmallString<100> PropertyName = thisPropertyName; + PropertyName[0] = front; + IdentifierInfo *AltMember = &S.PP.getIdentifierTable().get(PropertyName); + if (ObjCPropertyDecl *prop1 = IFace->FindPropertyDeclaration(AltMember)) + if (prop != prop1 && (prop1->getSetterMethodDecl() == setter)) { + S.Diag(RefExpr->getExprLoc(), diag::warn_property_setter_ambiguous_use) + << prop->getName() << prop1->getName() << setter->getSelector(); + S.Diag(prop->getLocation(), diag::note_property_declare); + S.Diag(prop1->getLocation(), diag::note_property_declare); + } + } Setter = setter; return true; } @@ -603,7 +621,7 @@ ExprResult ObjCPropertyOpBuilder::buildGet() { /// value being set as the value of the property operation. ExprResult ObjCPropertyOpBuilder::buildSet(Expr *op, SourceLocation opcLoc, bool captureSetValueAsResult) { - bool hasSetter = findSetter(); + bool hasSetter = findSetter(false); assert(hasSetter); (void) hasSetter; if (SyntacticRefExpr) |