@@ -970,9 +970,39 @@ void c_typecheck_baset::typecheck_expr_sizeof(exprt &expr)
970970
971971 if (type.id ()==ID_c_bit_field)
972972 {
973- error ().source_location = expr.source_location ();
974- error () << " sizeof cannot be applied to bit fields" << eom;
975- throw 0 ;
973+ // only comma or side-effect expressions are permitted
974+ const exprt &op = skip_typecast (to_unary_expr (as_const (expr)).op ());
975+ if (op.id () == ID_comma || op.id () == ID_side_effect)
976+ {
977+ const c_bit_field_typet &bf_type = to_c_bit_field_type (type);
978+ if (config.ansi_c .mode == configt::ansi_ct::flavourt::GCC)
979+ {
980+ new_expr = from_integer (
981+ (bf_type.get_width () + config.ansi_c .char_width - 1 ) /
982+ config.ansi_c .char_width ,
983+ size_type ());
984+ }
985+ else
986+ {
987+ auto size_of_opt = size_of_expr (bf_type.underlying_type (), *this );
988+
989+ if (!size_of_opt.has_value ())
990+ {
991+ error ().source_location = expr.source_location ();
992+ error () << " type has no size: "
993+ << to_string (bf_type.underlying_type ()) << eom;
994+ throw 0 ;
995+ }
996+
997+ new_expr = size_of_opt.value ();
998+ }
999+ }
1000+ else
1001+ {
1002+ error ().source_location = expr.source_location ();
1003+ error () << " sizeof cannot be applied to bit fields" << eom;
1004+ throw 0 ;
1005+ }
9761006 }
9771007 else if (type.id () == ID_bool)
9781008 {
@@ -1876,8 +1906,11 @@ void c_typecheck_baset::typecheck_expr_side_effect(side_effect_exprt &expr)
18761906 {
18771907 // promote to underlying type
18781908 typet underlying_type = to_c_bit_field_type (type0).underlying_type ();
1909+ typet type_before{type0};
18791910 to_unary_expr (expr).op () = typecast_exprt (op0, underlying_type);
18801911 expr.type ()=underlying_type;
1912+ typecast_exprt result{expr, type_before};
1913+ expr.swap (result);
18811914 }
18821915 else if (type0.id () == ID_bool || type0.id () == ID_c_bool)
18831916 {
@@ -4345,10 +4378,11 @@ void c_typecheck_baset::typecheck_side_effect_assignment(
43454378 }
43464379
43474380 // Add a cast to the underlying type for bit fields.
4348- // In particular, sizeof(s.f=1) works for bit fields.
4349- if (op0.type ().id ()==ID_c_bit_field)
4350- op0 =
4351- typecast_exprt (op0, to_c_bit_field_type (op0.type ()).underlying_type ());
4381+ if (op0.type () != op1.type () && op0.type ().id () == ID_c_bit_field)
4382+ {
4383+ op1 =
4384+ typecast_exprt{op1, to_c_bit_field_type (op0.type ()).underlying_type ()};
4385+ }
43524386
43534387 const typet o_type0=op0.type ();
43544388 const typet o_type1=op1.type ();
0 commit comments