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...