@@ -418,6 +418,11 @@ impl Type {
418
418
}
419
419
}
420
420
421
+ pub fn is_bitfield ( & self ) -> bool {
422
+ let concrete = self . unwrap_typedef ( ) ;
423
+ matches ! ( concrete, CBitField { .. } )
424
+ }
425
+
421
426
pub fn is_bool ( & self ) -> bool {
422
427
let concrete = self . unwrap_typedef ( ) ;
423
428
match concrete {
@@ -1211,7 +1216,7 @@ impl Type {
1211
1216
}
1212
1217
1213
1218
pub fn one ( & self ) -> Expr {
1214
- if self . is_integer ( ) {
1219
+ if self . is_integer ( ) || self . is_bitfield ( ) {
1215
1220
Expr :: int_constant ( 1 , self . clone ( ) )
1216
1221
} else if self . is_c_bool ( ) {
1217
1222
Expr :: c_true ( )
@@ -1225,8 +1230,10 @@ impl Type {
1225
1230
}
1226
1231
1227
1232
pub fn zero ( & self ) -> Expr {
1228
- if self . is_integer ( ) {
1233
+ if self . is_integer ( ) || self . is_bitfield ( ) {
1229
1234
Expr :: int_constant ( 0 , self . clone ( ) )
1235
+ } else if self . is_bool ( ) {
1236
+ Expr :: bool_false ( )
1230
1237
} else if self . is_c_bool ( ) {
1231
1238
Expr :: c_false ( )
1232
1239
} else if self . is_float ( ) {
@@ -1236,7 +1243,63 @@ impl Type {
1236
1243
} else if self . is_pointer ( ) {
1237
1244
Expr :: pointer_constant ( 0 , self . clone ( ) )
1238
1245
} else {
1239
- unreachable ! ( "Can't convert {:?} to a one value" , self ) ;
1246
+ unreachable ! ( "Can't convert {:?} to a zero value" , self ) ;
1247
+ }
1248
+ }
1249
+
1250
+ pub fn zero_initializer ( & self , st : & SymbolTable ) -> Expr {
1251
+ let concrete = self . unwrap_typedef ( ) ;
1252
+ match concrete {
1253
+ // Base case
1254
+ Bool
1255
+ | CBitField { .. }
1256
+ | CInteger ( _)
1257
+ | Double
1258
+ | Float
1259
+ | Pointer { .. }
1260
+ | Signedbv { .. }
1261
+ | Unsignedbv { .. } => self . zero ( ) ,
1262
+
1263
+ // Recursive cases
1264
+ Array { typ, size } => typ. zero_initializer ( st) . array_constant ( * size) ,
1265
+ InfiniteArray { typ } => typ. zero_initializer ( st) . infinite_array_constant ( ) ,
1266
+ Struct { components, .. } => {
1267
+ let values: Vec < Expr > =
1268
+ components. iter ( ) . map ( |c| c. typ ( ) . zero_initializer ( st) ) . collect ( ) ;
1269
+ Expr :: struct_expr_from_padded_values ( self . clone ( ) , values, st)
1270
+ }
1271
+ StructTag ( tag) => st. lookup ( * tag) . unwrap ( ) . typ . zero_initializer ( st) ,
1272
+ TypeDef { .. } => unreachable ! ( "Should have been normalized away" ) ,
1273
+ Union { components, .. } => {
1274
+ if components. is_empty ( ) {
1275
+ Expr :: empty_union ( self . clone ( ) , st)
1276
+ } else {
1277
+ let largest = components. iter ( ) . max_by_key ( |c| c. sizeof_in_bits ( st) ) . unwrap ( ) ;
1278
+ Expr :: union_expr (
1279
+ self . clone ( ) ,
1280
+ largest. name ( ) ,
1281
+ largest. typ ( ) . zero_initializer ( st) ,
1282
+ st,
1283
+ )
1284
+ }
1285
+ }
1286
+ UnionTag ( tag) => st. lookup ( * tag) . unwrap ( ) . typ . zero_initializer ( st) ,
1287
+ Vector { typ, size } => {
1288
+ let zero = typ. zero_initializer ( st) ;
1289
+ let size = ( * size) . try_into ( ) . unwrap ( ) ;
1290
+ let elems = vec ! [ zero; size] ;
1291
+ Expr :: vector_expr ( self . clone ( ) , elems)
1292
+ }
1293
+
1294
+ // Cases that can't be zero init
1295
+ // Note that other than flexible array, none of these can be fields in a struct or union
1296
+ Code { .. }
1297
+ | Constructor
1298
+ | Empty
1299
+ | FlexibleArray { .. }
1300
+ | IncompleteStruct { .. }
1301
+ | IncompleteUnion { .. }
1302
+ | VariadicCode { .. } => panic ! ( "Can't zero init {:?}" , self ) ,
1240
1303
}
1241
1304
}
1242
1305
}
0 commit comments