[Mlir-commits] [mlir] [mlir][IR] Avoid Clang 21 crash during SFINAE overload resolution (PR #208359)

Kazu Hirata llvmlistbot at llvm.org
Thu Jul 9 07:53:17 PDT 2026


https://github.com/kazutakahirata updated https://github.com/llvm/llvm-project/pull/208359

>From 448aa8f6c740903fb14c5c1df2e93bdd386e0594 Mon Sep 17 00:00:00 2001
From: Kazu Hirata <kazu at google.com>
Date: Wed, 8 Jul 2026 14:23:33 -0700
Subject: [PATCH 1/2] [mlir][IR] Avoid Clang 21 crash during SFINAE overload
 resolution

Clang 21.1.8 segfaults during SFINAE overload resolution for T::getChecked
when matching non-pointer arguments against an unconstrained MLIRContext*
parameter.

This patch avoids the crash by adding an explicit SFINAE constraint to
the second overload of StorageUserBase::getChecked, ensuring that it is
only considered when the second argument is convertible to MLIRContext*.

Assisted-by: Antigravity
---
 mlir/include/mlir/IR/StorageUniquerSupport.h | 11 +++++++++--
 1 file changed, 9 insertions(+), 2 deletions(-)

diff --git a/mlir/include/mlir/IR/StorageUniquerSupport.h b/mlir/include/mlir/IR/StorageUniquerSupport.h
index 8959dab047103..b8fd6051afa81 100644
--- a/mlir/include/mlir/IR/StorageUniquerSupport.h
+++ b/mlir/include/mlir/IR/StorageUniquerSupport.h
@@ -194,9 +194,16 @@ class StorageUserBase : public BaseT, public Traits<ConcreteT>... {
   /// Get or create a new ConcreteT instance within the ctx. If the arguments
   /// provided are invalid, errors are emitted using the provided `emitError`
   /// and a null object is returned.
-  template <typename... Args>
+  ///
+  /// Workaround: We use Arg1 && instead of MLIRContext * in the parameter list
+  /// to work around a bug in Clang 21.1.8 where Clang segfaults during SFINAE
+  /// overload resolution when attempting to match non-pointer arguments
+  /// against an unconstrained MLIRContext * parameter.
+  template <typename Arg1, typename... Args,
+            typename = std::enable_if_t<std::is_convertible<
+                llvm::remove_cvref_t<Arg1>, MLIRContext *>::value>>
   static ConcreteT getChecked(function_ref<InFlightDiagnostic()> emitErrorFn,
-                              MLIRContext *ctx, Args... args) {
+                              Arg1 &&ctx, Args... args) {
     // If the construction invariants fail then we return a null attribute.
     if (failed(ConcreteT::verifyInvariants(emitErrorFn, args...)))
       return ConcreteT();

>From 949f63fe41ea2594e56f0b35ab15cb6b9b161bed Mon Sep 17 00:00:00 2001
From: Kazu Hirata <kazu at google.com>
Date: Thu, 9 Jul 2026 07:52:57 -0700
Subject: [PATCH 2/2] Address comments.

---
 mlir/include/mlir/IR/StorageUniquerSupport.h | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/mlir/include/mlir/IR/StorageUniquerSupport.h b/mlir/include/mlir/IR/StorageUniquerSupport.h
index b8fd6051afa81..85189b5793fc7 100644
--- a/mlir/include/mlir/IR/StorageUniquerSupport.h
+++ b/mlir/include/mlir/IR/StorageUniquerSupport.h
@@ -200,8 +200,8 @@ class StorageUserBase : public BaseT, public Traits<ConcreteT>... {
   /// overload resolution when attempting to match non-pointer arguments
   /// against an unconstrained MLIRContext * parameter.
   template <typename Arg1, typename... Args,
-            typename = std::enable_if_t<std::is_convertible<
-                llvm::remove_cvref_t<Arg1>, MLIRContext *>::value>>
+            typename = std::enable_if_t<std::is_convertible_v<
+                llvm::remove_cvref_t<Arg1>, MLIRContext *>>>
   static ConcreteT getChecked(function_ref<InFlightDiagnostic()> emitErrorFn,
                               Arg1 &&ctx, Args... args) {
     // If the construction invariants fail then we return a null attribute.



More information about the Mlir-commits mailing list