-
Notifications
You must be signed in to change notification settings - Fork 13.1k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
[AIX] Lint on structs that have a different alignment in AIX's C ABI #135552
[AIX] Lint on structs that have a different alignment in AIX's C ABI #135552
Conversation
Thanks for the pull request, and welcome! The Rust team is excited to review your changes, and you should hear from @fee1-dead (or someone else) some time within the next two weeks. Please see the contribution instructions for more information. Namely, in order to ensure the minimum review times lag, PR authors and assigned reviewers should ensure that the review label (
|
This PR is related to the discussion that was previously started by @mustartt: https://internals.rust-lang.org/t/repr-c-aix-struct-alignment/21594 FYI @daltenty |
This comment has been minimized.
This comment has been minimized.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Please give an actual description of the "power alignment rule" for the lint. It must not use undefined terms like "natural alignment". Otherwise the lint is not implementing a spec.
compiler/rustc_lint/src/types.rs
Outdated
/// - floating-point data type as its first member, or | ||
/// - first member being an aggregate whose recursively first member is a | ||
/// floating-point data type | ||
/// must have its natural alignment. This is currently unimplemented within |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
"natural alignment"?
What does "natural alignment" mean?
The alignment of f64 is 8 bytes, so the "natural alignment" of the struct should be 8 bytes, and the produced struct will be 8 bytes, but the alignment to 4 bytes described here by @mustartt is not a "natural alignment".
compiler/rustc_lint/src/types.rs
Outdated
// - the first argument of the struct is a floating-point type, or | ||
// - the first argument of the struct is an aggregate whose | ||
// recursively first member is a floating-point type |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
// - the first argument of the struct is a floating-point type, or | |
// - the first argument of the struct is an aggregate whose | |
// recursively first member is a floating-point type | |
// - the first field of the struct is a floating-point type, or | |
// - the first field of the struct is an aggregate whose | |
// recursively first field is a floating-point type |
compiler/rustc_lint/src/types.rs
Outdated
&& !adt_def.all_fields().next().is_none() | ||
{ | ||
let struct_variant_data = item.expect_struct().0; | ||
// Analyze only the first member of the struct to see if it |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
// Analyze only the first member of the struct to see if it | |
// Analyze only the first field of the struct to see if it |
compiler/rustc_lint/src/types.rs
Outdated
/// } | ||
/// ``` | ||
/// | ||
/// A warning should be produced for the above struct as the first member |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
/// A warning should be produced for the above struct as the first member | |
/// A warning should be produced for the above struct as the first field |
@rustbot review |
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
What a strange rule. Thank you, that is a much better description. A few more edits and this should be good.
It seems we would match the alignment produced if -qalign=natural
is used, wouldn't we? Of course, such C code is incompatible with -qalign=power
, which as I understand it is the default?
if adt_def.repr().c() | ||
&& !adt_def.repr().packed() | ||
&& cx.tcx.sess.target.os == "aix" |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
please check this first in both functions, so that the code doesn't really run for most targets.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Good idea. I will add an AIX check in the other function, too.
y: FloatAgg2, //~ WARNING repr(C) does not follow the power alignment rule. This may affect platform C ABI compatibility for this type | ||
z: FloatAgg2, //~ WARNING repr(C) does not follow the power alignment rule. This may affect platform C ABI compatibility for this type |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
So if included in FloatAgg3, FloatAgg2 is given a different layout...?
y: FloatAgg2, //~ WARNING repr(C) does not follow the power alignment rule. This may affect platform C ABI compatibility for this type | |
z: FloatAgg2, //~ WARNING repr(C) does not follow the power alignment rule. This may affect platform C ABI compatibility for this type | |
// NOTE: the "power" alignment rule is infectious to nested struct fields | |
y: FloatAgg2, //~ WARNING repr(C) does not follow the power alignment rule. This may affect platform C ABI compatibility for this type | |
z: FloatAgg2, //~ WARNING repr(C) does not follow the power alignment rule. This may affect platform C ABI compatibility for this type |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think adding the comment here makes sense.
Currently, in Rust, we would get something like:
offset_of!(FloatAgg3, x) == 0
offset_of!(FloatAgg3, y) == 40
offset_of!(FloatAgg3, z) == 80
Whereas power alignment would expect it to be more like:
offset_of!(FloatAgg3, x) == 0
offset_of!(FloatAgg3, y) == 32
offset_of!(FloatAgg3, z) == 64
compiler/rustc_lint/src/types.rs
Outdated
/// In this case, "natural alignment" (detailed in | ||
/// https://www.ibm.com/docs/en/xl-c-and-cpp-aix/16.1?topic=data-using-alignment-modes#alignment) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This link should probably come first, actually.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Sorry for the silly question, but just wanted to check if I understand the suggestion. Do you mean that the link should be in the paragraph above instead and we should remove this section (since your suggestion above relates to having to avoid describing natural alignment)?
Please do correct me if I misunderstood. :-)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Correct, it should probably be on the first line (which my suggestion currently doesn't capture, but please feel free to edit things as you see fit).
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Sounds good. Thanks for clarifying! I tried to make it closer to the top/first line, so hopefully you are okay with its placement.
uthe relevant part of the error:
|
compiler/rustc_lint/src/types.rs
Outdated
/// is an aggregate whose recursively "first" field is a floating-point | ||
/// type greater than 4-bytes. | ||
/// The alignment for subsequent fields of the associated structs use an | ||
/// alignment value where the floating-point type is aligned on a 4-byte |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
an important question: how would the XLC compiler handle this case?
#pragma align(power)
typedef struct Lol {
float criminal_field;
uint16_t filler;
_Float16 half_as_bad;
} Lmao;
Does the _Float16
get aligned to 4, even though its natural alignment would be 2? Does the compiler even support a half type of some kind? (please substitute whatever it does support, if so).
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Using XLC, it appears that half precision floating point was never supported in C on the AIX platform. Thus, the ABI is currently unknown.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I see.
Yup, you and I both have the same understanding. Power alignment is the default, which is why they differ. |
@rustbot review |
This comment has been minimized.
This comment has been minimized.
@@ -0,0 +1,146 @@ | |||
//@ check-pass | |||
//@ revisions: aix |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
this doesn't need a revision
//@ revisions: aix |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
unless IBM does in fact have other platforms which use this bizarre alignment rule and is thinking about adding them to rustc, in which case I suppose I have no objection to keeping a single revision in place.
//@[aix] compile-flags: --target powerpc64-ibm-aix | ||
//@[aix] needs-llvm-components: powerpc |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This test should use our minicore.
//@[aix] compile-flags: --target powerpc64-ibm-aix | |
//@[aix] needs-llvm-components: powerpc | |
//@ compile-flags: --target powerpc64-ibm-aix | |
//@ needs-llvm-components: powerpc | |
//@ add-core-stubs | |
#![feature(no_core)] | |
#![no_core] | |
#![no_std] |
compiler/rustc_lint/src/types.rs
Outdated
@@ -727,7 +728,43 @@ declare_lint! { | |||
"proper use of libc types in foreign item definitions" | |||
} | |||
|
|||
declare_lint_pass!(ImproperCTypesDefinitions => [IMPROPER_CTYPES_DEFINITIONS]); | |||
declare_lint! { | |||
/// In it's platform C ABI, AIX uses the "power" (as in PowerPC) alignment |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
/// In it's platform C ABI, AIX uses the "power" (as in PowerPC) alignment | |
/// In its platform C ABI, AIX uses the "power" (as in PowerPC) alignment |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
one nit, and with CI fixed then this will be good
(+history cleanup / squash pls) |
b48eb01
to
646c280
Compare
This comment has been minimized.
This comment has been minimized.
646c280
to
1d184a1
Compare
@@ -727,7 +728,50 @@ declare_lint! { | |||
"proper use of libc types in foreign item definitions" | |||
} | |||
|
|||
declare_lint_pass!(ImproperCTypesDefinitions => [IMPROPER_CTYPES_DEFINITIONS]); | |||
declare_lint! { | |||
/// The `uses_power_alignment` lint detects specific `repr(C)` |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Hi @workingjubilee! Just tagging you here in case you had any opinions on this first sentence I added, since I realized I needed this line when building the lint docs. I added a more general first sentence here as we go into describing power alignment below. Hope this is fine, but if not, I am open to suggestions.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This seems fine to me!
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Sounds good! Thank you so much for your thorough review! I really appreciate it!
This comment has been minimized.
This comment has been minimized.
1d184a1
to
2d26033
Compare
This comment has been minimized.
This comment has been minimized.
2d26033
to
3f73f85
Compare
This comment has been minimized.
This comment has been minimized.
3f73f85
to
cd2ecc4
Compare
This should only affect the AIX target so it's safe to @bors r+ rollup |
…gnostic-power-alignment, r=workingjubilee [AIX] Lint on structs that have a different alignment in AIX's C ABI This PR adds a linting diagnostic on AIX for repr(C) structs that are required to follow the power alignment rule. A repr(C) struct needs to follow the power alignment rule if the struct: - Has a floating-point data type (greater than 4-bytes) as its first member, or - The first member of the struct is an aggregate, whose recursively first member is a floating-point data type (greater than 4-bytes). The power alignment rule for eligible structs is currently unimplemented, so a linting diagnostic is produced when such a struct is encountered.
Rollup of 10 pull requests Successful merges: - rust-lang#134746 (Don't ICE in coerce when autoderef fails to structurally normalize non-WF type in new solver) - rust-lang#135552 ([AIX] Lint on structs that have a different alignment in AIX's C ABI) - rust-lang#135764 (Fix tests on LLVM 20) - rust-lang#135779 (CI: free disk on linux arm runner) - rust-lang#135790 (Update windows-gnu targets to set `DebuginfoKind::DWARF`) - rust-lang#135879 (fix outdated file path ref in llvm) - rust-lang#135883 (Remove erroneous `unsafe` in `BTreeSet::upper_bound_mut`) - rust-lang#135884 (remove implied end of slice) - rust-lang#135887 (improvements on `build_steps::test` implementation) - rust-lang#135898 (rustdoc-json-types: Finalize dyn compatibility renaming) r? `@ghost` `@rustbot` modify labels: rollup
…iaskrgr Rollup of 9 pull requests Successful merges: - rust-lang#134746 (Don't ICE in coerce when autoderef fails to structurally normalize non-WF type in new solver) - rust-lang#135552 ([AIX] Lint on structs that have a different alignment in AIX's C ABI) - rust-lang#135779 (CI: free disk on linux arm runner) - rust-lang#135790 (Update windows-gnu targets to set `DebuginfoKind::DWARF`) - rust-lang#135879 (fix outdated file path ref in llvm) - rust-lang#135883 (Remove erroneous `unsafe` in `BTreeSet::upper_bound_mut`) - rust-lang#135884 (remove implied end of slice) - rust-lang#135887 (improvements on `build_steps::test` implementation) - rust-lang#135898 (rustdoc-json-types: Finalize dyn compatibility renaming) r? `@ghost` `@rustbot` modify labels: rollup
This PR adds a linting diagnostic on AIX for repr(C) structs that are required to follow
the power alignment rule. A repr(C) struct needs to follow the power alignment rule if
the struct:
floating-point data type (greater than 4-bytes).
The power alignment rule for eligible structs is currently unimplemented, so a linting
diagnostic is produced when such a struct is encountered.