On Fri, Feb 13, 2026 at 03:17:53PM -0500, Marek Polacek wrote:
> Bootstrapped/regtested on x86_64-pc-linux-gnu, ok for trunk?
> 
> -- >8 --
> [bit.cast]/2: Mandates: Neither To nor From are consteval-only types
> 
> but we are not checking this, so the attached test compiled.
> 
>       PR libstdc++/124096
> 
> libstdc++-v3/ChangeLog:
> 
>       * include/std/bit: Check that neither To nor From are consteval-only
>       types.
>       * testsuite/26_numerics/bit/bit.cast/124096.cc: New test.
> ---
>  libstdc++-v3/include/std/bit                        |  4 ++++
>  .../testsuite/26_numerics/bit/bit.cast/124096.cc    | 13 +++++++++++++
>  2 files changed, 17 insertions(+)
>  create mode 100644 libstdc++-v3/testsuite/26_numerics/bit/bit.cast/124096.cc
> 
> diff --git a/libstdc++-v3/include/std/bit b/libstdc++-v3/include/std/bit
> index 6ea0f6eef83..f33acb999cf 100644
> --- a/libstdc++-v3/include/std/bit
> +++ b/libstdc++-v3/include/std/bit
> @@ -93,6 +93,10 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
>        && is_trivially_copyable_v<_To> && is_trivially_copyable_v<_From>
>  #endif
>      {
> +#if __cpp_impl_reflection >= 202506L
> +      static_assert(!is_consteval_only_v<_To> && !is_consteval_only_v<_From>,
> +                 "neither To nor From can be consteval-only types");
> +#endif
>        return __builtin_bit_cast(_To, __from);
>      }
>  #endif // __cpp_lib_bit_cast
> diff --git a/libstdc++-v3/testsuite/26_numerics/bit/bit.cast/124096.cc 
> b/libstdc++-v3/testsuite/26_numerics/bit/bit.cast/124096.cc
> new file mode 100644
> index 00000000000..12c93f712df
> --- /dev/null
> +++ b/libstdc++-v3/testsuite/26_numerics/bit/bit.cast/124096.cc
> @@ -0,0 +1,13 @@
> +// PR libstdc++/124096
> +// { dg-do compile { target c++26 } }
> +// { dg-additional-options "-freflection" }
> +
> +#include <bit>
> +
> +consteval void
> +f ()
> +{
> +  (void) std::bit_cast<long long>(^^int);  // { dg-error "here" }
> +}

Shouldn't the testcase check both From and To separately?
Also, wouldn't it be better to use say
  auto a = ^^int;
  auto *b = &a;
  void *c = nullptr;
  std::bit_cast<void*>(b);
  std::bit_cast<decltype (^^int)*>(c);
?  What sizeof(^^int) is is implementation-defined (I think
in gcc we use sizeof(void*) aka sizeof(__INTPTR_TYPE__) or so,
so long long can error differently e.g. on ia32, in clang it is
16 regardless of -m32/-m64), while pointer to decltype(^^int) is
also consteval-only but better should be the same as other pointers.

        Jakub

Reply via email to