@@ -248,16 +248,36 @@ fn sanity_check_layout<'tcx>(
248
248
"size mismatch between ABI and layout in {layout:#?}"
249
249
);*/
250
250
}
251
+ Abi :: Vector { count, element } => {
252
+ // No padding in vectors. Alignment can be strengthened, though.
253
+ assert ! (
254
+ layout. align( ) . abi >= element. align( & tcx) . abi,
255
+ "alignment mismatch between ABI and layout in {layout:#?}"
256
+ ) ;
257
+ let size = element. size ( & tcx) * count;
258
+ assert_eq ! (
259
+ layout. size( ) ,
260
+ size. align_to( tcx. data_layout( ) . vector_align( size) . abi) ,
261
+ "size mismatch between ABI and layout in {layout:#?}"
262
+ ) ;
263
+ }
251
264
Abi :: ScalarPair ( scalar1, scalar2) => {
252
- // Sanity-check scalar pair size.
253
- let field2_offset = scalar1. size ( & tcx) . align_to ( scalar2. align ( & tcx) . abi ) ;
254
- let total = field2_offset + scalar2. size ( & tcx) ;
265
+ // Sanity-check scalar pairs. These are a bit more flexible and support
266
+ // padding, but we can at least ensure both fields actually fit into the layout
267
+ // and the alignment requirement has not been weakened.
268
+ let align1 = scalar1. align ( & tcx) . abi ;
269
+ let align2 = scalar2. align ( & tcx) . abi ;
255
270
assert ! (
256
- layout. size( ) >= total,
271
+ layout. align( ) . abi >= cmp:: max( align1, align2) ,
272
+ "alignment mismatch between ABI and layout in {layout:#?}" ,
273
+ ) ;
274
+ let field2_offset = scalar1. size ( & tcx) . align_to ( align2) ;
275
+ assert ! (
276
+ layout. size( ) >= field2_offset + scalar2. size( & tcx) ,
257
277
"size mismatch between ABI and layout in {layout:#?}"
258
278
) ;
259
279
}
260
- _ => { }
280
+ Abi :: Uninhabited | Abi :: Aggregate { .. } => { } // Nothing to check.
261
281
}
262
282
}
263
283
@@ -1401,16 +1421,6 @@ impl<'tcx> LayoutCx<'tcx, TyCtxt<'tcx>> {
1401
1421
// Without latter check aligned enums with custom discriminant values
1402
1422
// Would result in ICE see the issue #92464 for more info
1403
1423
abi = Abi :: Scalar ( tag) ;
1404
- // Make sure the variants with fields have the same ABI as the enum itself
1405
- // (since downcasting to them is a NOP).
1406
- for variant in & mut layout_variants {
1407
- if variant. fields . count ( ) > 0
1408
- && matches ! ( variant. abi, Abi :: Aggregate { .. } )
1409
- {
1410
- assert_eq ! ( variant. size, size) ;
1411
- variant. abi = abi;
1412
- }
1413
- }
1414
1424
} else {
1415
1425
// Try to use a ScalarPair for all tagged enums.
1416
1426
let mut common_prim = None ;
@@ -1479,17 +1489,24 @@ impl<'tcx> LayoutCx<'tcx, TyCtxt<'tcx>> {
1479
1489
// We can use `ScalarPair` only when it matches our
1480
1490
// already computed layout (including `#[repr(C)]`).
1481
1491
abi = pair. abi ;
1482
- // Make sure the variants with fields have the same ABI as the enum itself
1483
- // (since downcasting to them is a NOP).
1484
- for variant in & mut layout_variants {
1485
- if variant. fields . count ( ) > 0
1486
- && matches ! ( variant. abi, Abi :: Aggregate { .. } )
1487
- {
1488
- variant. abi = abi;
1489
- // Also need to bump up the size, so that the pair fits inside.
1490
- variant. size = size;
1491
- }
1492
- }
1492
+ }
1493
+ }
1494
+ }
1495
+
1496
+ // If we pick a "clever" (by-value) ABI, we might have to adjust the ABI of the
1497
+ // variants to ensure they are consistent. This is because a downcast is
1498
+ // semantically a NOP, and thus should not affect layout.
1499
+ if matches ! ( abi, Abi :: Scalar ( ..) | Abi :: ScalarPair ( ..) ) {
1500
+ for variant in & mut layout_variants {
1501
+ // We only do this for variants with fields; the others are not accessed anyway.
1502
+ // Also do not overwrite any already existing "clever" ABIs.
1503
+ if variant. fields . count ( ) > 0
1504
+ && matches ! ( variant. abi, Abi :: Aggregate { .. } )
1505
+ {
1506
+ variant. abi = abi;
1507
+ // Also need to bump up the size and alignment, so that the entire value fits in here.
1508
+ variant. size = cmp:: max ( variant. size , size) ;
1509
+ variant. align . abi = cmp:: max ( variant. align . abi , align. abi ) ;
1493
1510
}
1494
1511
}
1495
1512
}
0 commit comments