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
