aboutsummaryrefslogtreecommitdiff
path: root/lib/Sema/SemaPseudoObject.cpp
diff options
context:
space:
mode:
authorFariborz Jahanian <fjahanian@apple.com>2012-05-24 22:48:38 +0000
committerFariborz Jahanian <fjahanian@apple.com>2012-05-24 22:48:38 +0000
commitb5b155cb8bd2460693572bab5ce14dabf1a27d2f (patch)
treebb9fcc86d175dea0923877b3606a6ab15a616069 /lib/Sema/SemaPseudoObject.cpp
parent0218068cbbb2e98164431653d76587e5b8bb9c38 (diff)
objective-c: warn on use of property setters
backing two propeties because proprty names match except for first letter being of different case. // rdar://11528439, [PR12936]. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@157435 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/Sema/SemaPseudoObject.cpp')
-rw-r--r--lib/Sema/SemaPseudoObject.cpp24
1 files changed, 21 insertions, 3 deletions
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)