Skip to content

transpile: Properly handle address-of static compound literals#1644

Open
Rua wants to merge 3 commits intoimmunant:masterfrom
Rua:static-compound-literal
Open

transpile: Properly handle address-of static compound literals#1644
Rua wants to merge 3 commits intoimmunant:masterfrom
Rua:static-compound-literal

Conversation

@Rua
Copy link
Contributor

@Rua Rua commented Mar 6, 2026

This allows limited use of statements in translations of statics, only if the statements are Stmt::Item. This is then used to solve the original bug, by declaring a fresh static variable to take the address of.

This code doesn't currently account for situations in which the compound literal expression needs to be sectioned off for late initialisation, as that would have complicated the code a fair bit further.

@Rua Rua force-pushed the static-compound-literal branch from dcbe0fa to 8a200eb Compare March 6, 2026 17:49
@Rua Rua marked this pull request as ready for review March 6, 2026 17:51
@Rua Rua force-pushed the static-compound-literal branch 4 times, most recently from 4a06d79 to b768426 Compare March 6, 2026 18:51
Comment on lines +93 to +94
/// If all statements in self.stmts are Item statements, returns the contained Items.
/// Otherwise, returns None.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
/// If all statements in self.stmts are Item statements, returns the contained Items.
/// Otherwise, returns None.
/// If all statements in `self.stmts` are [`Item`]s, returns the contained [`Item`]s.
/// Otherwise, returns [`None`].

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can we wait to merge this until after #1643 merges, which has gotten pretty long? #1643 changes things like mk_linkage, "link_section", etc., so it's going to have conflicts here, and I'd like to review the changes here after it's rebased on that.

val,
is_unsafe: true,
}
}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
}
pub fn new_unsafe(stmts: Vec<Stmt>, val: T) -> Self {
WithStmts {
stmts,
val,
is_unsafe: true,
}
}

I'm not sure why there aren't newlines between the functions here, but let's fix it for new functions.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Also, I feel like these 4 functions would be better off as builder-like methods, like this:

    pub fn new_val(val: T) -> Self {
        WithStmts {
            stmts: vec![],
            val,
            is_unsafe: false,
        }
    }

    pub fn stmts(self, stmts: Vec<Stmt>) -> Self {
        Self { stmts, ..self }
    }

    pub fn is_unsafe(self, is_unsafe: bool) -> Self {
        Self { is_unsafe, ..self }
    }

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

WithStmts doesn't use the builder pattern anywhere, so converting it to one seems like a separate refactor that belongs in its own PR?

#[no_mangle]
pub static mut static_single_int_ptr: *mut ::core::ffi::c_int =
&42 as *const ::core::ffi::c_int as *mut ::core::ffi::c_int;
unsafe { &raw const c2rust_fresh0 as *mut ::core::ffi::c_int };
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why do these need to be unsafe?

Copy link
Contributor Author

@Rua Rua Mar 10, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hmm, I guess taking a raw pointer is not unsafe, only taking a regular reference is.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It seems that convert_address_of_common doesn't mark its expression as unsafe, and never did even before my refactorings? Even when it's taking the address of a static? How did it work before then?

@Rua Rua force-pushed the static-compound-literal branch 3 times, most recently from e380100 to 3e04701 Compare March 14, 2026 11:11
@Rua Rua force-pushed the static-compound-literal branch from 3e04701 to e485aae Compare March 17, 2026 10:58
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.

Allow WithStmts in static initialisers to contain statements File-scope compound literal translated incorrectly, causing segfault on write

2 participants