public inbox for gcc-bugs@sourceware.org
help / color / mirror / Atom feed
* [Bug c++/103511] New: __builtin_bit_cast requires a constructor call
@ 2021-12-01  3:46 de34 at live dot cn
  2021-12-01  8:35 ` [Bug c++/103511] " redi at gcc dot gnu.org
                   ` (5 more replies)
  0 siblings, 6 replies; 7+ messages in thread
From: de34 at live dot cn @ 2021-12-01  3:46 UTC (permalink / raw)
  To: gcc-bugs

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

            Bug ID: 103511
           Summary: __builtin_bit_cast requires a constructor call
           Product: gcc
           Version: 12.0
            Status: UNCONFIRMED
          Keywords: rejects-valid
          Severity: normal
          Priority: P3
         Component: c++
          Assignee: unassigned at gcc dot gnu.org
          Reporter: de34 at live dot cn
  Target Milestone: ---

According to [class.prop] p1, a trivially copyable class may have all of its
constructors deleted. And according to [bit.cast] p1, an object of such a class
type can be created or copied by std::bit_cast since C++20.
But currently gcc's __builtin_bit_cast seemly requires that the target type has
at least one eligible copy or move constructor.

#include <bit>

class Weird {
    Weird(const Weird&) = delete;
    Weird(Weird&&) = delete;
    // works when either constructor is changed to = default
    Weird &operator=(const Weird&) = default;
    Weird &operator=(Weird&&) = default;

    int value_;
};

int main()
{
    auto x [[maybe_unused]] = std::bit_cast<Weird>(0);
}

wandbox links:
https://wandbox.org/permlink/giaPU2R4O2XeF6UF
https://wandbox.org/permlink/lrMmtVw1mt5nZjqY

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

* [Bug c++/103511] __builtin_bit_cast requires a constructor call
  2021-12-01  3:46 [Bug c++/103511] New: __builtin_bit_cast requires a constructor call de34 at live dot cn
@ 2021-12-01  8:35 ` redi at gcc dot gnu.org
  2021-12-01 11:03 ` jakub at gcc dot gnu.org
                   ` (4 subsequent siblings)
  5 siblings, 0 replies; 7+ messages in thread
From: redi at gcc dot gnu.org @ 2021-12-01  8:35 UTC (permalink / raw)
  To: gcc-bugs

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

--- Comment #1 from Jonathan Wakely <redi at gcc dot gnu.org> ---
This seems like a defect in the standard.

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

* [Bug c++/103511] __builtin_bit_cast requires a constructor call
  2021-12-01  3:46 [Bug c++/103511] New: __builtin_bit_cast requires a constructor call de34 at live dot cn
  2021-12-01  8:35 ` [Bug c++/103511] " redi at gcc dot gnu.org
@ 2021-12-01 11:03 ` jakub at gcc dot gnu.org
  2023-07-07 17:19 ` ldionne.2 at gmail dot com
                   ` (3 subsequent siblings)
  5 siblings, 0 replies; 7+ messages in thread
From: jakub at gcc dot gnu.org @ 2021-12-01 11:03 UTC (permalink / raw)
  To: gcc-bugs

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

Jakub Jelinek <jakub at gcc dot gnu.org> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
                 CC|                            |jakub at gcc dot gnu.org,
                   |                            |jason at gcc dot gnu.org

--- Comment #2 from Jakub Jelinek <jakub at gcc dot gnu.org> ---
If __builtin_bit_cast should bypass the ctors, then perhaps something like:
--- gcc/cp/semantics.c.jj
+++ gcc/cp/semantics.c
@@ -11673,7 +11673,7 @@ cp_build_bit_cast (location_t loc, tree type, tree arg,
   SET_EXPR_LOCATION (ret, loc);

   if (!processing_template_decl && CLASS_TYPE_P (type))
-    ret = get_target_expr_sfinae (ret, complain);
+    ret = force_target_expr (type, ret, complain);

   return ret;
 }
would handle it, but I don't know if that is desirable or the right thing.

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

* [Bug c++/103511] __builtin_bit_cast requires a constructor call
  2021-12-01  3:46 [Bug c++/103511] New: __builtin_bit_cast requires a constructor call de34 at live dot cn
  2021-12-01  8:35 ` [Bug c++/103511] " redi at gcc dot gnu.org
  2021-12-01 11:03 ` jakub at gcc dot gnu.org
@ 2023-07-07 17:19 ` ldionne.2 at gmail dot com
  2023-07-07 17:21 ` jakub at gcc dot gnu.org
                   ` (2 subsequent siblings)
  5 siblings, 0 replies; 7+ messages in thread
From: ldionne.2 at gmail dot com @ 2023-07-07 17:19 UTC (permalink / raw)
  To: gcc-bugs

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

Louis Dionne <ldionne.2 at gmail dot com> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
                 CC|                            |ldionne.2 at gmail dot com

--- Comment #3 from Louis Dionne <ldionne.2 at gmail dot com> ---
I concur with the reporter of this issue. `bit_cast` requires the types to be
TriviallyCopyable. In turn, TriviallyCopyable requires (for class types) that
there's at least one eligible copy constructor, move constructor, copy
assignment operator, or move assignment operator. It doesn't say which of those
has to be valid, but at least one of those has to be valid.

However, GCC's implementation of __builtin_bit_cast seems to always require at
least a copy or a move constructor, which seems like a bug to me.

For example, the following code should be valid IIUC, but it fails with GCC:

  struct CopyAssignable {
    CopyAssignable() = default;
    int value = 0;

    CopyAssignable(const CopyAssignable&)            = delete;
    CopyAssignable(CopyAssignable&&)                 = delete;
    CopyAssignable& operator=(const CopyAssignable&) = default;
    CopyAssignable& operator=(CopyAssignable&&)      = delete;
  };

  struct MoveAssignable {
    MoveAssignable() = default;
    int value = 0;

    MoveAssignable(const MoveAssignable&)            = delete;
    MoveAssignable(MoveAssignable&&)                 = delete;
    MoveAssignable& operator=(const MoveAssignable&) = delete;
    MoveAssignable& operator=(MoveAssignable&&)      = default;
  };

  int main(int, char**) {
    CopyAssignable foo1;
    (void)__builtin_bit_cast(CopyAssignable, foo1); // doesn't work
    MoveAssignable foo2;
    (void)__builtin_bit_cast(MoveAssignable, foo2); // doesn't work
  }

Full example on Godbolt showing that this is accepted by Clang and MSVC but
rejected by GCC: https://godbolt.org/z/548YKndrK
I am running into this issue while trying to fix something in libc++ here:
https://reviews.llvm.org/D154613

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

* [Bug c++/103511] __builtin_bit_cast requires a constructor call
  2021-12-01  3:46 [Bug c++/103511] New: __builtin_bit_cast requires a constructor call de34 at live dot cn
                   ` (2 preceding siblings ...)
  2023-07-07 17:19 ` ldionne.2 at gmail dot com
@ 2023-07-07 17:21 ` jakub at gcc dot gnu.org
  2023-07-07 21:08 ` ldionne.2 at gmail dot com
  2024-04-14 19:22 ` pinskia at gcc dot gnu.org
  5 siblings, 0 replies; 7+ messages in thread
From: jakub at gcc dot gnu.org @ 2023-07-07 17:21 UTC (permalink / raw)
  To: gcc-bugs

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

--- Comment #4 from Jakub Jelinek <jakub at gcc dot gnu.org> ---
Jason, your call on this?

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

* [Bug c++/103511] __builtin_bit_cast requires a constructor call
  2021-12-01  3:46 [Bug c++/103511] New: __builtin_bit_cast requires a constructor call de34 at live dot cn
                   ` (3 preceding siblings ...)
  2023-07-07 17:21 ` jakub at gcc dot gnu.org
@ 2023-07-07 21:08 ` ldionne.2 at gmail dot com
  2024-04-14 19:22 ` pinskia at gcc dot gnu.org
  5 siblings, 0 replies; 7+ messages in thread
From: ldionne.2 at gmail dot com @ 2023-07-07 21:08 UTC (permalink / raw)
  To: gcc-bugs

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

--- Comment #5 from Louis Dionne <ldionne.2 at gmail dot com> ---
Note that my claim about TriviallyCopyable is taken from the Standard here, for
reference (even though Jason probably knows this by heart :-).

https://eel.is/c++draft/class.prop#1:

> A trivially copyable class is a class:
> (1.1) that has at least one eligible copy constructor, move constructor, copy assignment operator, or move assignment operator ([special], [class.copy.ctor], [class.copy.assign]),
> (1.2) where each eligible copy constructor, move constructor, copy assignment operator, and move assignment operator is trivial, and
> (1.3) that has a trivial, non-deleted destructor ([class.dtor]).

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

* [Bug c++/103511] __builtin_bit_cast requires a constructor call
  2021-12-01  3:46 [Bug c++/103511] New: __builtin_bit_cast requires a constructor call de34 at live dot cn
                   ` (4 preceding siblings ...)
  2023-07-07 21:08 ` ldionne.2 at gmail dot com
@ 2024-04-14 19:22 ` pinskia at gcc dot gnu.org
  5 siblings, 0 replies; 7+ messages in thread
From: pinskia at gcc dot gnu.org @ 2024-04-14 19:22 UTC (permalink / raw)
  To: gcc-bugs

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

Andrew Pinski <pinskia at gcc dot gnu.org> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
   Last reconfirmed|                            |2024-04-14
             Status|UNCONFIRMED                 |NEW
     Ever confirmed|0                           |1

--- Comment #6 from Andrew Pinski <pinskia at gcc dot gnu.org> ---
Confirmed. Both clang and MSVC accept this.

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

end of thread, other threads:[~2024-04-14 19:22 UTC | newest]

Thread overview: 7+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2021-12-01  3:46 [Bug c++/103511] New: __builtin_bit_cast requires a constructor call de34 at live dot cn
2021-12-01  8:35 ` [Bug c++/103511] " redi at gcc dot gnu.org
2021-12-01 11:03 ` jakub at gcc dot gnu.org
2023-07-07 17:19 ` ldionne.2 at gmail dot com
2023-07-07 17:21 ` jakub at gcc dot gnu.org
2023-07-07 21:08 ` ldionne.2 at gmail dot com
2024-04-14 19:22 ` pinskia 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).