@@ -755,10 +755,10 @@ declare_lint! {
755
755
/// *subsequent* fields of the associated structs to use an alignment value
756
756
/// where the floating-point type is aligned on a 4-byte boundary.
757
757
///
758
- /// The power alignment rule for structs needed for C compatibility is
759
- /// unimplementable within `repr(C)` in the compiler without building in
760
- /// handling of references to packed fields and infectious nested layouts,
761
- /// so a warning is produced in these situations .
758
+ /// Effectively, subsequent floating-point fields act as-if they are `repr(packed(4))`. This
759
+ /// would be unsound to do in a `repr(C)` type without all the restrictions that come with
760
+ /// `repr(packed)`. Rust instead chooses a layout that maintains soundness of Rust code, at the
761
+ /// expense of incompatibility with C code .
762
762
///
763
763
/// ### Example
764
764
///
@@ -790,8 +790,10 @@ declare_lint! {
790
790
/// - offset_of!(Floats, a) == 0
791
791
/// - offset_of!(Floats, b) == 8
792
792
/// - offset_of!(Floats, c) == 12
793
- /// However, rust currently aligns `c` at offset_of!(Floats, c) == 16.
794
- /// Thus, a warning should be produced for the above struct in this case.
793
+ ///
794
+ /// However, Rust currently aligns `c` at `offset_of!(Floats, c) == 16`.
795
+ /// Using offset 12 would be unsound since `f64` generally must be 8-aligned on this target.
796
+ /// Thus, a warning is produced for the above struct.
795
797
USES_POWER_ALIGNMENT ,
796
798
Warn ,
797
799
"Structs do not follow the power alignment rule under repr(C)"
@@ -1655,15 +1657,13 @@ impl ImproperCTypesDefinitions {
1655
1657
cx : & LateContext < ' tcx > ,
1656
1658
ty : Ty < ' tcx > ,
1657
1659
) -> bool {
1660
+ assert ! ( cx. tcx. sess. target. os == "aix" ) ;
1658
1661
// Structs (under repr(C)) follow the power alignment rule if:
1659
1662
// - the first field of the struct is a floating-point type that
1660
1663
// is greater than 4-bytes, or
1661
1664
// - the first field of the struct is an aggregate whose
1662
1665
// recursively first field is a floating-point type greater than
1663
1666
// 4 bytes.
1664
- if cx. tcx . sess . target . os != "aix" {
1665
- return false ;
1666
- }
1667
1667
if ty. is_floating_point ( ) && ty. primitive_size ( cx. tcx ) . bytes ( ) > 4 {
1668
1668
return true ;
1669
1669
} else if let Adt ( adt_def, _) = ty. kind ( )
@@ -1701,21 +1701,14 @@ impl ImproperCTypesDefinitions {
1701
1701
&& !adt_def. all_fields ( ) . next ( ) . is_none ( )
1702
1702
{
1703
1703
let struct_variant_data = item. expect_struct ( ) . 1 ;
1704
- for ( index , .. ) in struct_variant_data. fields ( ) . iter ( ) . enumerate ( ) {
1704
+ for field_def in struct_variant_data. fields ( ) . iter ( ) . skip ( 1 ) {
1705
1705
// Struct fields (after the first field) are checked for the
1706
1706
// power alignment rule, as fields after the first are likely
1707
1707
// to be the fields that are misaligned.
1708
- if index != 0 {
1709
- let first_field_def = struct_variant_data. fields ( ) [ index] ;
1710
- let def_id = first_field_def. def_id ;
1711
- let ty = cx. tcx . type_of ( def_id) . instantiate_identity ( ) ;
1712
- if self . check_arg_for_power_alignment ( cx, ty) {
1713
- cx. emit_span_lint (
1714
- USES_POWER_ALIGNMENT ,
1715
- first_field_def. span ,
1716
- UsesPowerAlignment ,
1717
- ) ;
1718
- }
1708
+ let def_id = field_def. def_id ;
1709
+ let ty = cx. tcx . type_of ( def_id) . instantiate_identity ( ) ;
1710
+ if self . check_arg_for_power_alignment ( cx, ty) {
1711
+ cx. emit_span_lint ( USES_POWER_ALIGNMENT , field_def. span , UsesPowerAlignment ) ;
1719
1712
}
1720
1713
}
1721
1714
}
0 commit comments