public inbox for gcc-bugs@sourceware.org
help / color / mirror / Atom feed
* [Bug libstdc++/105027] New: Missing constraints on std::bit_cast
@ 2022-03-22 22:25 ed at catmur dot uk
  2022-03-23  9:46 ` [Bug libstdc++/105027] " redi at gcc dot gnu.org
                   ` (6 more replies)
  0 siblings, 7 replies; 8+ messages in thread
From: ed at catmur dot uk @ 2022-03-22 22:25 UTC (permalink / raw)
  To: gcc-bugs

https://gcc.gnu.org/bugzilla/show_bug.cgi?id=105027

            Bug ID: 105027
           Summary: Missing constraints on std::bit_cast
           Product: gcc
           Version: 12.0
            Status: UNCONFIRMED
          Severity: normal
          Priority: P3
         Component: libstdc++
          Assignee: unassigned at gcc dot gnu.org
          Reporter: ed at catmur dot uk
  Target Milestone: ---

[bit.cast] Constraints (nb. prior to P1719R2 these were specified as SFINAE,
but they have been there since the start):
(1.1) sizeof(To) == sizeof(From) is true;
(1.2) is_­trivially_­copyable_­v<To> is true; and
(1.3) is_­trivially_­copyable_­v<From> is true.

#include <bit>
template<class T, class U>
concept BitCastable = requires(U u) { std::bit_cast<T>(u); };
static_assert(BitCastable<int, unsigned>); // OK
static_assert(BitCastable<int, char>); // #1: different size
struct A { A(A const&); int i; };
static_assert(BitCastable<int, A>); // #2: not trivially copyable

#1 and #2 are erroneously accepted although the corresponding call to
std::bit_cast would fail internally; MSVC and clang (with libc++) correctly
reject.

static_assert(BitCastable<long, int()>); // #3: see below
int f();
long l = std::bit_cast<long>(f); // #4

By my reading of [temp.deduct] #3 should be a hard error, since sizeof(int())
is not only invalid; it is not SFINAE. However, compilers that allow it (gcc
everywhere, MSVC and clang as SFINAE) should then reject either by SFINAE, or
as having the incorrect size, or since function types are not trivially
copyable; gcc/libstdc++ does not and also accepts #4, decaying the function
reference to a function pointer; clang/libstdc++ rejects within its own
__builtin_bit_cast.

^ permalink raw reply	[flat|nested] 8+ messages in thread

* [Bug libstdc++/105027] Missing constraints on std::bit_cast
  2022-03-22 22:25 [Bug libstdc++/105027] New: Missing constraints on std::bit_cast ed at catmur dot uk
@ 2022-03-23  9:46 ` redi at gcc dot gnu.org
  2022-03-23  9:49 ` redi at gcc dot gnu.org
                   ` (5 subsequent siblings)
  6 siblings, 0 replies; 8+ messages in thread
From: redi at gcc dot gnu.org @ 2022-03-23  9:46 UTC (permalink / raw)
  To: gcc-bugs

https://gcc.gnu.org/bugzilla/show_bug.cgi?id=105027

Jonathan Wakely <redi at gcc dot gnu.org> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
     Ever confirmed|0                           |1
           Assignee|unassigned at gcc dot gnu.org      |redi at gcc dot gnu.org
             Status|UNCONFIRMED                 |ASSIGNED
   Target Milestone|---                         |11.3
   Last reconfirmed|                            |2022-03-23

--- Comment #1 from Jonathan Wakely <redi at gcc dot gnu.org> ---
(In reply to Ed Catmur from comment #0)
> #1 and #2 are erroneously accepted although the corresponding call to
> std::bit_cast would fail internally;

Yes, those checks are done by the compiler in __builtin_bit_cast but that means
they're the equivalent of "Mandates:" not "Constraints:".

> static_assert(BitCastable<long, int()>); // #3: see below
> int f();
> long l = std::bit_cast<long>(f); // #4
> 
> By my reading of [temp.deduct] #3 should be a hard error, since
> sizeof(int()) is not only invalid; it is not SFINAE.

[temp.deduct.general] p8 says "If a substitution results in an invalid type or
expression, type deduction fails. An invalid type or expression is one that
would be ill-formed, with a diagnostic required, if written in the same context
using the substituted arguments."

Substituting a function type for T in sizeof(T) creates an invalid expression,
so deduction fails. It's a substitution failure, not an error.

> However, compilers that
> allow it (gcc everywhere,

GCC allows it because of https://gcc.gnu.org/onlinedocs/gcc/Pointer-Arith.html
but that extension is disabled in SFINAE contexts, so it's still a substitution
failure.

> MSVC and clang as SFINAE) should then reject
> either by SFINAE, or as having the incorrect size, or since function types
> are not trivially copyable; gcc/libstdc++ does not and also accepts #4,

GCC does reject it as a substitution failure, like MSVC and Clang do. The
reason #4 is accepted is because std::bit_cast isn't constrained. You don't get
a substitution failure for sizeof(int()) if there's no constraint using sizeof.

> decaying the function reference to a function pointer; clang/libstdc++
> rejects within its own __builtin_bit_cast.

Maybe __builtin_bit_cast should check that, but it won't matter once
std::bit_cast is properly constrained.

^ permalink raw reply	[flat|nested] 8+ messages in thread

* [Bug libstdc++/105027] Missing constraints on std::bit_cast
  2022-03-22 22:25 [Bug libstdc++/105027] New: Missing constraints on std::bit_cast ed at catmur dot uk
  2022-03-23  9:46 ` [Bug libstdc++/105027] " redi at gcc dot gnu.org
@ 2022-03-23  9:49 ` redi at gcc dot gnu.org
  2022-03-23  9:56 ` redi at gcc dot gnu.org
                   ` (4 subsequent siblings)
  6 siblings, 0 replies; 8+ messages in thread
From: redi at gcc dot gnu.org @ 2022-03-23  9:49 UTC (permalink / raw)
  To: gcc-bugs

https://gcc.gnu.org/bugzilla/show_bug.cgi?id=105027

--- Comment #2 from Jonathan Wakely <redi at gcc dot gnu.org> ---
(In reply to Ed Catmur from comment #0)
> [bit.cast] Constraints (nb. prior to P1719R2 these were specified as SFINAE,
> but they have been there since the start):

N.B. P1719 didn't change anything here, the new Constraints: element is exactly
equivalent to "shall not participate in overload resolution unless ..."

^ permalink raw reply	[flat|nested] 8+ messages in thread

* [Bug libstdc++/105027] Missing constraints on std::bit_cast
  2022-03-22 22:25 [Bug libstdc++/105027] New: Missing constraints on std::bit_cast ed at catmur dot uk
  2022-03-23  9:46 ` [Bug libstdc++/105027] " redi at gcc dot gnu.org
  2022-03-23  9:49 ` redi at gcc dot gnu.org
@ 2022-03-23  9:56 ` redi at gcc dot gnu.org
  2022-03-23 12:17 ` cvs-commit at gcc dot gnu.org
                   ` (3 subsequent siblings)
  6 siblings, 0 replies; 8+ messages in thread
From: redi at gcc dot gnu.org @ 2022-03-23  9:56 UTC (permalink / raw)
  To: gcc-bugs

https://gcc.gnu.org/bugzilla/show_bug.cgi?id=105027

--- Comment #3 from Jonathan Wakely <redi at gcc dot gnu.org> ---
(In reply to Ed Catmur from comment #0)
> static_assert(BitCastable<long, int()>); // #3: see below
> int f();
> long l = std::bit_cast<long>(f); // #4
> 
> By my reading of [temp.deduct] #3 should be a hard error, since
> sizeof(int()) is not only invalid;

Your BitCastable concept uses requires (U u) so the decay to a function pointer
happens there, and so its std::bit_cast<T>(u) expression *is* valid.

i.e. #3 is not testing the same thing as #4

^ permalink raw reply	[flat|nested] 8+ messages in thread

* [Bug libstdc++/105027] Missing constraints on std::bit_cast
  2022-03-22 22:25 [Bug libstdc++/105027] New: Missing constraints on std::bit_cast ed at catmur dot uk
                   ` (2 preceding siblings ...)
  2022-03-23  9:56 ` redi at gcc dot gnu.org
@ 2022-03-23 12:17 ` cvs-commit at gcc dot gnu.org
  2022-04-04 11:47 ` cvs-commit at gcc dot gnu.org
                   ` (2 subsequent siblings)
  6 siblings, 0 replies; 8+ messages in thread
From: cvs-commit at gcc dot gnu.org @ 2022-03-23 12:17 UTC (permalink / raw)
  To: gcc-bugs

https://gcc.gnu.org/bugzilla/show_bug.cgi?id=105027

--- Comment #4 from CVS Commits <cvs-commit at gcc dot gnu.org> ---
The master branch has been updated by Jonathan Wakely <redi@gcc.gnu.org>:

https://gcc.gnu.org/g:4894d69a1f37d54b6a612e58053db477ff5ba832

commit r12-7781-g4894d69a1f37d54b6a612e58053db477ff5ba832
Author: Jonathan Wakely <jwakely@redhat.com>
Date:   Wed Mar 23 09:57:20 2022 +0000

    libstdc++: Add missing constraints to std::bit_cast [PR105027]

    Our std::bit_cast was relying on the compiler to check for errors inside
    __builtin_bit_cast, instead of checking them as constraints. That means
    std::bit_cast was not SFINAE-friendly.

    This fix uses a requires-clause, so for old versions of Clang without
    concepts support the function will still be unconstrained. At some point
    in future we can remove the #ifdef __cpp_concepts check and rely on all
    compilers having full concepts support in C++20 mode.

    libstdc++-v3/ChangeLog:

            PR libstdc++/105027
            * include/std/bit (bit_cast): Add constraints.
            * testsuite/26_numerics/bit/bit.cast/105027.cc: New test.

^ permalink raw reply	[flat|nested] 8+ messages in thread

* [Bug libstdc++/105027] Missing constraints on std::bit_cast
  2022-03-22 22:25 [Bug libstdc++/105027] New: Missing constraints on std::bit_cast ed at catmur dot uk
                   ` (3 preceding siblings ...)
  2022-03-23 12:17 ` cvs-commit at gcc dot gnu.org
@ 2022-04-04 11:47 ` cvs-commit at gcc dot gnu.org
  2022-04-04 21:20 ` redi at gcc dot gnu.org
  2022-04-04 21:20 ` redi at gcc dot gnu.org
  6 siblings, 0 replies; 8+ messages in thread
From: cvs-commit at gcc dot gnu.org @ 2022-04-04 11:47 UTC (permalink / raw)
  To: gcc-bugs

https://gcc.gnu.org/bugzilla/show_bug.cgi?id=105027

--- Comment #5 from CVS Commits <cvs-commit at gcc dot gnu.org> ---
The releases/gcc-11 branch has been updated by Jonathan Wakely
<redi@gcc.gnu.org>:

https://gcc.gnu.org/g:20f2303b0ce6bbe412e852e6423daabd04c39ebb

commit r11-9773-g20f2303b0ce6bbe412e852e6423daabd04c39ebb
Author: Jonathan Wakely <jwakely@redhat.com>
Date:   Wed Mar 23 09:57:20 2022 +0000

    libstdc++: Add missing constraints to std::bit_cast [PR105027]

    Our std::bit_cast was relying on the compiler to check for errors inside
    __builtin_bit_cast, instead of checking them as constraints. That means
    std::bit_cast was not SFINAE-friendly.

    This fix uses a requires-clause, so for old versions of Clang without
    concepts support the function will still be unconstrained. At some point
    in future we can remove the #ifdef __cpp_concepts check and rely on all
    compilers having full concepts support in C++20 mode.

    libstdc++-v3/ChangeLog:

            PR libstdc++/105027
            * include/std/bit (bit_cast): Add constraints.
            * testsuite/26_numerics/bit/bit.cast/105027.cc: New test.

    (cherry picked from commit 4894d69a1f37d54b6a612e58053db477ff5ba832)

^ permalink raw reply	[flat|nested] 8+ messages in thread

* [Bug libstdc++/105027] Missing constraints on std::bit_cast
  2022-03-22 22:25 [Bug libstdc++/105027] New: Missing constraints on std::bit_cast ed at catmur dot uk
                   ` (4 preceding siblings ...)
  2022-04-04 11:47 ` cvs-commit at gcc dot gnu.org
@ 2022-04-04 21:20 ` redi at gcc dot gnu.org
  2022-04-04 21:20 ` redi at gcc dot gnu.org
  6 siblings, 0 replies; 8+ messages in thread
From: redi at gcc dot gnu.org @ 2022-04-04 21:20 UTC (permalink / raw)
  To: gcc-bugs

https://gcc.gnu.org/bugzilla/show_bug.cgi?id=105027

--- Comment #6 from Jonathan Wakely <redi at gcc dot gnu.org> ---
Fixed for 11.3

^ permalink raw reply	[flat|nested] 8+ messages in thread

* [Bug libstdc++/105027] Missing constraints on std::bit_cast
  2022-03-22 22:25 [Bug libstdc++/105027] New: Missing constraints on std::bit_cast ed at catmur dot uk
                   ` (5 preceding siblings ...)
  2022-04-04 21:20 ` redi at gcc dot gnu.org
@ 2022-04-04 21:20 ` redi at gcc dot gnu.org
  6 siblings, 0 replies; 8+ messages in thread
From: redi at gcc dot gnu.org @ 2022-04-04 21:20 UTC (permalink / raw)
  To: gcc-bugs

https://gcc.gnu.org/bugzilla/show_bug.cgi?id=105027

Jonathan Wakely <redi at gcc dot gnu.org> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
         Resolution|---                         |FIXED
             Status|ASSIGNED                    |RESOLVED

--- Comment #7 from Jonathan Wakely <redi at gcc dot gnu.org> ---
.

^ permalink raw reply	[flat|nested] 8+ messages in thread

end of thread, other threads:[~2022-04-04 21:20 UTC | newest]

Thread overview: 8+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2022-03-22 22:25 [Bug libstdc++/105027] New: Missing constraints on std::bit_cast ed at catmur dot uk
2022-03-23  9:46 ` [Bug libstdc++/105027] " redi at gcc dot gnu.org
2022-03-23  9:49 ` redi at gcc dot gnu.org
2022-03-23  9:56 ` redi at gcc dot gnu.org
2022-03-23 12:17 ` cvs-commit at gcc dot gnu.org
2022-04-04 11:47 ` cvs-commit at gcc dot gnu.org
2022-04-04 21:20 ` redi at gcc dot gnu.org
2022-04-04 21:20 ` redi at gcc dot gnu.org

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).