diff --git a/clang/lib/CodeGen/CGObjC.cpp b/clang/lib/CodeGen/CGObjC.cpp index 7c842a94986c..95be0dd1204b 100644 --- a/clang/lib/CodeGen/CGObjC.cpp +++ b/clang/lib/CodeGen/CGObjC.cpp @@ -595,7 +595,8 @@ void CodeGenFunction::EmitObjCPropertySet(const Expr *Exp, Args); } else if (const ObjCImplicitSetterGetterRefExpr *E = dyn_cast(Exp)) { - Selector S = E->getSetterMethod()->getSelector(); + const ObjCMethodDecl *SetterMD = E->getSetterMethod(); + Selector S = SetterMD->getSelector(); CallArgList Args; llvm::Value *Receiver; if (E->getInterfaceDecl()) { @@ -606,7 +607,8 @@ void CodeGenFunction::EmitObjCPropertySet(const Expr *Exp, return; } else Receiver = EmitScalarExpr(E->getBase()); - Args.push_back(std::make_pair(Src, E->getType())); + ObjCMethodDecl::param_iterator P = SetterMD->param_begin(); + Args.push_back(std::make_pair(Src, (*P)->getType())); CGM.getObjCRuntime().GenerateMessageSend(*this, ReturnValueSlot(), getContext().VoidTy, S, Receiver, diff --git a/clang/lib/Sema/SemaExpr.cpp b/clang/lib/Sema/SemaExpr.cpp index 7152f04b8878..3473ef00902a 100644 --- a/clang/lib/Sema/SemaExpr.cpp +++ b/clang/lib/Sema/SemaExpr.cpp @@ -5796,11 +5796,22 @@ QualType Sema::CheckAssignmentOperands(Expr *LHS, Expr *&RHS, QualType LHSType = LHS->getType(); QualType RHSType = CompoundType.isNull() ? RHS->getType() : CompoundType; - AssignConvertType ConvTy; if (CompoundType.isNull()) { + QualType LHSTy(LHSType); // Simple assignment "x = y". - ConvTy = CheckSingleAssignmentConstraints(LHSType, RHS); + if (const ObjCImplicitSetterGetterRefExpr *OISGE = + dyn_cast(LHS)) { + // If using property-dot syntax notation for assignment, and there is a + // setter, RHS expression is being passed to the setter argument. So, + // type conversion (and comparison) is RHS to setter's argument type. + if (const ObjCMethodDecl *SetterMD = OISGE->getSetterMethod()) { + ObjCMethodDecl::param_iterator P = SetterMD->param_begin(); + LHSTy = (*P)->getType(); + } + } + + ConvTy = CheckSingleAssignmentConstraints(LHSTy, RHS); // Special case of NSObject attributes on c-style pointer types. if (ConvTy == IncompatiblePointer && ((Context.isObjCNSObjectType(LHSType) && diff --git a/clang/test/CodeGenObjC/dot-syntax-2.m b/clang/test/CodeGenObjC/dot-syntax-2.m new file mode 100644 index 000000000000..020868a80712 --- /dev/null +++ b/clang/test/CodeGenObjC/dot-syntax-2.m @@ -0,0 +1,27 @@ +// RUN: %clang_cc1 -emit-llvm -o %t %s +// rdar: // 8062778 + +@interface NSDictionary @end + +@interface NSMutableDictionary : NSDictionary +@end + +@interface MutableMyClass +- (NSMutableDictionary *)myDict; +- (void)setMyDict:(NSDictionary *)myDict; + +- (NSMutableDictionary *)myLang; +- (void)setMyLang:(NSDictionary *)myLang; +@end + +@interface AnotherClass @end + +@implementation AnotherClass +- (void)foo +{ + MutableMyClass * myObject; + NSDictionary * newDict; + myObject.myDict = newDict; + myObject.myLang = newDict; +} +@end