public inbox for gcc-bugs@sourceware.org
help / color / mirror / Atom feed
From: "jakub at gcc dot gnu.org" <gcc-bugzilla@gcc.gnu.org>
To: gcc-bugs@gcc.gnu.org
Subject: [Bug c++/102490] Erroneous optimization of default constexpr operator== of struct with bitfields
Date: Mon, 27 Sep 2021 11:33:34 +0000	[thread overview]
Message-ID: <bug-102490-4-ns3z67jKH7@http.gcc.gnu.org/bugzilla/> (raw)
In-Reply-To: <bug-102490-4@http.gcc.gnu.org/bugzilla/>

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

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

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

--- Comment #2 from Jakub Jelinek <jakub at gcc dot gnu.org> ---
The bug is that the operator== is synthetized before the bitfields are adjusted
to the middle-end way, but assumes they are already adjusted that way.
In particular, the synthetization is done from:
#8  0x0000000000c8fe64 in build_comparison_op (fndecl=<function_decl
0x7fffea1a5500 operator==>, complain=0) at ../../gcc/cp/method.c:1454
#9  0x0000000000c91895 in synthesize_method (fndecl=<function_decl
0x7fffea1a5500 operator==>) at ../../gcc/cp/method.c:1779
#10 0x0000000000c98e1a in defaulted_late_check (fn=<function_decl
0x7fffea1a5500 operator==>) at ../../gcc/cp/method.c:3168
#11 0x0000000000b10439 in check_bases_and_members (t=<record_type
0x7fffea1a1b28 A>) at ../../gcc/cp/class.c:6136
#12 0x0000000000b161c8 in finish_struct_1 (t=<record_type 0x7fffea1a1b28 A>) at
../../gcc/cp/class.c:7372
#13 0x0000000000b17d3d in finish_struct (t=<record_type 0x7fffea1a1b28 A>,
attributes=<tree 0x0>) at ../../gcc/cp/class.c:7668
but the bitfields are adjusted in
#0  layout_class_type (t=<record_type 0x7fffea1a1b28 A>,
virtuals_p=0x7fffffffcef0) at ../../gcc/cp/class.c:6711
#1  0x0000000000b162ae in finish_struct_1 (t=<record_type 0x7fffea1a1b28 A>) at
../../gcc/cp/class.c:7397
#2  0x0000000000b17d3d in finish_struct (t=<record_type 0x7fffea1a1b28 A>,
attributes=<tree 0x0>) at ../../gcc/cp/class.c:7668
So, we emit e.g. the COMPONENT_REFs with the underlying bitfield type, but then
layout_class_type changes the type of the FIELD_DECLs to something else and
we'd 
instead want to either compare in the actual bitfield types, or on NOP_EXPRs
from the COMPONENT_REFs to the underlying type.

So, either build_comparison_op should check for DECL_C_BIT_FIELD fields whether
TREE_TYPE of the field has the DECL_SIZE precision or not (but we'd also need
to handle there e.g. the
      /* If this field is a bit-field whose width is greater than its
         type, then there are some special rules for allocating
         it.  */
      if (DECL_C_BIT_FIELD (field)
          && tree_int_cst_lt (TYPE_SIZE (type), DECL_SIZE (field)))
stuff from layout_class_type (as well as the:
      /* The middle end uses the type of expressions to determine the
         possible range of expression values.  In order to optimize
         "x.i > 7" to "false" for a 2-bit bitfield "i", the middle end
         must be made aware of the width of "i", via its type.

         Because C++ does not have integer types of arbitrary width,
         we must (for the purposes of the front end) convert from the
         type assigned here to the declared type of the bitfield
         whenever a bitfield expression is used as an rvalue.
         Similarly, when assigning a value to a bitfield, the value
         must be converted to the type given the bitfield here.  */
      if (DECL_C_BIT_FIELD (field))
), or we need to somehow make sure that the == and <=> methods are synthetized
only after that happens.  Jason, thoughts on that?

Also, wonder about :0 bitfields in classes that have defaulted comparisons...

  parent reply	other threads:[~2021-09-27 11:33 UTC|newest]

Thread overview: 8+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2021-09-26 11:31 [Bug c++/102490] New: " luc.briand35 at gmail dot com
2021-09-27 10:16 ` [Bug c++/102490] " jakub at gcc dot gnu.org
2021-09-27 11:33 ` jakub at gcc dot gnu.org [this message]
2021-09-27 11:37 ` pinskia at gcc dot gnu.org
2021-09-27 12:38 ` jakub at gcc dot gnu.org
2021-10-05 17:15 ` jakub at gcc dot gnu.org
2021-10-06  2:41 ` cvs-commit at gcc dot gnu.org
2022-11-03 21:18 ` ppalka at gcc dot gnu.org

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=bug-102490-4-ns3z67jKH7@http.gcc.gnu.org/bugzilla/ \
    --to=gcc-bugzilla@gcc.gnu.org \
    --cc=gcc-bugs@gcc.gnu.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
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).