Skip to content

ir: Skip phantom anonymous members from inside attribute expressions#3392

Open
armoha wants to merge 1 commit into
rust-lang:mainfrom
armoha:aligned-struct-alignof-anonymous
Open

ir: Skip phantom anonymous members from inside attribute expressions#3392
armoha wants to merge 1 commit into
rust-lang:mainfrom
armoha:aligned-struct-alignof-anonymous

Conversation

@armoha

@armoha armoha commented Jul 10, 2026

Copy link
Copy Markdown
Contributor

Supersede #3361
Fixes #3295

CompInfo::from_ty unconditionally promotes any anonymous struct or union child cursor as a member, adding phantom members to corrupt the struct's layout. Clang exposes anonymous structs declared inside __alignof__ expressions within __attribute__((aligned(...))) as child cursors of the surrounding struct.

Cursor::extent_contains checks the cursor's source location to find phantom member whose source ranges are outside the parent's body. This PR is based on PR #3361 by @barry3406 and extends it to check the end offset. It isn't valid C syntax for child cursor to start inside but somehow extend past the parent's body but stricter check is just added for safety.

Alternatives

Filtering by cursor kind is not sufficient because anonymous members are represented as StructDecl cursors, not FieldDecl. Walking up the AST and semantic analysis would be more complex.

Limitations

I think it would be extremely rare but this PR doesn't work for macros and templates defining both a struct member and an aligned attribute with a nested anonymous struct:

#define CONVOLUTED_FIELD struct {int aaa;} __attribute__((aligned(__alignof__(struct {int bbb;}))))

typedef struct macro_t {
    CONVOLUTED_FIELD;
} macro_t;
#[repr(C)]
#[derive(Debug, Default, Copy, Clone)]
pub struct macro_t {
    pub __bindgen_anon_1: macro_t__bindgen_ty_1,
}
#[repr(C)]
#[derive(Debug, Default, Copy, Clone)]
pub struct macro_t__bindgen_ty_1 {
    pub aaa: ::std::os::raw::c_int,
    pub __bindgen_anon_1: macro_t__bindgen_ty_1__bindgen_ty_1,  // <-- incorrect member struct
}
#[repr(C)]
#[derive(Debug, Default, Copy, Clone)]
pub struct macro_t__bindgen_ty_1__bindgen_ty_1 {
    pub bbb: ::std::os::raw::c_int,
}
#[allow(clippy::unnecessary_operation, clippy::identity_op)]
const _: () = {
    [
        "Size of macro_t__bindgen_ty_1__bindgen_ty_1",
    ][::std::mem::size_of::<macro_t__bindgen_ty_1__bindgen_ty_1>() - 4usize];
    [
        "Alignment of macro_t__bindgen_ty_1__bindgen_ty_1",
    ][::std::mem::align_of::<macro_t__bindgen_ty_1__bindgen_ty_1>() - 4usize];
    [
        "Offset of field: macro_t__bindgen_ty_1__bindgen_ty_1::bbb",
    ][::std::mem::offset_of!(macro_t__bindgen_ty_1__bindgen_ty_1, bbb) - 0usize];
};
#[allow(clippy::unnecessary_operation, clippy::identity_op)]
const _: () = {
    [
        "Size of macro_t__bindgen_ty_1",
    ][::std::mem::size_of::<macro_t__bindgen_ty_1>() - 4usize];
    [
        "Alignment of macro_t__bindgen_ty_1",
    ][::std::mem::align_of::<macro_t__bindgen_ty_1>() - 4usize];
    [
        "Offset of field: macro_t__bindgen_ty_1::aaa",
    ][::std::mem::offset_of!(macro_t__bindgen_ty_1, aaa) - 0usize];
};
#[allow(clippy::unnecessary_operation, clippy::identity_op)]
const _: () = {
    ["Size of macro_t"][::std::mem::size_of::<macro_t>() - 4usize];
    ["Alignment of macro_t"][::std::mem::align_of::<macro_t>() - 4usize];
};

Clang exposes anonymous structs declared inside the parent struct's
attribute expressions (e.g. `__alignof__(struct{int aaa;})` inside
`__attribute__((aligned(...)))`) as child cursors of the surrounding
struct. The existing `is_anonymous() && kind != EnumDecl` check in
`CompInfo::from_ty` promoted them to anonymous members, corrupting
the parent struct's layout.

Filter them out by checking that the child's source range lies fully
within the parent's source range via a new `Cursor::extent_contains`
helper.

Fixes rust-lang#3295

Co-authored-by: barry3406 <duan3406@gmail.com>
@armoha armoha force-pushed the aligned-struct-alignof-anonymous branch from 05d0dd3 to adad51c Compare July 10, 2026 08:27
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

__attribute__((aligned(__alignof__(struct {...})))) will trigger size check error

1 participant