public inbox for gcc-bugs@sourceware.org
help / color / mirror / Atom feed
* [Bug c++/114536] New: wrong constant evaluation of std::bit_cast for bit fields
@ 2024-03-31 10:13 fchelnokov at gmail dot com
  2024-03-31 10:19 ` [Bug c++/114536] " pinskia at gcc dot gnu.org
                   ` (6 more replies)
  0 siblings, 7 replies; 8+ messages in thread
From: fchelnokov at gmail dot com @ 2024-03-31 10:13 UTC (permalink / raw)
  To: gcc-bugs

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

            Bug ID: 114536
           Summary: wrong constant evaluation of std::bit_cast for bit
                    fields
           Product: gcc
           Version: 13.2.1
            Status: UNCONFIRMED
          Severity: normal
          Priority: P3
         Component: c++
          Assignee: unassigned at gcc dot gnu.org
          Reporter: fchelnokov at gmail dot com
  Target Milestone: ---

In this program


#include <bit>

struct A { unsigned char a: 7; };

struct B { unsigned char b; };

// fails in GCC
static_assert( std::bit_cast<B>(A{1}).b == 1 );

int main() {
    // correctly returns 1 in GCC
    return std::bit_cast<B>(A{1}).b;
}


static_assert fails with the message:

note: the comparison reduces to '(0 == 1)'

which contradicts runtime evaluation of the same expression. Online demo:
https://gcc.godbolt.org/z/fza4zas3E

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

* [Bug c++/114536] wrong constant evaluation of std::bit_cast for bit fields
  2024-03-31 10:13 [Bug c++/114536] New: wrong constant evaluation of std::bit_cast for bit fields fchelnokov at gmail dot com
@ 2024-03-31 10:19 ` pinskia at gcc dot gnu.org
  2024-03-31 10:22 ` fchelnokov at gmail dot com
                   ` (5 subsequent siblings)
  6 siblings, 0 replies; 8+ messages in thread
From: pinskia at gcc dot gnu.org @ 2024-03-31 10:19 UTC (permalink / raw)
  To: gcc-bugs

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

--- Comment #1 from Andrew Pinski <pinskia at gcc dot gnu.org> ---
So in the case of bitfields there is a padding bit(s) which are still
uninitialized and this might be undefined at runtime even.

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

* [Bug c++/114536] wrong constant evaluation of std::bit_cast for bit fields
  2024-03-31 10:13 [Bug c++/114536] New: wrong constant evaluation of std::bit_cast for bit fields fchelnokov at gmail dot com
  2024-03-31 10:19 ` [Bug c++/114536] " pinskia at gcc dot gnu.org
@ 2024-03-31 10:22 ` fchelnokov at gmail dot com
  2024-03-31 10:25 ` pinskia at gcc dot gnu.org
                   ` (4 subsequent siblings)
  6 siblings, 0 replies; 8+ messages in thread
From: fchelnokov at gmail dot com @ 2024-03-31 10:22 UTC (permalink / raw)
  To: gcc-bugs

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

--- Comment #2 from Fedor Chelnokov <fchelnokov at gmail dot com> ---
May be just fail constant evaluation then instead of evaluating it to 0?

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

* [Bug c++/114536] wrong constant evaluation of std::bit_cast for bit fields
  2024-03-31 10:13 [Bug c++/114536] New: wrong constant evaluation of std::bit_cast for bit fields fchelnokov at gmail dot com
  2024-03-31 10:19 ` [Bug c++/114536] " pinskia at gcc dot gnu.org
  2024-03-31 10:22 ` fchelnokov at gmail dot com
@ 2024-03-31 10:25 ` pinskia at gcc dot gnu.org
  2024-03-31 10:26 ` redi at gcc dot gnu.org
                   ` (3 subsequent siblings)
  6 siblings, 0 replies; 8+ messages in thread
From: pinskia at gcc dot gnu.org @ 2024-03-31 10:25 UTC (permalink / raw)
  To: gcc-bugs

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

--- Comment #3 from Andrew Pinski <pinskia at gcc dot gnu.org> ---
(In reply to Fedor Chelnokov from comment #2)
> May be just fail constant evaluation then instead of evaluating it to 0?

I suspect gcc is not rejecting it because the struct is just one unsigned char
and it is getting confused between that and the unsigned char.

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

* [Bug c++/114536] wrong constant evaluation of std::bit_cast for bit fields
  2024-03-31 10:13 [Bug c++/114536] New: wrong constant evaluation of std::bit_cast for bit fields fchelnokov at gmail dot com
                   ` (2 preceding siblings ...)
  2024-03-31 10:25 ` pinskia at gcc dot gnu.org
@ 2024-03-31 10:26 ` redi at gcc dot gnu.org
  2024-03-31 10:27 ` redi at gcc dot gnu.org
                   ` (2 subsequent siblings)
  6 siblings, 0 replies; 8+ messages in thread
From: redi at gcc dot gnu.org @ 2024-03-31 10:26 UTC (permalink / raw)
  To: gcc-bugs

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

--- Comment #4 from Jonathan Wakely <redi at gcc dot gnu.org> ---
The padding bit has an indeterminate value. Because the result type is an
unsigned char, the indeterminate bit does not produce undefined behaviour, but
it's not allowed in a constant expression.

I don't think this is a bug.

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

* [Bug c++/114536] wrong constant evaluation of std::bit_cast for bit fields
  2024-03-31 10:13 [Bug c++/114536] New: wrong constant evaluation of std::bit_cast for bit fields fchelnokov at gmail dot com
                   ` (3 preceding siblings ...)
  2024-03-31 10:26 ` redi at gcc dot gnu.org
@ 2024-03-31 10:27 ` redi at gcc dot gnu.org
  2024-03-31 19:28 ` pinskia at gcc dot gnu.org
  2024-04-03 15:41 ` jakub at gcc dot gnu.org
  6 siblings, 0 replies; 8+ messages in thread
From: redi at gcc dot gnu.org @ 2024-03-31 10:27 UTC (permalink / raw)
  To: gcc-bugs

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

--- Comment #5 from Jonathan Wakely <redi at gcc dot gnu.org> ---
(In reply to Fedor Chelnokov from comment #2)
> May be just fail constant evaluation then instead of evaluating it to 0?

Hmm, yes, it should fail to produce a constant expression.

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

* [Bug c++/114536] wrong constant evaluation of std::bit_cast for bit fields
  2024-03-31 10:13 [Bug c++/114536] New: wrong constant evaluation of std::bit_cast for bit fields fchelnokov at gmail dot com
                   ` (4 preceding siblings ...)
  2024-03-31 10:27 ` redi at gcc dot gnu.org
@ 2024-03-31 19:28 ` pinskia at gcc dot gnu.org
  2024-04-03 15:41 ` jakub at gcc dot gnu.org
  6 siblings, 0 replies; 8+ messages in thread
From: pinskia at gcc dot gnu.org @ 2024-03-31 19:28 UTC (permalink / raw)
  To: gcc-bugs

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

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

           What    |Removed                     |Added
----------------------------------------------------------------------------
             Status|UNCONFIRMED                 |NEW
   Last reconfirmed|                            |2024-03-31
     Ever confirmed|0                           |1

--- Comment #6 from Andrew Pinski <pinskia at gcc dot gnu.org> ---
Note you can't compare against clang though:
/opt/compiler-explorer/gcc-snapshot/lib/gcc/x86_64-linux-gnu/14.0.1/../../../../include/c++/14.0.1/bit:94:14:
note: constexpr bit_cast involving bit-field is not yet supported


But anyways with the padding bit.

With signed char instead of unsigned char, GCC gives:
```
/opt/compiler-explorer/gcc-trunk-20240331/include/c++/14.0.1/bit:94:33: error:
'__builtin_bit_cast' accessing uninitialized byte at offset 0

```

That is correct for that but in the case of unsigned char (or std::byte).

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

* [Bug c++/114536] wrong constant evaluation of std::bit_cast for bit fields
  2024-03-31 10:13 [Bug c++/114536] New: wrong constant evaluation of std::bit_cast for bit fields fchelnokov at gmail dot com
                   ` (5 preceding siblings ...)
  2024-03-31 19:28 ` pinskia at gcc dot gnu.org
@ 2024-04-03 15:41 ` jakub at gcc dot gnu.org
  6 siblings, 0 replies; 8+ messages in thread
From: jakub at gcc dot gnu.org @ 2024-04-03 15:41 UTC (permalink / raw)
  To: gcc-bugs

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

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,
                   |                            |redi at gcc dot gnu.org

--- Comment #7 from Jakub Jelinek <jakub at gcc dot gnu.org> ---
Adjusted testcase:
namespace std {
template<typename T, typename F>
constexpr T
bit_cast (const F& f) noexcept
{
  return __builtin_bit_cast (T, f);
}
}

struct A { unsigned char a : 7; };
struct B { unsigned char b; };
constexpr unsigned char c = __builtin_bit_cast (B, A{1}).b;
constexpr unsigned char d = std::bit_cast <B> (A{1}).b;

This shows that we diagnose correctly the c case:
pr114536.C:12:58: error: accessing uninitialized member ‘B::b’
   12 | constexpr unsigned char c = __builtin_bit_cast (B, A{1}).b;
      |                                                 ~~~~~~~~~^
but don't diagnose when the builtin call is wrapped in another call
(std::bit_cast).
The reason for that is:
  /* The result of a constexpr function must be completely initialized.

     However, in C++20, a constexpr constructor doesn't necessarily have
     to initialize all the fields, so we don't clear CONSTRUCTOR_NO_CLEARING
     in order to detect reading an unitialized object in constexpr instead
     of value-initializing it.  (reduced_constant_expression_p is expected to
     take care of clearing the flag.)  */
  if (TREE_CODE (result) == CONSTRUCTOR
      && (cxx_dialect < cxx20
          || !DECL_CONSTRUCTOR_P (fun)))
    clear_no_implicit_zero (result);
hunk in cxx_eval_call_expression.

This is done there since PR80829 for the nested CONSTRUCTOR_NO_CLEARING, and on
the outermost since r7-4090-gf64e0c029c452c9fc508adebf18d0ceb3ffdc066.
If it is UB to return not completely initialized aggregate, shouldn't
clear_no_implicit_zero actually diagnose it if CONSTRUCTOR_NO_CLEARING is set
and not all ctor elements are initialized?

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

end of thread, other threads:[~2024-04-03 15:41 UTC | newest]

Thread overview: 8+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2024-03-31 10:13 [Bug c++/114536] New: wrong constant evaluation of std::bit_cast for bit fields fchelnokov at gmail dot com
2024-03-31 10:19 ` [Bug c++/114536] " pinskia at gcc dot gnu.org
2024-03-31 10:22 ` fchelnokov at gmail dot com
2024-03-31 10:25 ` pinskia at gcc dot gnu.org
2024-03-31 10:26 ` redi at gcc dot gnu.org
2024-03-31 10:27 ` redi at gcc dot gnu.org
2024-03-31 19:28 ` pinskia at gcc dot gnu.org
2024-04-03 15:41 ` jakub 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).