[SYCL] Fix use-after-free releasing UR resources through a freed adapter
Managed<ur_program/kernel_handle_t> stored a raw adapter_impl* and released
its UR resource in ~Managed through that pointer. Adapters were owned by
GlobalHandler as raw new/delete and freed in unloadAdapters(). A cached or
in-flight Managed (e.g. the program build result kept in a context's
KernelProgramCache, or a discarded getBuiltURProgram() retain() temporary)
could outlive adapter teardown and call urProgramRelease through a freed
adapter -> use-after-free. On Windows/icx the freed adapter's func-ptr table
reads back null, so the call jumps to 0x0 (SEH 0xC0000005); on other configs
the freed memory stayed usable and the bug was latent.
Own adapters with std::shared_ptr in GlobalHandler (the sole owner) and have
Managed hold a std::weak_ptr<adapter_impl> (adapter_impl now derives
enable_shared_from_this). ~Managed/retain lock the weak_ptr at point of use and
skip the release when the adapter is already gone, instead of dereferencing
freed memory. A weak_ptr is used rather than an owning shared_ptr so that
Managed handles do not extend adapter lifetime, which would perturb the
process-shutdown ordering of other runtime globals.
Fixes https://github.com/intel/llvm/issues/22367
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>