Skip to content

Do not give function allocations alignment in consteval and Miri. #144706

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

Merged
merged 2 commits into from
Aug 4, 2025

Conversation

zachs18
Copy link
Contributor

@zachs18 zachs18 commented Jul 30, 2025

We do not yet have a (clear and T-lang approved) design for how #[align(N)] on functions should affect function pointers' addresses on various platforms, so for now do not give function pointers alignment in consteval and Miri.


Old summary:

Not a full solution to #144661, but fixes the immediate issue by making function allocations all have alignment 1 in consteval, ignoring #[rustc_align(N)], so the compiler doesn't know if any offset other than 0 is non-null.

A more "principlied" solution would probably be to make function pointers to #[instruction_set(arm::t32)] functions be at offset 1 of an align-max(2, align attribute) allocation instead of at offset 0 of their allocation during consteval, and on wasm to either disallow #[align(N)] where N > 1, or to pad the function table such that the function pointer of a #[align(N)] function is a multiple of N at runtime.

@rustbot
Copy link
Collaborator

rustbot commented Jul 30, 2025

r? @lcnr

rustbot has assigned @lcnr.
They will have a look at your PR within the next two weeks and either review your PR or reassign to another reviewer.

Use r? to explicitly pick a reviewer

@rustbot rustbot added the S-waiting-on-review Status: Awaiting review from the assignee but also interested parties. label Jul 30, 2025
@rustbot
Copy link
Collaborator

rustbot commented Jul 30, 2025

Some changes occurred to the CTFE / Miri interpreter

cc @rust-lang/miri

Some changes occurred to the CTFE machinery

cc @RalfJung, @oli-obk, @lcnr

@rustbot rustbot added the T-compiler Relevant to the compiler team, which will review and decide on the PR/issue. label Jul 30, 2025
@rust-log-analyzer

This comment has been minimized.

@zachs18
Copy link
Contributor Author

zachs18 commented Jul 31, 2025

@rustbot author

@rustbot rustbot added S-waiting-on-author Status: This is awaiting some action (such as code changes or more information) from the author. and removed S-waiting-on-review Status: Awaiting review from the assignee but also interested parties. labels Jul 31, 2025
@rustbot
Copy link
Collaborator

rustbot commented Jul 31, 2025

Reminder, once the PR becomes ready for a review, use @rustbot ready.

@RalfJung
Copy link
Member

RalfJung commented Jul 31, 2025

So this essentially reverts #140072... Cc @folkertdev.

But I agree, #140072 is just wrong, so we should probably revert and reconsider.
Cc @rust-lang/opsem

@RalfJung
Copy link
Member

@zachs18 you can just remove that failing Miri test.

@lcnr
Copy link
Contributor

lcnr commented Jul 31, 2025

r? @RalfJung lacking context (and not sure I want to know about function pointer alignment issues for now :>)

@rustbot rustbot assigned RalfJung and unassigned lcnr Jul 31, 2025
@folkertdev
Copy link
Contributor

For wasm we already basically decided to limit the maximum alignment to just 1 (the only value that makes sense on that target). It's unfortunate because then any code that uses an alignment higher than 1 is non-portable, but function alignment is a highly specific tool anyway so that should be OK.

make function pointers to #[instruction_set(arm::t32)] functions be at offset 1

I guess that works? Seems a bit hacky but at least const eval won't need to actually know about the pointer tagging.

@RalfJung
Copy link
Member

RalfJung commented Jul 31, 2025

That's just the one case where we know about this kind of problem though. Who knows what other current or future architectures come up with. We should have a very high bar for such architecture-specific logic in the interpreter and I am not convinced this meets that bar.

@RalfJung
Copy link
Member

RalfJung commented Jul 31, 2025

Given that this turns out to be a non-trivial question, I think that until we have a clear motivation for turning align(N) on functions into a language-level guarantee about function pointers, and a t-lang decision to do so, we shouldn't use this attribute at all in the interpreter.

@rustbot
Copy link
Collaborator

rustbot commented Jul 31, 2025

The Miri subtree was changed

cc @rust-lang/miri

@zachs18
Copy link
Contributor Author

zachs18 commented Jul 31, 2025

@rustbot ready

I deleted the Miri test, and changed the FIXME comment from "as a workaround for #144661, [...]" to "Until we have a clear design for the effects of align(N) functions on the address of function pointers, we don't consider the align(N) attribute on functions in the interpreter."

@rustbot rustbot added S-waiting-on-review Status: Awaiting review from the assignee but also interested parties. and removed S-waiting-on-author Status: This is awaiting some action (such as code changes or more information) from the author. labels Jul 31, 2025
@zachs18 zachs18 changed the title Work around function pointer alignment issue in consteval by not giving function allocations alignment in consteval. Do not give function allocations alignment in consteval and Miri. Jul 31, 2025
@nikic
Copy link
Contributor

nikic commented Aug 1, 2025

Can't we base this on the Fn vs Fi information in the data layout? That's what LLVM does.

@RalfJung
Copy link
Member

RalfJung commented Aug 1, 2025

I don't even know what these words mean.^^

But this is a discussion for #140261. It clearly needs some thought whether we want to expose this inside the language.

@nikic
Copy link
Contributor

nikic commented Aug 1, 2025

@RalfJung I'm referring to:

F<type><abi>

This specifies the alignment for function pointers. The options for <type> are:

  • i: The alignment of function pointers is independent of the alignment of functions, and is a multiple of <abi>.
  • n: The alignment of function pointers is a multiple of the explicit alignment specified on the function, and is a multiple of <abi>.

The ARM targets specify Fi8 in the data layout, which means they have 1 byte function pointer alignment that is independent of function alignment.

@RalfJung
Copy link
Member

RalfJung commented Aug 1, 2025

Interesting. So far I don't think rustc parses the LLVM data layout string, or if it does then at least the interpreter doesn't.

This seems non-trivial enough that it warrants t-lang involvement IMO, so I added this as an unresolved question in #140261. For now I think a revert is the right call.

Replace commented-out code with link to context for change.

Co-authored-by: Ralf Jung <[email protected]>
@RalfJung
Copy link
Member

RalfJung commented Aug 1, 2025

Thanks!

@bors r+

@bors
Copy link
Collaborator

bors commented Aug 1, 2025

📌 Commit fe72018 has been approved by RalfJung

It is now in the queue for this repository.

@bors bors added S-waiting-on-bors Status: Waiting on bors to run and complete tests. Bors will change the label on completion. and removed S-waiting-on-review Status: Awaiting review from the assignee but also interested parties. labels Aug 1, 2025
Zalathar added a commit to Zalathar/rust that referenced this pull request Aug 3, 2025
Do not give function allocations alignment in consteval and Miri.

We do not yet have a (clear and T-lang approved) design for how `#[align(N)]` on functions should affect function pointers' addresses on various platforms, so for now do not give function pointers alignment in consteval and Miri.

----

Old summary:

Not a full solution to <rust-lang#144661>, but fixes the immediate issue by making function allocations all have alignment 1 in consteval, ignoring `#[rustc_align(N)]`, so the compiler doesn't know if any offset other than 0 is non-null.

A more "principlied" solution would probably be to make function pointers to `#[instruction_set(arm::t32)]` functions be at offset 1 of an align-`max(2, align attribute)` allocation instead of at offset 0 of their allocation during consteval, and on wasm to either disallow `#[align(N)]` where N > 1, or to pad the function table such that the function pointer of a `#[align(N)]` function is a multiple of `N` at runtime.
bors added a commit that referenced this pull request Aug 3, 2025
Rollup of 13 pull requests

Successful merges:

 - #143857 (Port #[macro_export] to the new attribute parsing infrastructure)
 - #144070 (Implement `hash_map` macro )
 - #144322 (Add lint against dangling pointers from local variables)
 - #144667 (`AlignmentEnum` should just be `repr(usize)` now)
 - #144706 (Do not give function allocations alignment in consteval and Miri.)
 - #144790 (Multiple bounds checking elision failures)
 - #144794 (Port `#[coroutine]` to the new attribute system)
 - #144805 (compiletest: Preliminary cleanup of `ProcRes` printing/unwinding)
 - #144808 (`Interner` arg to `EarlyBinder` does not affect auto traits)
 - #144816 (Update E0562 to account for the new impl trait positions)
 - #144822 (Return a struct with named fields from `hash_owner_nodes`)
 - #144824 (Updated test links in compiler)
 - #144829 (Use full flag name in strip command for Darwin)

r? `@ghost`
`@rustbot` modify labels: rollup
bors added a commit that referenced this pull request Aug 4, 2025
Rollup of 12 pull requests

Successful merges:

 - #142205 (Mark `slice::swap_with_slice` unstably const)
 - #144188 (`available_parallelism`: Add documentation for why we don't look at `ulimit`)
 - #144322 (Add lint against dangling pointers from local variables)
 - #144497 (tests: Add test for basic line-by-line stepping in a debugger)
 - #144559 (Enable extract-insert-dyn.rs test on RISC-V (riscv64))
 - #144667 (`AlignmentEnum` should just be `repr(usize)` now)
 - #144706 (Do not give function allocations alignment in consteval and Miri.)
 - #144746 (resolve: Cleanups and micro-optimizations to extern prelude)
 - #144785 (Regression test for LLVM error with unsupported expression in static initializer for const pointer in array on macOS.)
 - #144811 (Stylize `*-lynxos178-*` target maintainer handle to make it easier to copy/paste)
 - #144848 (For "stage 1" ui-fulldeps, use the stage 1 compiler to query target info)
 - #144853 (Remove unnecessary `rust_` prefixes)

Failed merges:

 - #144794 (Port `#[coroutine]` to the new attribute system)

r? `@ghost`
`@rustbot` modify labels: rollup
@bors bors merged commit 0225f8b into rust-lang:master Aug 4, 2025
10 checks passed
@rustbot rustbot added this to the 1.91.0 milestone Aug 4, 2025
rust-timer added a commit that referenced this pull request Aug 4, 2025
Rollup merge of #144706 - zachs18:fix-144661, r=RalfJung

Do not give function allocations alignment in consteval and Miri.

We do not yet have a (clear and T-lang approved) design for how `#[align(N)]` on functions should affect function pointers' addresses on various platforms, so for now do not give function pointers alignment in consteval and Miri.

----

Old summary:

Not a full solution to <#144661>, but fixes the immediate issue by making function allocations all have alignment 1 in consteval, ignoring `#[rustc_align(N)]`, so the compiler doesn't know if any offset other than 0 is non-null.

A more "principlied" solution would probably be to make function pointers to `#[instruction_set(arm::t32)]` functions be at offset 1 of an align-`max(2, align attribute)` allocation instead of at offset 0 of their allocation during consteval, and on wasm to either disallow `#[align(N)]` where N > 1, or to pad the function table such that the function pointer of a `#[align(N)]` function is a multiple of `N` at runtime.
github-actions bot pushed a commit to rust-lang/miri that referenced this pull request Aug 4, 2025
Rollup of 12 pull requests

Successful merges:

 - rust-lang/rust#142205 (Mark `slice::swap_with_slice` unstably const)
 - rust-lang/rust#144188 (`available_parallelism`: Add documentation for why we don't look at `ulimit`)
 - rust-lang/rust#144322 (Add lint against dangling pointers from local variables)
 - rust-lang/rust#144497 (tests: Add test for basic line-by-line stepping in a debugger)
 - rust-lang/rust#144559 (Enable extract-insert-dyn.rs test on RISC-V (riscv64))
 - rust-lang/rust#144667 (`AlignmentEnum` should just be `repr(usize)` now)
 - rust-lang/rust#144706 (Do not give function allocations alignment in consteval and Miri.)
 - rust-lang/rust#144746 (resolve: Cleanups and micro-optimizations to extern prelude)
 - rust-lang/rust#144785 (Regression test for LLVM error with unsupported expression in static initializer for const pointer in array on macOS.)
 - rust-lang/rust#144811 (Stylize `*-lynxos178-*` target maintainer handle to make it easier to copy/paste)
 - rust-lang/rust#144848 (For "stage 1" ui-fulldeps, use the stage 1 compiler to query target info)
 - rust-lang/rust#144853 (Remove unnecessary `rust_` prefixes)

Failed merges:

 - rust-lang/rust#144794 (Port `#[coroutine]` to the new attribute system)

r? `@ghost`
`@rustbot` modify labels: rollup
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
S-waiting-on-bors Status: Waiting on bors to run and complete tests. Bors will change the label on completion. T-compiler Relevant to the compiler team, which will review and decide on the PR/issue.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

8 participants