From 18261a28811a368c32ff278d7ad9f07f49831e1d Mon Sep 17 00:00:00 2001 From: Elias Bachaalany Date: Mon, 23 Mar 2026 10:19:55 -0700 Subject: [PATCH] Fix DeclUnloader crash with UsingShadowDecl during undo When unloading transactions that contain implicit template instantiations with using-shadow declarations, the DeclUnloader crashes because the introducer's shadow chain may reference already-freed declarations. Fix: enable VisitRedeclarable for UsingShadowDecl (was FIXME'd out for newer Clang) and guard removeShadowDecl() with null/containment checks to prevent use-after-free. --- lib/Interpreter/DeclUnloader.cpp | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/lib/Interpreter/DeclUnloader.cpp b/lib/Interpreter/DeclUnloader.cpp index 37a60a0aef..783685ef2c 100644 --- a/lib/Interpreter/DeclUnloader.cpp +++ b/lib/Interpreter/DeclUnloader.cpp @@ -580,12 +580,16 @@ namespace cling { bool DeclUnloader::VisitUsingShadowDecl(UsingShadowDecl* USD) { // UsingShadowDecl: NamedDecl, Redeclarable bool Successful = true; - // FIXME: This is needed when we have newest clang: - //Successful = VisitRedeclarable(USD, USD->getDeclContext()); + Successful = VisitRedeclarable(USD, USD->getDeclContext()); Successful &= VisitNamedDecl(USD); // Unregister from the using decl that it shadows. - USD->getIntroducer()->removeShadowDecl(USD); + // Guard: the introducer's shadow chain may reference already-freed + // declarations when unloading implicit template instantiations. + if (auto* Introducer = USD->getIntroducer()) { + if (llvm::is_contained(Introducer->shadows(), USD)) + Introducer->removeShadowDecl(USD); + } return Successful; }