1
1
use std:: iter;
2
2
use std:: ops:: ControlFlow ;
3
3
4
- use rustc_abi:: { BackendRepr , TagEncoding , VariantIdx , Variants , WrappingRange } ;
4
+ use rustc_abi:: { BackendRepr , TagEncoding , Variants , WrappingRange } ;
5
5
use rustc_data_structures:: fx:: FxHashSet ;
6
6
use rustc_errors:: DiagMessage ;
7
7
use rustc_hir:: intravisit:: VisitorExt ;
8
8
use rustc_hir:: { AmbigArg , Expr , ExprKind , HirId , LangItem } ;
9
9
use rustc_middle:: bug;
10
10
use rustc_middle:: ty:: layout:: { LayoutOf , SizeSkeleton } ;
11
11
use rustc_middle:: ty:: {
12
- self , Adt , AdtKind , GenericArgsRef , Ty , TyCtxt , TypeSuperVisitable , TypeVisitable ,
12
+ self , AdtKind , GenericArgsRef , Ty , TyCtxt , TypeSuperVisitable , TypeVisitable ,
13
13
TypeVisitableExt ,
14
14
} ;
15
15
use rustc_session:: { declare_lint, declare_lint_pass, impl_lint_pass} ;
@@ -26,7 +26,7 @@ use crate::lints::{
26
26
AmbiguousWidePointerComparisonsExpectSuggestion , AtomicOrderingFence , AtomicOrderingLoad ,
27
27
AtomicOrderingStore , ImproperCTypes , InvalidAtomicOrderingDiag , InvalidNanComparisons ,
28
28
InvalidNanComparisonsSuggestion , UnpredictableFunctionPointerComparisons ,
29
- UnpredictableFunctionPointerComparisonsSuggestion , UnusedComparisons , UsesPowerAlignment ,
29
+ UnpredictableFunctionPointerComparisonsSuggestion , UnusedComparisons ,
30
30
VariantSizeDifferencesDiag ,
31
31
} ;
32
32
use crate :: { LateContext , LateLintPass , LintContext , fluent_generated as fluent} ;
@@ -752,62 +752,7 @@ declare_lint! {
752
752
"proper use of libc types in foreign item definitions"
753
753
}
754
754
755
- declare_lint ! {
756
- /// The `uses_power_alignment` lint detects specific `repr(C)`
757
- /// aggregates on AIX.
758
- /// In its platform C ABI, AIX uses the "power" (as in PowerPC) alignment
759
- /// rule (detailed in https://www.ibm.com/docs/en/xl-c-and-cpp-aix/16.1?topic=data-using-alignment-modes#alignment),
760
- /// which can also be set for XLC by `#pragma align(power)` or
761
- /// `-qalign=power`. Aggregates with a floating-point type as the
762
- /// recursively first field (as in "at offset 0") modify the layout of
763
- /// *subsequent* fields of the associated structs to use an alignment value
764
- /// where the floating-point type is aligned on a 4-byte boundary.
765
- ///
766
- /// Effectively, subsequent floating-point fields act as-if they are `repr(packed(4))`. This
767
- /// would be unsound to do in a `repr(C)` type without all the restrictions that come with
768
- /// `repr(packed)`. Rust instead chooses a layout that maintains soundness of Rust code, at the
769
- /// expense of incompatibility with C code.
770
- ///
771
- /// ### Example
772
- ///
773
- /// ```rust,ignore (fails on non-powerpc64-ibm-aix)
774
- /// #[repr(C)]
775
- /// pub struct Floats {
776
- /// a: f64,
777
- /// b: u8,
778
- /// c: f64,
779
- /// }
780
- /// ```
781
- ///
782
- /// This will produce:
783
- ///
784
- /// ```text
785
- /// warning: repr(C) does not follow the power alignment rule. This may affect platform C ABI compatibility for this type
786
- /// --> <source>:5:3
787
- /// |
788
- /// 5 | c: f64,
789
- /// | ^^^^^^
790
- /// |
791
- /// = note: `#[warn(uses_power_alignment)]` on by default
792
- /// ```
793
- ///
794
- /// ### Explanation
795
- ///
796
- /// The power alignment rule specifies that the above struct has the
797
- /// following alignment:
798
- /// - offset_of!(Floats, a) == 0
799
- /// - offset_of!(Floats, b) == 8
800
- /// - offset_of!(Floats, c) == 12
801
- ///
802
- /// However, Rust currently aligns `c` at `offset_of!(Floats, c) == 16`.
803
- /// Using offset 12 would be unsound since `f64` generally must be 8-aligned on this target.
804
- /// Thus, a warning is produced for the above struct.
805
- USES_POWER_ALIGNMENT ,
806
- Warn ,
807
- "Structs do not follow the power alignment rule under repr(C)"
808
- }
809
-
810
- declare_lint_pass ! ( ImproperCTypesDefinitions => [ IMPROPER_CTYPES_DEFINITIONS , USES_POWER_ALIGNMENT ] ) ;
755
+ declare_lint_pass ! ( ImproperCTypesDefinitions => [ IMPROPER_CTYPES_DEFINITIONS ] ) ;
811
756
812
757
#[ derive( Clone , Copy ) ]
813
758
pub ( crate ) enum CItemKind {
@@ -1647,68 +1592,6 @@ impl ImproperCTypesDefinitions {
1647
1592
vis. check_type_for_ffi_and_report_errors ( span, fn_ptr_ty, true , false ) ;
1648
1593
}
1649
1594
}
1650
-
1651
- fn check_arg_for_power_alignment < ' tcx > (
1652
- & mut self ,
1653
- cx : & LateContext < ' tcx > ,
1654
- ty : Ty < ' tcx > ,
1655
- ) -> bool {
1656
- assert ! ( cx. tcx. sess. target. os == "aix" ) ;
1657
- // Structs (under repr(C)) follow the power alignment rule if:
1658
- // - the first field of the struct is a floating-point type that
1659
- // is greater than 4-bytes, or
1660
- // - the first field of the struct is an aggregate whose
1661
- // recursively first field is a floating-point type greater than
1662
- // 4 bytes.
1663
- if ty. is_floating_point ( ) && ty. primitive_size ( cx. tcx ) . bytes ( ) > 4 {
1664
- return true ;
1665
- } else if let Adt ( adt_def, _) = ty. kind ( )
1666
- && adt_def. is_struct ( )
1667
- && adt_def. repr ( ) . c ( )
1668
- && !adt_def. repr ( ) . packed ( )
1669
- && adt_def. repr ( ) . align . is_none ( )
1670
- {
1671
- let struct_variant = adt_def. variant ( VariantIdx :: ZERO ) ;
1672
- // Within a nested struct, all fields are examined to correctly
1673
- // report if any fields after the nested struct within the
1674
- // original struct are misaligned.
1675
- for struct_field in & struct_variant. fields {
1676
- let field_ty = cx. tcx . type_of ( struct_field. did ) . instantiate_identity ( ) ;
1677
- if self . check_arg_for_power_alignment ( cx, field_ty) {
1678
- return true ;
1679
- }
1680
- }
1681
- }
1682
- return false ;
1683
- }
1684
-
1685
- fn check_struct_for_power_alignment < ' tcx > (
1686
- & mut self ,
1687
- cx : & LateContext < ' tcx > ,
1688
- item : & ' tcx hir:: Item < ' tcx > ,
1689
- ) {
1690
- let adt_def = cx. tcx . adt_def ( item. owner_id . to_def_id ( ) ) ;
1691
- // repr(C) structs also with packed or aligned representation
1692
- // should be ignored.
1693
- if adt_def. repr ( ) . c ( )
1694
- && !adt_def. repr ( ) . packed ( )
1695
- && adt_def. repr ( ) . align . is_none ( )
1696
- && cx. tcx . sess . target . os == "aix"
1697
- && !adt_def. all_fields ( ) . next ( ) . is_none ( )
1698
- {
1699
- let struct_variant_data = item. expect_struct ( ) . 2 ;
1700
- for field_def in struct_variant_data. fields ( ) . iter ( ) . skip ( 1 ) {
1701
- // Struct fields (after the first field) are checked for the
1702
- // power alignment rule, as fields after the first are likely
1703
- // to be the fields that are misaligned.
1704
- let def_id = field_def. def_id ;
1705
- let ty = cx. tcx . type_of ( def_id) . instantiate_identity ( ) ;
1706
- if self . check_arg_for_power_alignment ( cx, ty) {
1707
- cx. emit_span_lint ( USES_POWER_ALIGNMENT , field_def. span , UsesPowerAlignment ) ;
1708
- }
1709
- }
1710
- }
1711
- }
1712
1595
}
1713
1596
1714
1597
/// `ImproperCTypesDefinitions` checks items outside of foreign items (e.g. stuff that isn't in
@@ -1732,11 +1615,7 @@ impl<'tcx> LateLintPass<'tcx> for ImproperCTypesDefinitions {
1732
1615
}
1733
1616
// See `check_fn`..
1734
1617
hir:: ItemKind :: Fn { .. } => { }
1735
- // Structs are checked based on if they follow the power alignment
1736
- // rule (under repr(C)).
1737
- hir:: ItemKind :: Struct ( ..) => {
1738
- self . check_struct_for_power_alignment ( cx, item) ;
1739
- }
1618
+ hir:: ItemKind :: Struct ( ..) => { }
1740
1619
// See `check_field_def`..
1741
1620
hir:: ItemKind :: Union ( ..) | hir:: ItemKind :: Enum ( ..) => { }
1742
1621
// Doesn't define something that can contain a external type to be checked.
0 commit comments