forked from OSchip/llvm-project
[ObjC] avoid crashing when emitting synthesized getter/setter and ptrdiff_t is smaller than long
On targets where ptrdiff_t is smaller than long, clang crashes when emitting synthesized getters/setters that call objc_[gs]etProperty. Explicitly emit a zext/trunc of the ivar offset value (which is defined to long) to ptrdiff_t, which objc_[gs]etProperty takes. Add a test using the AVR target, where ptrdiff_t is smaller than long. Test failed previously and passes now. Differential Revision: https://reviews.llvm.org/D112049
This commit is contained in:
parent
18df04c944
commit
dd9f7963e4
|
@ -5242,6 +5242,15 @@ llvm::Value *CodeGenFunction::EmitIvarOffset(const ObjCInterfaceDecl *Interface,
|
|||
return CGM.getObjCRuntime().EmitIvarOffset(*this, Interface, Ivar);
|
||||
}
|
||||
|
||||
llvm::Value *
|
||||
CodeGenFunction::EmitIvarOffsetAsPointerDiff(const ObjCInterfaceDecl *Interface,
|
||||
const ObjCIvarDecl *Ivar) {
|
||||
llvm::Value *OffsetValue = EmitIvarOffset(Interface, Ivar);
|
||||
QualType PointerDiffType = getContext().getPointerDiffType();
|
||||
return Builder.CreateZExtOrTrunc(OffsetValue,
|
||||
getTypes().ConvertType(PointerDiffType));
|
||||
}
|
||||
|
||||
LValue CodeGenFunction::EmitLValueForIvar(QualType ObjectTy,
|
||||
llvm::Value *BaseValue,
|
||||
const ObjCIvarDecl *Ivar,
|
||||
|
|
|
@ -1228,7 +1228,7 @@ CodeGenFunction::generateObjCGetterBody(const ObjCImplementationDecl *classImpl,
|
|||
llvm::Value *cmd = emitCmdValueForGetterSetterBody(*this, getterMethod);
|
||||
llvm::Value *self = Builder.CreateBitCast(LoadObjCSelf(), VoidPtrTy);
|
||||
llvm::Value *ivarOffset =
|
||||
EmitIvarOffset(classImpl->getClassInterface(), ivar);
|
||||
EmitIvarOffsetAsPointerDiff(classImpl->getClassInterface(), ivar);
|
||||
|
||||
CallArgList args;
|
||||
args.add(RValue::get(self), getContext().getObjCIdType());
|
||||
|
@ -1532,7 +1532,7 @@ CodeGenFunction::generateObjCSetterBody(const ObjCImplementationDecl *classImpl,
|
|||
llvm::Value *self =
|
||||
Builder.CreateBitCast(LoadObjCSelf(), VoidPtrTy);
|
||||
llvm::Value *ivarOffset =
|
||||
EmitIvarOffset(classImpl->getClassInterface(), ivar);
|
||||
EmitIvarOffsetAsPointerDiff(classImpl->getClassInterface(), ivar);
|
||||
Address argAddr = GetAddrOfLocalVar(*setterMethod->param_begin());
|
||||
llvm::Value *arg = Builder.CreateLoad(argAddr, "arg");
|
||||
arg = Builder.CreateBitCast(arg, VoidPtrTy);
|
||||
|
|
|
@ -3974,6 +3974,8 @@ public:
|
|||
|
||||
llvm::Value *EmitIvarOffset(const ObjCInterfaceDecl *Interface,
|
||||
const ObjCIvarDecl *Ivar);
|
||||
llvm::Value *EmitIvarOffsetAsPointerDiff(const ObjCInterfaceDecl *Interface,
|
||||
const ObjCIvarDecl *Ivar);
|
||||
LValue EmitLValueForField(LValue Base, const FieldDecl* Field);
|
||||
LValue EmitLValueForLambdaField(const FieldDecl *Field);
|
||||
|
||||
|
|
|
@ -0,0 +1,14 @@
|
|||
// RUN: %clang_cc1 -triple avr -emit-llvm -fobjc-runtime=macosx %s -o /dev/null
|
||||
|
||||
__attribute__((objc_root_class))
|
||||
@interface Foo
|
||||
|
||||
@property(strong) Foo *f;
|
||||
|
||||
@end
|
||||
|
||||
@implementation Foo
|
||||
|
||||
@synthesize f = _f;
|
||||
|
||||
@end
|
Loading…
Reference in New Issue