Skip to content

Commit e9a1003

Browse files
compiler: Remove power alignment lint
This lint was based on a false premise: LLVM lacks a correct datalayout, but rustc assumed that the AIX datalayout was correct.
1 parent c6a9554 commit e9a1003

File tree

3 files changed

+5
-132
lines changed

3 files changed

+5
-132
lines changed

compiler/rustc_lint/messages.ftl

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1017,7 +1017,5 @@ lint_useless_ptr_null_checks_fn_ret = returned pointer of `{$fn_name}` call is n
10171017
lint_useless_ptr_null_checks_ref = references are not nullable, so checking them for null will always return false
10181018
.label = expression has type `{$orig_ty}`
10191019
1020-
lint_uses_power_alignment = repr(C) does not follow the power alignment rule. This may affect platform C ABI compatibility for this type
1021-
10221020
lint_variant_size_differences =
10231021
enum variant is more than three times larger ({$largest} bytes) than the next largest

compiler/rustc_lint/src/lints.rs

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1741,10 +1741,6 @@ pub(crate) struct OverflowingLiteral<'a> {
17411741
pub lit: String,
17421742
}
17431743

1744-
#[derive(LintDiagnostic)]
1745-
#[diag(lint_uses_power_alignment)]
1746-
pub(crate) struct UsesPowerAlignment;
1747-
17481744
#[derive(LintDiagnostic)]
17491745
#[diag(lint_unused_comparisons)]
17501746
pub(crate) struct UnusedComparisons;

compiler/rustc_lint/src/types.rs

Lines changed: 5 additions & 126 deletions
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,15 @@
11
use std::iter;
22
use std::ops::ControlFlow;
33

4-
use rustc_abi::{BackendRepr, TagEncoding, VariantIdx, Variants, WrappingRange};
4+
use rustc_abi::{BackendRepr, TagEncoding, Variants, WrappingRange};
55
use rustc_data_structures::fx::FxHashSet;
66
use rustc_errors::DiagMessage;
77
use rustc_hir::intravisit::VisitorExt;
88
use rustc_hir::{AmbigArg, Expr, ExprKind, HirId, LangItem};
99
use rustc_middle::bug;
1010
use rustc_middle::ty::layout::{LayoutOf, SizeSkeleton};
1111
use rustc_middle::ty::{
12-
self, Adt, AdtKind, GenericArgsRef, Ty, TyCtxt, TypeSuperVisitable, TypeVisitable,
12+
self, AdtKind, GenericArgsRef, Ty, TyCtxt, TypeSuperVisitable, TypeVisitable,
1313
TypeVisitableExt,
1414
};
1515
use rustc_session::{declare_lint, declare_lint_pass, impl_lint_pass};
@@ -26,7 +26,7 @@ use crate::lints::{
2626
AmbiguousWidePointerComparisonsExpectSuggestion, AtomicOrderingFence, AtomicOrderingLoad,
2727
AtomicOrderingStore, ImproperCTypes, InvalidAtomicOrderingDiag, InvalidNanComparisons,
2828
InvalidNanComparisonsSuggestion, UnpredictableFunctionPointerComparisons,
29-
UnpredictableFunctionPointerComparisonsSuggestion, UnusedComparisons, UsesPowerAlignment,
29+
UnpredictableFunctionPointerComparisonsSuggestion, UnusedComparisons,
3030
VariantSizeDifferencesDiag,
3131
};
3232
use crate::{LateContext, LateLintPass, LintContext, fluent_generated as fluent};
@@ -752,62 +752,7 @@ declare_lint! {
752752
"proper use of libc types in foreign item definitions"
753753
}
754754

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]);
811756

812757
#[derive(Clone, Copy)]
813758
pub(crate) enum CItemKind {
@@ -1647,68 +1592,6 @@ impl ImproperCTypesDefinitions {
16471592
vis.check_type_for_ffi_and_report_errors(span, fn_ptr_ty, true, false);
16481593
}
16491594
}
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-
}
17121595
}
17131596

17141597
/// `ImproperCTypesDefinitions` checks items outside of foreign items (e.g. stuff that isn't in
@@ -1732,11 +1615,7 @@ impl<'tcx> LateLintPass<'tcx> for ImproperCTypesDefinitions {
17321615
}
17331616
// See `check_fn`..
17341617
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(..) => {}
17401619
// See `check_field_def`..
17411620
hir::ItemKind::Union(..) | hir::ItemKind::Enum(..) => {}
17421621
// Doesn't define something that can contain a external type to be checked.

0 commit comments

Comments
 (0)