From bb13c320fff4bc4b3536e62626c97d7b055c6113 Mon Sep 17 00:00:00 2001 From: Fariborz Jahanian Date: Sat, 15 Oct 2011 17:36:49 +0000 Subject: [PATCH] obj-c++: allow the getter/setter to return/take parameters by reference. // rdar://10188258 git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@142075 91177308-0d34-0410-b5e6-96231b3b80d8 --- lib/Sema/SemaExpr.cpp | 6 ++++-- lib/Sema/SemaObjCProperty.cpp | 6 ++++-- test/CodeGenObjCXX/property-object-reference.mm | 12 ++++++++++++ 3 files changed, 20 insertions(+), 4 deletions(-) diff --git a/lib/Sema/SemaExpr.cpp b/lib/Sema/SemaExpr.cpp index 170097cc59..60f84183fa 100644 --- a/lib/Sema/SemaExpr.cpp +++ b/lib/Sema/SemaExpr.cpp @@ -7264,13 +7264,14 @@ void Sema::ConvertPropertyForLValue(ExprResult &LHS, ExprResult &RHS, return; } } - } else if (getLangOptions().ObjCAutoRefCount) { + } else { const ObjCMethodDecl *setter = PropRef->getExplicitProperty()->getSetterMethodDecl(); if (setter) { ObjCMethodDecl::param_const_iterator P = setter->param_begin(); LHSTy = (*P)->getType(); - Consumed = (*P)->hasAttr(); + if (getLangOptions().ObjCAutoRefCount) + Consumed = (*P)->hasAttr(); } } @@ -7285,6 +7286,7 @@ void Sema::ConvertPropertyForLValue(ExprResult &LHS, ExprResult &RHS, checkRetainCycles(const_cast(PropRef->getBase()), RHS.get()); } } + LHSTy = LHSTy.getNonReferenceType(); } diff --git a/lib/Sema/SemaObjCProperty.cpp b/lib/Sema/SemaObjCProperty.cpp index 751f553945..d35c01039c 100644 --- a/lib/Sema/SemaObjCProperty.cpp +++ b/lib/Sema/SemaObjCProperty.cpp @@ -948,7 +948,8 @@ bool Sema::DiagnosePropertyAccessorMismatch(ObjCPropertyDecl *property, ObjCMethodDecl *GetterMethod, SourceLocation Loc) { if (GetterMethod && - GetterMethod->getResultType() != property->getType()) { + GetterMethod->getResultType().getNonReferenceType() + != property->getType().getNonReferenceType()) { AssignConvertType result = Incompatible; if (property->getType()->isObjCObjectPointerType()) result = CheckAssignmentConstraints(Loc, GetterMethod->getResultType(), @@ -1510,7 +1511,8 @@ void Sema::ProcessPropertyDecl(ObjCPropertyDecl *property, Diag(SetterMethod->getLocation(), diag::err_setter_type_void); if (SetterMethod->param_size() != 1 || !Context.hasSameUnqualifiedType( - (*SetterMethod->param_begin())->getType(), property->getType())) { + (*SetterMethod->param_begin())->getType().getNonReferenceType(), + property->getType().getNonReferenceType())) { Diag(property->getLocation(), diag::warn_accessor_property_type_mismatch) << property->getDeclName() diff --git a/test/CodeGenObjCXX/property-object-reference.mm b/test/CodeGenObjCXX/property-object-reference.mm index b87ce2303b..0bd8fb8b9f 100644 --- a/test/CodeGenObjCXX/property-object-reference.mm +++ b/test/CodeGenObjCXX/property-object-reference.mm @@ -2,9 +2,14 @@ // rdar://10188258 struct Foo {int i;}; +static Foo gFoo; + @interface ObjCTest { } @property (nonatomic, readonly) Foo& FooRefProperty; +@property (nonatomic) Foo FooProperty; +- (Foo &) FooProperty; +- (void)setFooProperty : (Foo &) arg; @end @@ -13,11 +18,18 @@ struct Foo {int i;}; -(void) test { Foo& f = self.FooRefProperty; + Foo& f1 = self.FooProperty; } +- (Foo &) FooProperty { return gFoo; } +- (void)setFooProperty : (Foo &) arg { }; @end // CHECK: [[T0:%.*]] = load {{%.*}} [[S0:%.*]] // CHECK: load i8** @"\01L_OBJC_SELECTOR_REFERENCES_ // CHECK: [[T2:%.*]] = bitcast {{%.*}} [[T0]] to i8* // CHECK: @objc_msgSend +// CHECK: [[R0:%.*]] = load {{%.*}} [[U0:%.*]] +// CHECK: load i8** @"\01L_OBJC_SELECTOR_REFERENCES_ +// CHECK: [[R2:%.*]] = bitcast {{%.*}} [[R0]] to i8* +// CHECK: @objc_msgSend -- 2.40.0