11use std:: iter;
22use std:: ops:: ControlFlow ;
33
4- use rustc_abi:: { BackendRepr , TagEncoding , VariantIdx , Variants , WrappingRange } ;
4+ use rustc_abi:: { BackendRepr , TagEncoding , Variants , WrappingRange } ;
55use rustc_data_structures:: fx:: FxHashSet ;
66use rustc_errors:: DiagMessage ;
77use rustc_hir:: intravisit:: VisitorExt ;
88use rustc_hir:: { AmbigArg , Expr , ExprKind , HirId , LangItem } ;
99use rustc_middle:: bug;
1010use rustc_middle:: ty:: layout:: { LayoutOf , SizeSkeleton } ;
1111use rustc_middle:: ty:: {
12- self , Adt , AdtKind , GenericArgsRef , Ty , TyCtxt , TypeSuperVisitable , TypeVisitable ,
13- TypeVisitableExt ,
12+ self , AdtKind , GenericArgsRef , Ty , TyCtxt , TypeSuperVisitable , TypeVisitable , TypeVisitableExt ,
1413} ;
1514use rustc_session:: { declare_lint, declare_lint_pass, impl_lint_pass} ;
1615use rustc_span:: def_id:: LocalDefId ;
@@ -26,7 +25,7 @@ use crate::lints::{
2625 AmbiguousWidePointerComparisonsExpectSuggestion , AtomicOrderingFence , AtomicOrderingLoad ,
2726 AtomicOrderingStore , ImproperCTypes , InvalidAtomicOrderingDiag , InvalidNanComparisons ,
2827 InvalidNanComparisonsSuggestion , UnpredictableFunctionPointerComparisons ,
29- UnpredictableFunctionPointerComparisonsSuggestion , UnusedComparisons , UsesPowerAlignment ,
28+ UnpredictableFunctionPointerComparisonsSuggestion , UnusedComparisons ,
3029 VariantSizeDifferencesDiag ,
3130} ;
3231use crate :: { LateContext , LateLintPass , LintContext , fluent_generated as fluent} ;
@@ -752,62 +751,7 @@ declare_lint! {
752751 "proper use of libc types in foreign item definitions"
753752}
754753
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 ] ) ;
754+ declare_lint_pass ! ( ImproperCTypesDefinitions => [ IMPROPER_CTYPES_DEFINITIONS ] ) ;
811755
812756#[ derive( Clone , Copy ) ]
813757pub ( crate ) enum CItemKind {
@@ -1647,68 +1591,6 @@ impl ImproperCTypesDefinitions {
16471591 vis. check_type_for_ffi_and_report_errors ( span, fn_ptr_ty, true , false ) ;
16481592 }
16491593 }
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- }
17121594}
17131595
17141596/// `ImproperCTypesDefinitions` checks items outside of foreign items (e.g. stuff that isn't in
@@ -1732,11 +1614,7 @@ impl<'tcx> LateLintPass<'tcx> for ImproperCTypesDefinitions {
17321614 }
17331615 // See `check_fn`..
17341616 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- }
1617+ hir:: ItemKind :: Struct ( ..) => { }
17401618 // See `check_field_def`..
17411619 hir:: ItemKind :: Union ( ..) | hir:: ItemKind :: Enum ( ..) => { }
17421620 // Doesn't define something that can contain a external type to be checked.
0 commit comments