static TryEmitResult
tryEmitARCRetainScalarExpr(CodeGenFunction &CGF, const Expr *e);
static RValue AdjustRelatedResultType(CodeGenFunction &CGF,
- const Expr *E,
+ QualType ET,
const ObjCMethodDecl *Method,
RValue Result);
/// \brief Adjust the type of the result of an Objective-C message send
/// expression when the method has a related result type.
static RValue AdjustRelatedResultType(CodeGenFunction &CGF,
- const Expr *E,
+ QualType ExpT,
const ObjCMethodDecl *Method,
RValue Result) {
if (!Method)
return Result;
if (!Method->hasRelatedResultType() ||
- CGF.getContext().hasSameType(E->getType(), Method->getResultType()) ||
+ CGF.getContext().hasSameType(ExpT, Method->getResultType()) ||
!Result.isScalar())
return Result;
// We have applied a related result type. Cast the rvalue appropriately.
return RValue::get(CGF.Builder.CreateBitCast(Result.getScalarVal(),
- CGF.ConvertType(E->getType())));
+ CGF.ConvertType(ExpT)));
}
/// Decide whether to extend the lifetime of the receiver of a
Builder.CreateStore(newSelf, selfAddr);
}
- return AdjustRelatedResultType(*this, E, method, result);
+ return AdjustRelatedResultType(*this, E->getType(), method, result);
}
namespace {
assert(OMD && "Invalid call to generate getter (empty method)");
StartObjCMethod(OMD, IMP->getClassInterface(), OMD->getLocStart());
- generateObjCGetterBody(IMP, PID, AtomicHelperFn);
+ generateObjCGetterBody(IMP, PID, OMD, AtomicHelperFn);
FinishFunction();
}
void
CodeGenFunction::generateObjCGetterBody(const ObjCImplementationDecl *classImpl,
const ObjCPropertyImplDecl *propImpl,
+ const ObjCMethodDecl *GetterMethodDecl,
llvm::Constant *AtomicHelperFn) {
// If there's a non-trivial 'get' expression, we just have to emit that.
if (!hasTrivialGetExpr(propImpl)) {
}
value = Builder.CreateBitCast(value, ConvertType(propType));
+ value = Builder.CreateBitCast(value,
+ ConvertType(GetterMethodDecl->getResultType()));
}
EmitReturnOfRValue(RValue::get(value), propType);
isa<ObjCObjectPointerType>(GetterType))
compat =
Context.canAssignObjCInterfaces(
- PropertyIvarType->getAs<ObjCObjectPointerType>(),
- GetterType->getAs<ObjCObjectPointerType>());
- else if (CheckAssignmentConstraints(Loc, PropertyIvarType, GetterType)
+ GetterType->getAs<ObjCObjectPointerType>(),
+ PropertyIvarType->getAs<ObjCObjectPointerType>());
+ else if (CheckAssignmentConstraints(Loc, GetterType, PropertyIvarType)
!= Compatible) {
Diag(Loc, diag::error_property_accessor_type)
<< property->getDeclName() << PropertyIvarType
--- /dev/null
+// RUN: %clang_cc1 -triple x86_64-apple-darwin10 -emit-llvm -o - %s | FileCheck %s
+// rdar://11515196
+
+@interface NSArray @end
+
+@interface NSMutableArray : NSArray
+- (void) addObject;
+@end
+
+@interface BPXLAppDelegate
+
+- (NSArray *)arrayOfThings;
+
+@end
+
+
+@interface BPXLAppDelegate ()
+@property (retain, nonatomic) NSMutableArray *arrayOfThings;
+@end
+
+@implementation BPXLAppDelegate
+
+@synthesize arrayOfThings=_arrayOfThings;
+
+- (void)applicationDidFinishLaunching
+{
+ [self.arrayOfThings addObject];
+}
+
+@end
+
+// CHECK: define internal [[RET:%.*]]* @"\01-[BPXLAppDelegate arrayOfThings
+// CHECK: [[THREE:%.*]] = bitcast [[OPQ:%.*]]* [[TWO:%.*]] to [[RET]]*
+// CHECK: ret [[RET]]* [[THREE]]
+
NSArray* first;
}
-@property (readonly) NSArray* pieces;
-@property (readonly) NSMutableArray* first; // expected-warning {{type of property 'first' does not match type of accessor 'first'}}
+@property (readonly) NSArray* pieces; // expected-warning {{type of property 'pieces' does not match type of accessor 'pieces'}}
+@property (readonly) NSMutableArray* first;
-- (NSMutableArray*) pieces;
-- (NSArray*) first; // expected-note 2 {{declared here}}
+- (NSMutableArray*) pieces; // expected-note 2 {{declared here}}
+- (NSArray*) first;
@end
@interface Class2 {
- (id) lastPiece
{
- return container.pieces;
+ return container.pieces; // expected-warning {{type of property 'pieces' does not match type of accessor 'pieces'}}
}
- (id)firstPeice
{
- return container.first; // expected-warning {{type of property 'first' does not match type of accessor 'first'}}
+ return container.first;
}
@end