[PATCH] D124762: [WinEHPrepare] Avoid truncation of EH funclets with GNUstep ObjC runtime

Stefan Gränitz via Phabricator via cfe-commits cfe-commits at lists.llvm.org
Fri Jun 3 07:26:32 PDT 2022


sgraenitz updated this revision to Diff 434020.
sgraenitz added a comment.

Fix unchecked nullptr compiler crash and assertion


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D124762/new/

https://reviews.llvm.org/D124762

Files:
  clang/lib/CodeGen/CGCall.cpp
  llvm/lib/CodeGen/PreISelIntrinsicLowering.cpp
  llvm/lib/CodeGen/WinEHPrepare.cpp


Index: llvm/lib/CodeGen/WinEHPrepare.cpp
===================================================================
--- llvm/lib/CodeGen/WinEHPrepare.cpp
+++ llvm/lib/CodeGen/WinEHPrepare.cpp
@@ -963,7 +963,7 @@
         if (auto BU = CB->getOperandBundle(LLVMContext::OB_funclet))
           FuncletBundleOperand = BU->Inputs.front();
 
-        if (FuncletBundleOperand == FuncletPad)
+        if (!FuncletPad || FuncletBundleOperand == FuncletPad)
           continue;
 
         // Skip call sites which are nounwind intrinsics or inline asm.
Index: llvm/lib/CodeGen/PreISelIntrinsicLowering.cpp
===================================================================
--- llvm/lib/CodeGen/PreISelIntrinsicLowering.cpp
+++ llvm/lib/CodeGen/PreISelIntrinsicLowering.cpp
@@ -107,7 +107,9 @@
 
     IRBuilder<> Builder(CI->getParent(), CI->getIterator());
     SmallVector<Value *, 8> Args(CI->args());
-    CallInst *NewCI = Builder.CreateCall(FCache, Args);
+    SmallVector<llvm::OperandBundleDef, 1> BundleList;
+    CI->getOperandBundlesAsDefs(BundleList);
+    CallInst *NewCI = Builder.CreateCall(FCache, Args, BundleList);
     NewCI->setName(CI->getName());
 
     // Try to set the most appropriate TailCallKind based on both the current
Index: clang/lib/CodeGen/CGCall.cpp
===================================================================
--- clang/lib/CodeGen/CGCall.cpp
+++ clang/lib/CodeGen/CGCall.cpp
@@ -25,11 +25,13 @@
 #include "clang/AST/DeclCXX.h"
 #include "clang/AST/DeclObjC.h"
 #include "clang/Basic/CodeGenOptions.h"
+#include "clang/Basic/ObjCRuntime.h"
 #include "clang/Basic/TargetBuiltins.h"
 #include "clang/Basic/TargetInfo.h"
 #include "clang/CodeGen/CGFunctionInfo.h"
 #include "clang/CodeGen/SwiftCallingConv.h"
 #include "llvm/ADT/StringExtras.h"
+#include "llvm/Analysis/ObjCARCInstKind.h"
 #include "llvm/Analysis/ValueTracking.h"
 #include "llvm/IR/Assumptions.h"
 #include "llvm/IR/Attributes.h"
@@ -4465,16 +4467,37 @@
 CodeGenFunction::getBundlesForFunclet(llvm::Value *Callee) {
   SmallVector<llvm::OperandBundleDef, 1> BundleList;
   // There is no need for a funclet operand bundle if we aren't inside a
-  // funclet.
+  // funclet or the callee is not a function.
   if (!CurrentFuncletPad)
     return BundleList;
-
-  // Skip intrinsics which cannot throw.
   auto *CalleeFn = dyn_cast<llvm::Function>(Callee->stripPointerCasts());
-  if (CalleeFn && CalleeFn->isIntrinsic() && CalleeFn->doesNotThrow())
+  if (!CalleeFn)
     return BundleList;
 
-  BundleList.emplace_back("funclet", CurrentFuncletPad);
+  // Skip intrinsics which cannot throw.
+  bool InsertFuncletOp = true;
+  if (CalleeFn->isIntrinsic() && CalleeFn->doesNotThrow())
+    InsertFuncletOp = false;
+
+  // Most ObjC ARC intrinics are lowered in PreISelIntrinsicLowering. Thus,
+  // WinEHPrepare will see them as regular calls. We need to set the funclet
+  // operand explicitly in this case to avoid accidental truncation of EH
+  // funclets on Windows.
+  if (CalleeFn->isIntrinsic() && CalleeFn->doesNotThrow()) {
+    if (CGM.getTarget().getTriple().isOSWindows()) {
+      assert(CGM.getLangOpts().ObjCRuntime.getKind() == ObjCRuntime::GNUstep &&
+             "Only reproduced with GNUstep so far, but likely applies to other "
+             "ObjC runtimes on Windows");
+      using namespace llvm::objcarc;
+      ARCInstKind CalleeKind = GetFunctionClass(CalleeFn);
+      if (!IsUser(CalleeKind) && CalleeKind != ARCInstKind::None)
+        InsertFuncletOp = true;
+    }
+  }
+
+  if (InsertFuncletOp)
+    BundleList.emplace_back("funclet", CurrentFuncletPad);
+
   return BundleList;
 }
 


-------------- next part --------------
A non-text attachment was scrubbed...
Name: D124762.434020.patch
Type: text/x-patch
Size: 3616 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/cfe-commits/attachments/20220603/9f2be838/attachment-0001.bin>


More information about the cfe-commits mailing list