================
@@ -1435,6 +1436,73 @@ static bool 
CanSkipVTablePointerInitialization(CodeGenFunction &CGF,
   return true;
 }
 
+/// Get or create the MSVC-compatible __global_delete wrapper function.
+///
+/// MSVC's scalar/vector deleting destructors call __global_delete (a weak
+/// external) instead of calling ::operator delete directly. This allows
+/// environments without a global ::operator delete (e.g., kernel mode) to
+/// gracefully fall back to a no-op __empty_global_delete.
+static llvm::Constant *
+getOrCreateMSVCGlobalDeleteWrapper(CodeGenModule &CGM,
+                                   const FunctionDecl *GlobOD) {
+  assert(CGM.getTarget().getCXXABI().isMicrosoft() &&
+         "__global_delete wrapper is only used with the Microsoft ABI");
+  llvm::Module &M = CGM.getModule();
+  llvm::LLVMContext &LLVMCtx = M.getContext();
+
+  llvm::Constant *GlobDeleteCallee = CGM.GetAddrOfFunction(GlobOD);
+  auto *GlobDeleteFn = cast<llvm::Function>(GlobDeleteCallee);
+  llvm::FunctionType *FnTy = GlobDeleteFn->getFunctionType();
+
+  // Derive __global_delete and __empty_global_delete mangled names.
+  // Global ::operator delete mangling:   ??3@<signature>
+  // Global ::operator delete[] mangling: ??_V@<signature>
+  // We construct:
+  //   ?__global_delete@@<signature>
+  //   ?__empty_global_delete@@<signature>
+  StringRef GlobDeleteMangledName = GlobDeleteFn->getName();
+  StringRef Signature;
+  if (GlobDeleteMangledName.starts_with("??3@"))
+    Signature = GlobDeleteMangledName.substr(4);
+  else if (GlobDeleteMangledName.starts_with("??_V@"))
+    Signature = GlobDeleteMangledName.substr(5);
+  else
+    llvm_unreachable("unexpected global operator delete mangling");
+
+  std::string GlobalDeleteName = ("?__global_delete@@" + Signature).str();
+  std::string EmptyGlobalDeleteName =
+      ("?__empty_global_delete@@" + Signature).str();
+
+  // Only set up the wrapper once per module.
+  if (llvm::Function *Existing = M.getFunction(GlobalDeleteName))
+    return Existing;
+
+  // Create __empty_global_delete fallback.
+  llvm::Function *EmptyFn = llvm::Function::Create(
+      FnTy, llvm::GlobalValue::LinkOnceODRLinkage, EmptyGlobalDeleteName, &M);
+  EmptyFn->setComdat(M.getOrInsertComdat(EmptyGlobalDeleteName));
+  EmptyFn->setUnnamedAddr(llvm::GlobalValue::UnnamedAddr::Global);
+  CGM.SetLLVMFunctionAttributesForDefinition(GlobOD, EmptyFn);
+  auto *BB = llvm::BasicBlock::Create(LLVMCtx, "", EmptyFn);
+  llvm::ReturnInst::Create(LLVMCtx, BB);
----------------
dpaoliello wrote:

Your intuition here is correct: MSVC emits the definition for `__global_delete` 
if there are any calls to global `::operator delete`, therefore 
`__empty_global_delete` should never be called. I've switched it to trap 
instead of being a no-op.

https://github.com/llvm/llvm-project/pull/188372
_______________________________________________
cfe-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to