[llvm-branch-commits] [clang] release/23.x: [clang][win] Fix __global_delete breaking __attribute__((used)) (#217753) (PR #218040)

via llvm-branch-commits llvm-branch-commits at lists.llvm.org
Fri Aug 21 14:59:46 PDT 2026


llvmorg-github-actions[bot] wrote:


<!--LLVM PR SUMMARY COMMENT-->

@llvm/pr-subscribers-clang-codegen

Author: llvmbot

<details>
<summary>Changes</summary>

Backport 061865f32607cd064ab944407cc863186702d6f1

Requested by: @<!-- -->dpaoliello

---
Full diff: https://github.com/llvm/llvm-project/pull/218040.diff


2 Files Affected:

- (modified) clang/lib/CodeGen/CodeGenModule.cpp (+1-1) 
- (added) clang/test/CodeGenCXX/msvc-global-delete-llvm-used.cpp (+17) 


``````````diff
diff --git a/clang/lib/CodeGen/CodeGenModule.cpp b/clang/lib/CodeGen/CodeGenModule.cpp
index de060e31b8800..313a364e80aff 100644
--- a/clang/lib/CodeGen/CodeGenModule.cpp
+++ b/clang/lib/CodeGen/CodeGenModule.cpp
@@ -9026,7 +9026,7 @@ CodeGenModule::getOrCreateMSVCGlobalDeleteWrapper(const FunctionDecl *GlobOD) {
     // uses ::delete that alias is replaced by a real forwarding body, leaving
     // the empty otherwise unreferenced, so explicitly mark it used to ensure
     // it is always emitted (matching MSVC).
-    appendToUsed(M, {EmptyFn});
+    addUsedGlobal(EmptyFn);
   }
 
   // The wrapper defaults to a weak alias to the trapping __empty_global_delete
diff --git a/clang/test/CodeGenCXX/msvc-global-delete-llvm-used.cpp b/clang/test/CodeGenCXX/msvc-global-delete-llvm-used.cpp
new file mode 100644
index 0000000000000..07811b0f8eecc
--- /dev/null
+++ b/clang/test/CodeGenCXX/msvc-global-delete-llvm-used.cpp
@@ -0,0 +1,17 @@
+// RUN: %clang_cc1 -emit-llvm -fms-extensions %s -triple=x86_64-pc-windows-msvc -o - \
+// RUN:   | FileCheck %s --implicit-check-not="@llvm.used.1"
+
+// The __empty_global_delete fallback is marked used so it is always emitted.
+// It must join the single llvm.used that CodeGenModule emits at end-of-TU: if
+// it creates its own llvm.used first, the one holding __attribute__((used))
+// globals gets renamed to llvm.used.1, which LLVM ignores.
+
+struct S { virtual ~S(); };
+S::~S() {}
+void del(S *s) { ::delete s; }
+
+__attribute__((used)) static void keep_me() {}
+
+// CHECK: @llvm.used = appending global
+// CHECK-SAME: @"?__empty_global_delete@@YAXPEAX_K at Z"
+// CHECK-SAME: @"?keep_me@@YAXXZ"

``````````

</details>


https://github.com/llvm/llvm-project/pull/218040


More information about the llvm-branch-commits mailing list