mhjacobson created this revision. mhjacobson added reviewers: rjmccall, ddunbar. Herald added subscribers: Jim, dylanmckay. mhjacobson requested review of this revision. Herald added a project: clang. Herald added a subscriber: cfe-commits.
On targets where `ptrdiff_t` is smaller than `long`, clang crashes (backtrace below) 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. Backtrace: Assertion failed: (castIsValid(op, S, Ty) && "Invalid cast!"), function Create, file /Users/matt/src/llvm/llvm/lib/IR/Instructions.cpp, line 3042. ... 7 libsystem_c.dylib 0x00007fff6ec09ac6 err + 0 8 clang-14 0x000000010acf104c llvm::CastInst::Create(llvm::Instruction::CastOps, llvm::Value*, llvm::Type*, llvm::Twine const&, llvm::Instruction*) + 124 9 clang-14 0x000000010beb140a llvm::IRBuilderBase::CreateCast(llvm::Instruction::CastOps, llvm::Value*, llvm::Type*, llvm::Twine const&) + 234 10 clang-14 0x000000010bebdec2 llvm::IRBuilderBase::CreateZExt(llvm::Value*, llvm::Type*, llvm::Twine const&) + 50 11 clang-14 0x000000010cab50aa clang::CodeGen::CodeGenFunction::EmitCall(clang::CodeGen::CGFunctionInfo const&, clang::CodeGen::CGCallee const&, clang::CodeGen::ReturnValueSlot, clang::CodeGen::CallArgList const&, llvm::CallBase**, bool, clang::SourceLocation) + 8442 12 clang-14 0x000000010ceadeb8 clang::CodeGen::CodeGenFunction::EmitCall(clang::CodeGen::CGFunctionInfo const&, clang::CodeGen::CGCallee const&, clang::CodeGen::ReturnValueSlot, clang::CodeGen::CallArgList const&, llvm::CallBase**, bool) + 216 13 clang-14 0x000000010cc76fe3 clang::CodeGen::CodeGenFunction::generateObjCGetterBody(clang::ObjCImplementationDecl const*, clang::ObjCPropertyImplDecl const*, clang::ObjCMethodDecl const*, llvm::Constant*) + 2595 14 clang-14 0x000000010cc75387 clang::CodeGen::CodeGenFunction::GenerateObjCGetter(clang::ObjCImplementationDecl*, clang::ObjCPropertyImplDecl const*) + 343 15 clang-14 0x000000010cf1c4c0 clang::CodeGen::CodeGenModule::EmitObjCPropertyImplementations(clang::ObjCImplementationDecl const*) + 336 16 clang-14 0x000000010cf17799 clang::CodeGen::CodeGenModule::EmitTopLevelDecl(clang::Decl*) + 2009 17 clang-14 0x000000010d114bf2 (anonymous namespace)::CodeGeneratorImpl::HandleTopLevelDecl(clang::DeclGroupRef) + 146 18 clang-14 0x000000010cec0014 clang::BackendConsumer::HandleTopLevelDecl(clang::DeclGroupRef) + 228 19 clang-14 0x0000000110436425 clang::ParseAST(clang::Sema&, bool, bool) + 533 Repository: rG LLVM Github Monorepo https://reviews.llvm.org/D112049 Files: clang/lib/CodeGen/CGExpr.cpp clang/lib/CodeGen/CGObjC.cpp clang/lib/CodeGen/CodeGenFunction.h clang/test/CodeGen/avr/objc-property.m Index: clang/test/CodeGen/avr/objc-property.m =================================================================== --- /dev/null +++ clang/test/CodeGen/avr/objc-property.m @@ -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 Index: clang/lib/CodeGen/CodeGenFunction.h =================================================================== --- clang/lib/CodeGen/CodeGenFunction.h +++ clang/lib/CodeGen/CodeGenFunction.h @@ -3906,6 +3906,8 @@ 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); Index: clang/lib/CodeGen/CGObjC.cpp =================================================================== --- clang/lib/CodeGen/CGObjC.cpp +++ clang/lib/CodeGen/CGObjC.cpp @@ -1192,7 +1192,7 @@ Builder.CreateLoad(GetAddrOfLocalVar(getterMethod->getCmdDecl()), "cmd"); 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()); @@ -1479,7 +1479,7 @@ 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); Index: clang/lib/CodeGen/CGExpr.cpp =================================================================== --- clang/lib/CodeGen/CGExpr.cpp +++ clang/lib/CodeGen/CGExpr.cpp @@ -5077,6 +5077,15 @@ 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,
Index: clang/test/CodeGen/avr/objc-property.m =================================================================== --- /dev/null +++ clang/test/CodeGen/avr/objc-property.m @@ -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 Index: clang/lib/CodeGen/CodeGenFunction.h =================================================================== --- clang/lib/CodeGen/CodeGenFunction.h +++ clang/lib/CodeGen/CodeGenFunction.h @@ -3906,6 +3906,8 @@ 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); Index: clang/lib/CodeGen/CGObjC.cpp =================================================================== --- clang/lib/CodeGen/CGObjC.cpp +++ clang/lib/CodeGen/CGObjC.cpp @@ -1192,7 +1192,7 @@ Builder.CreateLoad(GetAddrOfLocalVar(getterMethod->getCmdDecl()), "cmd"); 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()); @@ -1479,7 +1479,7 @@ 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); Index: clang/lib/CodeGen/CGExpr.cpp =================================================================== --- clang/lib/CodeGen/CGExpr.cpp +++ clang/lib/CodeGen/CGExpr.cpp @@ -5077,6 +5077,15 @@ 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,
_______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits