From: Matt Jacobson Date: Mon, 1 Aug 2022 05:59:41 +0000 (-0400) Subject: [ObjC] type method metadata `_imp`, messenger routine at callsite with program addres... X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=c8b2f3f51bd923afbf9d3ebd0823bce895629630;p=platform%2Fupstream%2Fllvm.git [ObjC] type method metadata `_imp`, messenger routine at callsite with program address space On targets with non-default program address space (e.g., Harvard architectures), clang crashes when emitting Objective-C method metadata, because the address of the method IMP cannot be bitcast to i8*. It similarly crashes at messenger callsite with a failed bitcast. Define the _imp field instead as i8 addrspace(1)* (or whatever the target's program address space is). And in getMessageSendInfo(), create signatureType by specifying the program address space. Add a regression test using the AVR target. Test failed previously and passes now. Checked codegen of the test for x86_64-apple-darwin19.6.0 and saw no difference, as expected. Reviewed By: rjmccall, dylanmckay Differential Revision: https://reviews.llvm.org/D112113 --- diff --git a/clang/lib/CodeGen/CGObjCMac.cpp b/clang/lib/CodeGen/CGObjCMac.cpp index 46e65eb..2d704ce 100644 --- a/clang/lib/CodeGen/CGObjCMac.cpp +++ b/clang/lib/CodeGen/CGObjCMac.cpp @@ -174,6 +174,7 @@ protected: public: llvm::IntegerType *ShortTy, *IntTy, *LongTy; llvm::PointerType *Int8PtrTy, *Int8PtrPtrTy; + llvm::PointerType *Int8PtrProgramASTy; llvm::Type *IvarOffsetVarTy; /// ObjectPtrTy - LLVM type for object handles (typeof(id)) @@ -5739,11 +5740,13 @@ ObjCCommonTypesHelper::ObjCCommonTypesHelper(CodeGen::CodeGenModule &cgm) { CodeGen::CodeGenTypes &Types = CGM.getTypes(); ASTContext &Ctx = CGM.getContext(); + unsigned ProgramAS = CGM.getDataLayout().getProgramAddressSpace(); ShortTy = cast(Types.ConvertType(Ctx.ShortTy)); IntTy = CGM.IntTy; LongTy = cast(Types.ConvertType(Ctx.LongTy)); Int8PtrTy = CGM.Int8PtrTy; + Int8PtrProgramASTy = llvm::PointerType::get(CGM.Int8Ty, ProgramAS); Int8PtrPtrTy = CGM.Int8PtrPtrTy; // arm64 targets use "int" ivar offset variables. All others, @@ -5812,7 +5815,7 @@ ObjCCommonTypesHelper::ObjCCommonTypesHelper(CodeGen::CodeGenModule &cgm) // char *_imp; // } MethodTy = llvm::StructType::create("struct._objc_method", SelectorPtrTy, - Int8PtrTy, Int8PtrTy); + Int8PtrTy, Int8PtrProgramASTy); // struct _objc_cache * CacheTy = llvm::StructType::create(VMContext, "struct._objc_cache"); @@ -6771,11 +6774,11 @@ void CGObjCNonFragileABIMac::emitMethodConstant(ConstantArrayBuilder &builder, if (forProtocol) { // Protocol methods have no implementation. So, this entry is always NULL. - method.addNullPointer(ObjCTypes.Int8PtrTy); + method.addNullPointer(ObjCTypes.Int8PtrProgramASTy); } else { llvm::Function *fn = GetMethodDefinition(MD); assert(fn && "no definition for method?"); - method.addBitCast(fn, ObjCTypes.Int8PtrTy); + method.addBitCast(fn, ObjCTypes.Int8PtrProgramASTy); } method.finishAndAddTo(builder); diff --git a/clang/lib/CodeGen/CGObjCRuntime.cpp b/clang/lib/CodeGen/CGObjCRuntime.cpp index 550fd3d..7780a61 100644 --- a/clang/lib/CodeGen/CGObjCRuntime.cpp +++ b/clang/lib/CodeGen/CGObjCRuntime.cpp @@ -360,13 +360,15 @@ CGObjCRuntime::MessageSendInfo CGObjCRuntime::getMessageSendInfo(const ObjCMethodDecl *method, QualType resultType, CallArgList &callArgs) { + unsigned ProgramAS = CGM.getDataLayout().getProgramAddressSpace(); + // If there's a method, use information from that. if (method) { const CGFunctionInfo &signature = CGM.getTypes().arrangeObjCMessageSendSignature(method, callArgs[0].Ty); llvm::PointerType *signatureType = - CGM.getTypes().GetFunctionType(signature)->getPointerTo(); + CGM.getTypes().GetFunctionType(signature)->getPointerTo(ProgramAS); const CGFunctionInfo &signatureForCall = CGM.getTypes().arrangeCall(signature, callArgs); @@ -380,7 +382,7 @@ CGObjCRuntime::getMessageSendInfo(const ObjCMethodDecl *method, // Derive the signature to call from that. llvm::PointerType *signatureType = - CGM.getTypes().GetFunctionType(argsInfo)->getPointerTo(); + CGM.getTypes().GetFunctionType(argsInfo)->getPointerTo(ProgramAS); return MessageSendInfo(argsInfo, signatureType); } diff --git a/clang/test/CodeGen/avr/objc-method.m b/clang/test/CodeGen/avr/objc-method.m new file mode 100644 index 0000000..aeafb8e --- /dev/null +++ b/clang/test/CodeGen/avr/objc-method.m @@ -0,0 +1,21 @@ +// RUN: %clang_cc1 -triple avr -emit-llvm -fobjc-runtime=macosx %s -o /dev/null + +__attribute__((objc_root_class)) +@interface Foo + +- (id)foo; +- (id)bar; + +@end + +@implementation Foo + +- (id)foo { + return self; +} + +- (id)bar { + return [self foo]; +} + +@end