================
@@ -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