@@ -970,9 +970,39 @@ void c_typecheck_baset::typecheck_expr_sizeof(exprt &expr)
970
970
971
971
if (type.id ()==ID_c_bit_field)
972
972
{
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
+ }
976
1006
}
977
1007
else if (type.id () == ID_bool)
978
1008
{
@@ -1876,8 +1906,11 @@ void c_typecheck_baset::typecheck_expr_side_effect(side_effect_exprt &expr)
1876
1906
{
1877
1907
// promote to underlying type
1878
1908
typet underlying_type = to_c_bit_field_type (type0).underlying_type ();
1909
+ typet type_before{type0};
1879
1910
to_unary_expr (expr).op () = typecast_exprt (op0, underlying_type);
1880
1911
expr.type ()=underlying_type;
1912
+ typecast_exprt result{expr, type_before};
1913
+ expr.swap (result);
1881
1914
}
1882
1915
else if (type0.id () == ID_bool || type0.id () == ID_c_bool)
1883
1916
{
@@ -4345,10 +4378,11 @@ void c_typecheck_baset::typecheck_side_effect_assignment(
4345
4378
}
4346
4379
4347
4380
// 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
+ }
4352
4386
4353
4387
const typet o_type0=op0.type ();
4354
4388
const typet o_type1=op1.type ();
0 commit comments