https://github.com/rjodinchr updated https://github.com/llvm/llvm-project/pull/196571
>From 3a1a1f869091943822da9ba301f2d223840f11f9 Mon Sep 17 00:00:00 2001 From: Romaric Jodin <[email protected]> Date: Fri, 8 May 2026 16:14:06 +0200 Subject: [PATCH 1/2] Fix MSVC template parsing error in SerializationFormat This commit fixes a hard compilation error on Windows when building translation units that instantiate the `Add` registry template (such as `PointerFlowAnalysis.cpp`). **Root Cause:** When compiling on Windows, Clang defaults to MSVC compatibility mode (`-fms-compatibility`). Under this mode, Clang's two-phase template lookup struggles to resolve function-local static variables (`SavedSerialize` and `SavedDeserialize`) captured by a local class (`ConcreteCodec`) inside an uninstantiated template. During Phase 1 parsing, Clang incorrectly falls back to assuming these variables must be members of a dependent base class, rewriting them to `this->SavedSerialize`. During Phase 2 instantiation, compilation fails because the base class (`Codec`) has no such members. **The Fix:** Hoisted `SavedSerialize` and `SavedDeserialize` out of the constructor scope, making them `static inline` members of the `Add` class template. This allows Clang's Phase 1 parser to perfectly resolve the symbols without relying on broken MSVC fallbacks. **Why this is safe (Addressing the `dlopen` comment):** The original author explicitly commented that they avoided `static inline` class members to prevent Linux symbol visibility issues across shared library boundaries (`dlopen` with `RTLD_LOCAL`). That concern is still honored by this fix. The visibility risk only applies if the `ConcreteCodec`'s *own* execution state relied directly on static members. By moving the static variables to the `Add` factory class, `ConcreteCodec` continues to store `SerFn` and `DesFn` as strictly **instance members**. The `ConcreteCodec` constructor safely snapshots the plugin's local copy of `Add::SavedSerialize` at the moment of instantiation. Since the virtual methods executed by the host still read exclusively from the isolated instance state, the runtime behavior remains completely identical and safe. --- .../Core/Serialization/SerializationFormat.h | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/clang/include/clang/ScalableStaticAnalysisFramework/Core/Serialization/SerializationFormat.h b/clang/include/clang/ScalableStaticAnalysisFramework/Core/Serialization/SerializationFormat.h index fd261c6d9a723..9ab79dda3fc11 100644 --- a/clang/include/clang/ScalableStaticAnalysisFramework/Core/Serialization/SerializationFormat.h +++ b/clang/include/clang/ScalableStaticAnalysisFramework/Core/Serialization/SerializationFormat.h @@ -133,6 +133,9 @@ class SerializationFormat { using TypedSerializerFn = llvm::function_ref<SerRet(const AnalysisResultT &, SerArgs...)>; + static inline TypedSerializerFn SavedSerialize; + static inline DeserializerFn SavedDeserialize; + /// Takes the plugin's typed serializer and the deserializer, and /// inserts them into \c llvm::Registry<Codec>. Add(TypedSerializerFn TypedSerialize, DeserializerFn Deserialize) { @@ -154,8 +157,8 @@ class SerializationFormat { /// visibility issues across shared library boundaries on Linux /// (where \c dlopen with \c RTLD_LOCAL can give the host and /// plugin separate copies of \c static \c inline members). - static TypedSerializerFn SavedSerialize = TypedSerialize; - static DeserializerFn SavedDeserialize = Deserialize; + SavedSerialize = TypedSerialize; + SavedDeserialize = Deserialize; /// Concrete subclass of \c Codec for \c AnalysisResultT. /// The \c serialize() override performs the downcast from >From 71f74736a3ebeb2a59521f298523df17057a7555 Mon Sep 17 00:00:00 2001 From: Romaric Jodin <[email protected]> Date: Sat, 9 May 2026 17:03:07 +0200 Subject: [PATCH 2/2] Fix Windows CI segfault by using function pointers This commit fixes an 0xC0000005 access violation occurring during Windows CI testing for `clang-ssaf-format.exe`. * Root Cause: Because `TypedSerializerFn` and `DeserializerFn` were typed as `llvm::function_ref`, storing them in static variables (`SavedSerialize` and `SavedDeserialize`) inadvertently created dangling pointers. `llvm::function_ref` is a non-owning wrapper; it only captured a reference to the temporary callables decaying on the `Add` constructor's stack. Once the constructor returned, those temporaries were destroyed. Dereferencing the stored `function_ref` later caused an access violation on x64 Windows. * The Fix: Redefined `TypedSerializerFn` and `DeserializerFn` from `llvm::function_ref` to standard raw function pointers. This ensures the static registry variables safely capture and store the actual persistent addresses of the global functions being registered, completely eliminating the dangling pointers and resolving the crash. --- .../Core/Serialization/SerializationFormat.h | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/clang/include/clang/ScalableStaticAnalysisFramework/Core/Serialization/SerializationFormat.h b/clang/include/clang/ScalableStaticAnalysisFramework/Core/Serialization/SerializationFormat.h index 9ab79dda3fc11..af6a1ec98db78 100644 --- a/clang/include/clang/ScalableStaticAnalysisFramework/Core/Serialization/SerializationFormat.h +++ b/clang/include/clang/ScalableStaticAnalysisFramework/Core/Serialization/SerializationFormat.h @@ -111,7 +111,7 @@ class SerializationFormat { FormatT, llvm::function_ref<SerRet(const AnalysisResult &, SerArgs...)>, llvm::function_ref<DesRet(DesArgs...)>> { - using DeserializerFn = llvm::function_ref<DesRet(DesArgs...)>; + using DeserializerFn = DesRet (*)(DesArgs...); public: /// Abstract base type stored in \c llvm::Registry<Codec>. @@ -130,8 +130,7 @@ class SerializationFormat { }; template <class AnalysisResultT> struct Add { - using TypedSerializerFn = - llvm::function_ref<SerRet(const AnalysisResultT &, SerArgs...)>; + using TypedSerializerFn = SerRet (*)(const AnalysisResultT &, SerArgs...); static inline TypedSerializerFn SavedSerialize; static inline DeserializerFn SavedDeserialize; _______________________________________________ cfe-commits mailing list [email protected] https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
