Auto merge of #147375 - folkertdev:power-align-union, r=RalfJung

ignore power alignment rule on unions

fixes https://github.com/rust-lang/rust/issues/147348

The power alignment rule only applies to the non-first field of a struct, and so should not apply to unions at all.

The current code also does not consider enums (whose fields might be, morally, structs). Given that C does not actually have ADTs like this it's probably fine from a compatibility perspective, but I'll leave that to the powerpc folks.

cc `@daltenty` `@gilamn5tr`
r? compiler
This commit is contained in:
bors 2025-10-05 22:14:55 +00:00
commit 4fa824bb78
3 changed files with 51 additions and 36 deletions

View file

@ -220,21 +220,21 @@ fn check_struct_for_power_alignment<'tcx>(
adt_def: AdtDef<'tcx>, adt_def: AdtDef<'tcx>,
) { ) {
let tcx = cx.tcx; let tcx = cx.tcx;
// repr(C) structs also with packed or aligned representation
// should be ignored. // Only consider structs (not enums or unions) on AIX.
if adt_def.repr().c() if tcx.sess.target.os != "aix" || !adt_def.is_struct() {
&& !adt_def.repr().packed() return;
&& adt_def.repr().align.is_none() }
&& tcx.sess.target.os == "aix"
&& !adt_def.all_fields().next().is_none() // The struct must be repr(C), but ignore it if it explicitly specifies its alignment with
{ // either `align(N)` or `packed(N)`.
if adt_def.repr().c() && !adt_def.repr().packed() && adt_def.repr().align.is_none() {
let struct_variant_data = item.expect_struct().2; let struct_variant_data = item.expect_struct().2;
for field_def in struct_variant_data.fields().iter().skip(1) { for field_def in struct_variant_data.fields().iter().skip(1) {
// Struct fields (after the first field) are checked for the // Struct fields (after the first field) are checked for the
// power alignment rule, as fields after the first are likely // power alignment rule, as fields after the first are likely
// to be the fields that are misaligned. // to be the fields that are misaligned.
let def_id = field_def.def_id; let ty = tcx.type_of(field_def.def_id).instantiate_identity();
let ty = tcx.type_of(def_id).instantiate_identity();
if check_arg_for_power_alignment(cx, ty) { if check_arg_for_power_alignment(cx, ty) {
cx.emit_span_lint(USES_POWER_ALIGNMENT, field_def.span, UsesPowerAlignment); cx.emit_span_lint(USES_POWER_ALIGNMENT, field_def.span, UsesPowerAlignment);
} }

View file

@ -5,12 +5,12 @@
#![feature(no_core)] #![feature(no_core)]
#![no_core] #![no_core]
#![no_std] #![no_std]
#![crate_type = "lib"]
extern crate minicore; extern crate minicore;
use minicore::*; use minicore::*;
#[warn(uses_power_alignment)] #[warn(uses_power_alignment)]
#[repr(C)] #[repr(C)]
pub struct Floats { pub struct Floats {
a: f64, a: f64,
@ -96,32 +96,32 @@ pub struct FloatAgg7 {
#[repr(C)] #[repr(C)]
pub struct A { pub struct A {
d: f64, d: f64,
} }
#[repr(C)] #[repr(C)]
pub struct B { pub struct B {
a: A, a: A,
f: f32, f: f32,
d: f64, //~ WARNING repr(C) does not follow the power alignment rule. This may affect platform C ABI compatibility for this type d: f64, //~ WARNING repr(C) does not follow the power alignment rule. This may affect platform C ABI compatibility for this type
} }
#[repr(C)] #[repr(C)]
pub struct C { pub struct C {
c: u8, c: u8,
b: B, //~ WARNING repr(C) does not follow the power alignment rule. This may affect platform C ABI compatibility for this type b: B, //~ WARNING repr(C) does not follow the power alignment rule. This may affect platform C ABI compatibility for this type
} }
#[repr(C)] #[repr(C)]
pub struct D { pub struct D {
x: f64, x: f64,
} }
#[repr(C)] #[repr(C)]
pub struct E { pub struct E {
x: i32, x: i32,
d: D, //~ WARNING repr(C) does not follow the power alignment rule. This may affect platform C ABI compatibility for this type d: D, //~ WARNING repr(C) does not follow the power alignment rule. This may affect platform C ABI compatibility for this type
} }
#[repr(C)] #[repr(C)]
pub struct F { pub struct F {
a: u8, a: u8,
b: f64, //~ WARNING repr(C) does not follow the power alignment rule. This may affect platform C ABI compatibility for this type b: f64, //~ WARNING repr(C) does not follow the power alignment rule. This may affect platform C ABI compatibility for this type
} }
#[repr(C)] #[repr(C)]
pub struct G { pub struct G {
@ -173,4 +173,19 @@ pub struct M {
b: K, b: K,
c: L, c: L,
} }
fn main() { }
// The lint ignores unions
#[repr(C)]
pub union Union {
a: f64,
b: u8,
c: f64,
d: f32,
}
// The lint ignores enums
#[repr(C)]
pub enum Enum {
A { a: f64, b: u8, c: f64, d: f32 },
B,
}

View file

@ -5,7 +5,7 @@ LL | c: f64,
| ^^^^^^ | ^^^^^^
| |
note: the lint level is defined here note: the lint level is defined here
--> $DIR/reprc-power-alignment.rs:12:8 --> $DIR/reprc-power-alignment.rs:13:8
| |
LL | #[warn(uses_power_alignment)] LL | #[warn(uses_power_alignment)]
| ^^^^^^^^^^^^^^^^^^^^ | ^^^^^^^^^^^^^^^^^^^^
@ -73,28 +73,28 @@ LL | y: Floats,
| ^^^^^^^^^ | ^^^^^^^^^
warning: repr(C) does not follow the power alignment rule. This may affect platform C ABI compatibility for this type warning: repr(C) does not follow the power alignment rule. This may affect platform C ABI compatibility for this type
--> $DIR/reprc-power-alignment.rs:105:3 --> $DIR/reprc-power-alignment.rs:105:5
| |
LL | d: f64, LL | d: f64,
| ^^^^^^ | ^^^^^^
warning: repr(C) does not follow the power alignment rule. This may affect platform C ABI compatibility for this type warning: repr(C) does not follow the power alignment rule. This may affect platform C ABI compatibility for this type
--> $DIR/reprc-power-alignment.rs:110:3 --> $DIR/reprc-power-alignment.rs:110:5
| |
LL | b: B, LL | b: B,
| ^^^^ | ^^^^
warning: repr(C) does not follow the power alignment rule. This may affect platform C ABI compatibility for this type warning: repr(C) does not follow the power alignment rule. This may affect platform C ABI compatibility for this type
--> $DIR/reprc-power-alignment.rs:119:3 --> $DIR/reprc-power-alignment.rs:119:5
| |
LL | d: D, LL | d: D,
| ^^^^ | ^^^^
warning: repr(C) does not follow the power alignment rule. This may affect platform C ABI compatibility for this type warning: repr(C) does not follow the power alignment rule. This may affect platform C ABI compatibility for this type
--> $DIR/reprc-power-alignment.rs:124:3 --> $DIR/reprc-power-alignment.rs:124:5
| |
LL | b: f64, LL | b: f64,
| ^^^^^^ | ^^^^^^
warning: repr(C) does not follow the power alignment rule. This may affect platform C ABI compatibility for this type warning: repr(C) does not follow the power alignment rule. This may affect platform C ABI compatibility for this type
--> $DIR/reprc-power-alignment.rs:130:5 --> $DIR/reprc-power-alignment.rs:130:5