[all-commits] [llvm/llvm-project] 5fc5c2: [clang][win] Fix __global_delete wrappers for Arm6...

Daniel Paoliello via All-commits all-commits at lists.llvm.org
Thu Jul 16 12:02:12 PDT 2026


  Branch: refs/heads/main
  Home:   https://github.com/llvm/llvm-project
  Commit: 5fc5c2e4cde7ca12cbbd3868a8c24e0bbfcf570a
      https://github.com/llvm/llvm-project/commit/5fc5c2e4cde7ca12cbbd3868a8c24e0bbfcf570a
  Author: Daniel Paoliello <danpao at microsoft.com>
  Date:   2026-07-16 (Thu, 16 Jul 2026)

  Changed paths:
    M clang/lib/CodeGen/CGClass.cpp
    M clang/lib/CodeGen/CGExprCXX.cpp
    M clang/lib/CodeGen/CodeGenModule.cpp
    M clang/lib/CodeGen/CodeGenModule.h
    M clang/test/CodeGenCXX/microsoft-vector-deleting-dtors.cpp
    M clang/test/CodeGenCXX/microsoft-vector-deleting-dtors2.cpp
    A clang/test/CodeGenCXX/msvc-global-delete-forwarding-at-delete-site.cpp
    M clang/test/CodeGenCXX/msvc-global-delete-scalar-array-split.cpp
    M clang/test/CodeGenCXX/msvc-global-delete-scope-no-dtor.cpp
    M clang/test/CodeGenCXX/msvc-no-global-delete-forwarding.cpp

  Log Message:
  -----------
  [clang][win] Fix __global_delete wrappers for Arm64EC and cross-TU ::delete (#209585)

PR #188372 made Clang's MSVC-ABI deleting-destructor path route global
deletes
through compiler-generated __global_delete / __global_array_delete
wrappers
instead of referencing ::operator delete directly. This lets a deleting
destructor be emitted in environments (e.g. kernel mode) where no global
::operator delete exists: each wrapper defaults to a trapping
__empty_global_delete fallback, and a real forwarding body that calls
::operator delete is materialized only when the program actually uses
::delete.

This change refines how those wrappers and their fallbacks are emitted,
fixing
two problems that made the #188372 mechanism fail in practice.

New behavior:

- The trapping fallback is now emitted as a weak GlobalAlias to
__empty_global_delete rather than via an /alternatename directive. This
lowers
to a COFF weak-external-with-default -- exactly what MSVC emits -- so a
real
__global_delete defined in any TU overrides the fallback in every other
TU at
  link time.

- A ::delete expression now registers the wrapper for its resolved
global
operator delete directly (in EmitCXXDeleteExpr), so the strong
forwarding body
is emitted in that TU regardless of where the class's deleting
destructor is
defined. This matches MSVC, which emits the forwarder at every ::delete
site.

Bugs fixed:

1. Arm64EC (miscompile -> LNK2019). /alternatename only names the plain
symbol,
not the backend-generated "$$h" hybrid EC symbol referenced by the exit
thunk, so Arm64EC images left __global_delete$exit_thunk unresolved. The
weak
GlobalAlias correctly produces the "$$h" symbol, exit thunk, and plain
alias
   (verified on both x64 and Arm64EC).

2. Cross-TU ::delete (runtime crash). Previously the forwarding body was
only
emitted in a TU that *both* emitted a matching vector deleting
destructor and
contained a ::delete. A TU that only performed `::delete p` -- with the
class
defined elsewhere -- emitted no forwarder, so nothing overrode the
weak-alias
trap and the program executed a trapping __empty_global_delete at
runtime
(STATUS_ILLEGAL_INSTRUCTION). Registering the wrapper at the ::delete
site
   fixes this.

To share wrapper-creation logic between the deleting-destructor path and
the
delete-expression path, getOrCreateMSVCGlobalDeleteWrapper is promoted
from a
static helper in CGClass.cpp to a CodeGenModule method.

Verified end-to-end: a weak alias in one TU and a strong forwarder in
another
resolve to the forwarder under both lld-link and MSVC link.exe, and the
previously-crashing delete-only TU now runs cleanly.



To unsubscribe from these emails, change your notification settings at https://github.com/llvm/llvm-project/settings/notifications


More information about the All-commits mailing list