[PATCH] D112049: [ObjC] avoid crashing when emitting synthesized getter/setter and ptrdiff_t is smaller than long

Matt Jacobson via Phabricator via cfe-commits cfe-commits at lists.llvm.org
Mon Oct 18 19:28:14 PDT 2021


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))
+ at interface Foo
+
+ at property(strong) Foo *f;
+
+ at end
+
+ at implementation Foo
+
+ at synthesize f = _f;
+
+ at 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,


-------------- next part --------------
A non-text attachment was scrubbed...
Name: D112049.380570.patch
Type: text/x-patch
Size: 2989 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/cfe-commits/attachments/20211019/d543bf1f/attachment.bin>


More information about the cfe-commits mailing list