https://github.com/eisenwave updated 
https://github.com/llvm/llvm-project/pull/195534

>From 9e700211401821a4238f6088729236aab2e52915 Mon Sep 17 00:00:00 2001
From: Eisenwave <[email protected]>
Date: Sun, 3 May 2026 17:17:24 +0200
Subject: [PATCH 1/5] [clang] Deduce _BitInt(N) template parameter as size_t

Update template argument deduction to deduce the N in _BitInt(N) as size_t 
rather than int.
This increases consistency with deduction of array sizes, and matches the 
behavior proposed in P3666.
---
 clang/lib/Sema/SemaTemplateDeduction.cpp |  7 ++++--
 clang/test/SemaTemplate/deduction.cpp    | 27 ++++++++++++++++++++++++
 2 files changed, 32 insertions(+), 2 deletions(-)

diff --git a/clang/lib/Sema/SemaTemplateDeduction.cpp 
b/clang/lib/Sema/SemaTemplateDeduction.cpp
index a287319cc4f88..3528fa001c201 100644
--- a/clang/lib/Sema/SemaTemplateDeduction.cpp
+++ b/clang/lib/Sema/SemaTemplateDeduction.cpp
@@ -2521,11 +2521,14 @@ static TemplateDeductionResult 
DeduceTemplateArgumentsByTypeMatch(
         if (!NTTP)
           return TemplateDeductionResult::Success;
 
-        llvm::APSInt ArgSize(S.Context.getTypeSize(S.Context.IntTy), false);
+        // P3666 suggested wording for [temp.deduct.type]:
+        //   The type of N in the type _BitInt(N) is std::size_t.
+        QualType T = S.Context.getSizeType();
+        llvm::APSInt ArgSize(S.Context.getTypeSize(T), false);
         ArgSize = IA->getNumBits();
 
         return DeduceNonTypeTemplateArgument(
-            S, TemplateParams, NTTP, ArgSize, S.Context.IntTy, true, Info,
+            S, TemplateParams, NTTP, ArgSize, T, true, Info,
             POK != PartialOrderingKind::None, Deduced, HasDeducedAnyParam);
       }
 
diff --git a/clang/test/SemaTemplate/deduction.cpp 
b/clang/test/SemaTemplate/deduction.cpp
index a209615c36479..e1ac6a9e5d267 100644
--- a/clang/test/SemaTemplate/deduction.cpp
+++ b/clang/test/SemaTemplate/deduction.cpp
@@ -633,6 +633,33 @@ namespace dependent_list_deduction {
   }
 }
 
+namespace bitint_deduction {
+#if __cplusplus >= 201703L
+  template<auto X> void f(unsigned _BitInt(X)) {
+    static_assert(is_same<decltype(X), decltype(sizeof(0))>::value, "");
+    static_assert(X == 31, "");
+  }
+  template<auto X> void g(_BitInt(X)) {
+    static_assert(is_same<decltype(X), decltype(sizeof(0))>::value, "");
+    static_assert(X == 32, "");
+  }
+  template<typename T, T V> void i(unsigned _BitInt(V)) {
+    static_assert(is_same<T, decltype(sizeof(0))>::value, "");
+    static_assert(V == 33, "");
+  }
+  template<typename T, T V> void j(_BitInt(V)) {
+    static_assert(is_same<T, decltype(sizeof(0))>::value, "");
+    static_assert(V == 34, "");
+  }
+  void h() {
+    f(static_cast<unsigned _BitInt(31)>(0));
+    g(static_cast<_BitInt(32)>(0));
+    i(static_cast<unsigned _BitInt(33)>(0));
+    j(static_cast<_BitInt(34)>(0));
+  }
+#endif
+}
+
 namespace designators {
   template<typename T, int N> constexpr int f(T (&&)[N]) { return N; } // 
expected-note 2{{couldn't infer template argument 'T'}}
   static_assert(f({1, 2, [20] = 3}) == 3, ""); // expected-error {{no matching 
function}} expected-warning 2{{C99}} expected-note {{}}

>From 6519a0e71345d54bb4853d02cbad325c052613c2 Mon Sep 17 00:00:00 2001
From: Eisenwave <[email protected]>
Date: Sun, 3 May 2026 18:27:47 +0200
Subject: [PATCH 2/5] Move test to ext-int.cpp, add size_t

---
 clang/test/SemaCXX/ext-int.cpp        | 50 ++++++++++++++++++++++-----
 clang/test/SemaTemplate/deduction.cpp | 27 ---------------
 2 files changed, 41 insertions(+), 36 deletions(-)

diff --git a/clang/test/SemaCXX/ext-int.cpp b/clang/test/SemaCXX/ext-int.cpp
index 5c566dafed931..cb43ada30d13b 100644
--- a/clang/test/SemaCXX/ext-int.cpp
+++ b/clang/test/SemaCXX/ext-int.cpp
@@ -61,6 +61,38 @@ template<typename T>
 void deduced_whole_type(T){}
 template<int I>
 void deduced_bound(_BitInt(I)){}
+template<int I>
+void deduced_bound_unsigned(unsigned _BitInt(I)){}
+
+template <typename T, typename U>
+struct is_same {
+  static constexpr bool value = false;
+};
+template <typename T>
+struct is_same<T,T> {
+  static constexpr bool value = true;
+};
+
+using size_t = decltype(sizeof(0));
+
+#if __cplusplus >= 201703L
+template<auto X> void deduced_bound_auto(_BitInt(X)) {
+  static_assert(is_same<decltype(X), size_t>::value, "");
+  static_assert(X == 9, "");
+}
+template<auto X> void deduced_bound_auto_unsigned(unsigned _BitInt(X)) {
+  static_assert(is_same<decltype(X), size_t>::value, "");
+  static_assert(X == 11, "");
+}
+template<typename T, T V> void deduced_bound_dependent(_BitInt(V)) {
+  static_assert(is_same<T, size_t>::value, "");
+  static_assert(V == 9, "");
+}
+template<typename T, T V> void deduced_bound_dependent_unsigned(unsigned 
_BitInt(V)) {
+  static_assert(is_same<T, size_t>::value, "");
+  static_assert(V == 11, "");
+}
+#endif
 
 // Ensure ext-int can be used in template places.
 void Templates() {
@@ -69,20 +101,20 @@ void Templates() {
   ExtIntTemplParam<b> c;
   constexpr _BitInt(9) d = 1;
   ExtIntTemplParam<b> e;
+  constexpr unsigned _BitInt(11) f = 1;
 
   deduced_whole_type(b);
+  deduced_whole_type(f);
   deduced_bound(b);
+  deduced_bound_unsigned(f);
+#if __cplusplus >= 201703L
+  deduced_bound_auto(d);
+  deduced_bound_auto_unsigned(f);
+  deduced_bound_dependent(d);
+  deduced_bound_dependent_unsigned(f);
+#endif
 }
 
-template <typename T, typename U>
-struct is_same {
-  static constexpr bool value = false;
-};
-template <typename T>
-struct is_same<T,T> {
-  static constexpr bool value = true;
-};
-
 // Reject vector types:
 // expected-error@+1{{'_BitInt' vector element width must be a power of 2}}
 typedef _BitInt(5) __attribute__((vector_size(16))) VecTy3;
diff --git a/clang/test/SemaTemplate/deduction.cpp 
b/clang/test/SemaTemplate/deduction.cpp
index e1ac6a9e5d267..a209615c36479 100644
--- a/clang/test/SemaTemplate/deduction.cpp
+++ b/clang/test/SemaTemplate/deduction.cpp
@@ -633,33 +633,6 @@ namespace dependent_list_deduction {
   }
 }
 
-namespace bitint_deduction {
-#if __cplusplus >= 201703L
-  template<auto X> void f(unsigned _BitInt(X)) {
-    static_assert(is_same<decltype(X), decltype(sizeof(0))>::value, "");
-    static_assert(X == 31, "");
-  }
-  template<auto X> void g(_BitInt(X)) {
-    static_assert(is_same<decltype(X), decltype(sizeof(0))>::value, "");
-    static_assert(X == 32, "");
-  }
-  template<typename T, T V> void i(unsigned _BitInt(V)) {
-    static_assert(is_same<T, decltype(sizeof(0))>::value, "");
-    static_assert(V == 33, "");
-  }
-  template<typename T, T V> void j(_BitInt(V)) {
-    static_assert(is_same<T, decltype(sizeof(0))>::value, "");
-    static_assert(V == 34, "");
-  }
-  void h() {
-    f(static_cast<unsigned _BitInt(31)>(0));
-    g(static_cast<_BitInt(32)>(0));
-    i(static_cast<unsigned _BitInt(33)>(0));
-    j(static_cast<_BitInt(34)>(0));
-  }
-#endif
-}
-
 namespace designators {
   template<typename T, int N> constexpr int f(T (&&)[N]) { return N; } // 
expected-note 2{{couldn't infer template argument 'T'}}
   static_assert(f({1, 2, [20] = 3}) == 3, ""); // expected-error {{no matching 
function}} expected-warning 2{{C99}} expected-note {{}}

>From 084dc0cbb1326dde31c3f1c75ba25cdb117047c8 Mon Sep 17 00:00:00 2001
From: Jan Schultke <[email protected]>
Date: Sun, 3 May 2026 18:29:06 +0200
Subject: [PATCH 3/5] Update clang/lib/Sema/SemaTemplateDeduction.cpp

Co-authored-by: Corentin Jabot <[email protected]>
---
 clang/lib/Sema/SemaTemplateDeduction.cpp | 3 +--
 1 file changed, 1 insertion(+), 2 deletions(-)

diff --git a/clang/lib/Sema/SemaTemplateDeduction.cpp 
b/clang/lib/Sema/SemaTemplateDeduction.cpp
index 3528fa001c201..947f742600a64 100644
--- a/clang/lib/Sema/SemaTemplateDeduction.cpp
+++ b/clang/lib/Sema/SemaTemplateDeduction.cpp
@@ -2521,8 +2521,7 @@ static TemplateDeductionResult 
DeduceTemplateArgumentsByTypeMatch(
         if (!NTTP)
           return TemplateDeductionResult::Success;
 
-        // P3666 suggested wording for [temp.deduct.type]:
-        //   The type of N in the type _BitInt(N) is std::size_t.
+        // Deduce the size parameter of _BitInt as std::size_t
         QualType T = S.Context.getSizeType();
         llvm::APSInt ArgSize(S.Context.getTypeSize(T), false);
         ArgSize = IA->getNumBits();

>From d750161666fc0b3eeffec5e3bacae512ec352e08 Mon Sep 17 00:00:00 2001
From: Eisenwave <[email protected]>
Date: Sun, 3 May 2026 20:28:03 +0200
Subject: [PATCH 4/5] Update release notes

---
 clang/docs/ReleaseNotes.rst | 5 +++++
 1 file changed, 5 insertions(+)

diff --git a/clang/docs/ReleaseNotes.rst b/clang/docs/ReleaseNotes.rst
index 2319ff13f7864..31e04fc169061 100644
--- a/clang/docs/ReleaseNotes.rst
+++ b/clang/docs/ReleaseNotes.rst
@@ -130,6 +130,11 @@ C++ Specific Potentially Breaking Changes
 - ``VarTemplateSpecializationDecl::getTemplateArgsAsWritten()`` method now
   returns ``nullptr`` for implicitly instantiated declarations.
 
+- Template argument deduction now treats the ``N`` in ``_BitInt(N)``
+  as being of type ``std::size_t`` instead of ``int``,
+  matching the deduction of array sizes from ``int(&)[N]``.
+  This is a breaking change for code that depended on the previously deduced 
type. (#GH195033)
+
 ABI Changes in This Version
 ---------------------------
 - Fix AArch64 argument passing for C++ empty classes with large explicitly 
specified alignment.

>From 9d60be5afcee23be08143ac964fc0630d667255c Mon Sep 17 00:00:00 2001
From: Eisenwave <[email protected]>
Date: Wed, 6 May 2026 20:51:25 +0200
Subject: [PATCH 5/5] Make ArgSize unsigned

---
 clang/lib/Sema/SemaTemplateDeduction.cpp | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/clang/lib/Sema/SemaTemplateDeduction.cpp 
b/clang/lib/Sema/SemaTemplateDeduction.cpp
index 947f742600a64..452c0ff88ac27 100644
--- a/clang/lib/Sema/SemaTemplateDeduction.cpp
+++ b/clang/lib/Sema/SemaTemplateDeduction.cpp
@@ -2523,7 +2523,7 @@ static TemplateDeductionResult 
DeduceTemplateArgumentsByTypeMatch(
 
         // Deduce the size parameter of _BitInt as std::size_t
         QualType T = S.Context.getSizeType();
-        llvm::APSInt ArgSize(S.Context.getTypeSize(T), false);
+        llvm::APSInt ArgSize(S.Context.getTypeSize(T), true);
         ArgSize = IA->getNumBits();
 
         return DeduceNonTypeTemplateArgument(

_______________________________________________
cfe-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to