Skip to content

refactor: keep the original symbol when renaming an extern declaration - #1945

Open
ahomescu wants to merge 2 commits into
masterfrom
ahomescu/fix_reorganize_definitions/preserve_extern_link_name
Open

refactor: keep the original symbol when renaming an extern declaration #1945
ahomescu wants to merge 2 commits into
masterfrom
ahomescu/fix_reorganize_definitions/preserve_extern_link_name

Conversation

@ahomescu

Copy link
Copy Markdown
Contributor

Fresh copy of #1935 since I closed that one.


Stack created with GitHub Stacks CLIGive Feedback 💬

@ahomescu
ahomescu force-pushed the ahomescu/fix_reorganize_definitions/preserve_extern_link_name branch from be5a534 to 3ba5ded Compare July 25, 2026 03:13
@ahomescu
ahomescu force-pushed the ahomescu/fix_reorganize_definitions/non_ascii_idents branch from 81bf2f0 to a2771af Compare July 25, 2026 03:17
@ahomescu
ahomescu force-pushed the ahomescu/fix_reorganize_definitions/preserve_extern_link_name branch from 3ba5ded to c4d9955 Compare July 25, 2026 03:17
@ahomescu
ahomescu force-pushed the ahomescu/fix_reorganize_definitions/non_ascii_idents branch from a2771af to 476788d Compare July 25, 2026 03:26
@ahomescu
ahomescu force-pushed the ahomescu/fix_reorganize_definitions/preserve_extern_link_name branch from c4d9955 to 0f16dcf Compare July 25, 2026 03:26
@ahomescu
ahomescu changed the base branch from ahomescu/fix_reorganize_definitions/non_ascii_idents to master July 25, 2026 05:09
@ahomescu
ahomescu force-pushed the ahomescu/fix_reorganize_definitions/preserve_extern_link_name branch from 0f16dcf to 372a77b Compare July 25, 2026 05:09
@ahomescu
ahomescu marked this pull request as ready for review July 25, 2026 05:09
ahomescu added 2 commits July 24, 2026 22:30
Regression test: `test_reorganize_foreign_static_rename`
(`tests/snapshots/reorganize_foreign_static_rename.rs`). Two translation
units include the same header, which declares the C global `cfg` directly in
one unit and through a `typedef` in the other, so the two declarations are
not syntactically identical, cannot be collapsed, and the second is renamed
to `cfg_1` to clear the collision.

An `extern` static links against its own name unless a `#[link_name]` says
otherwise, so the rename quietly repoints the declaration at a symbol named
`cfg_1`, which does not exist. Nothing catches this: the output compiles,
and only a link of the whole program would fail, so the recorded snapshot
is the evidence — it shows `cfg_1` carrying no `#[link_name]`.

`test_reorganize_foreign_fn_rename` does the same thing with a function.
There the transform compares resolved types, so a `typedef` collapses; the
declarations differ instead in a parameter of type `int (*)[]` versus
`int (*)[4]`, which C treats as compatible but which transpile to pointers
to differently-sized Rust arrays.

Both inputs are real `c2rust transpile -r` output, transcribed into the
single-file form these tests use, and the C behind them is strictly
conforming: an array type of unknown size is compatible with any array type
of the same element type (C11 6.7.6.2p6), pointers are compatible when their
pointees are, and a `typedef` is an alias rather than a distinct type. So
every declaration of `cfg` and of `compute` has compatible type across the
program, as C11 6.2.7p2 requires, and the bug does not depend on feeding the
transform undefined behavior. Each test records its C sources in a comment.
When two declarations of the same name cannot be collapsed, `move_items`
appends a numeric suffix to the second one to clear the collision. For a
regular item that is harmless, since it is mangled under its own path, but a
foreign function or static links against its own name: renaming one repoints
it at a symbol that does not exist, and nothing reports it until the whole
program is linked.

`MovedDecl::preserve_link_name` now records the original name in a
`#[link_name]` before the ident is changed, so the declaration keeps naming
the symbol it was written against. It applies only to `ForeignItemKind::Fn`
and `Static`, the two kinds that have a symbol — an `extern type` has none —
and leaves an existing `#[link_name]` alone, since that already says what to
link against and is unaffected by the Rust-side rename.

This covers the rename introduced by the previous commit as well: both the
`compute_1` function and the `cfg_1` static now carry a `#[link_name]`.
@ahomescu
ahomescu force-pushed the ahomescu/fix_reorganize_definitions/preserve_extern_link_name branch from 372a77b to 10fb614 Compare July 25, 2026 05:33
@ahomescu
ahomescu requested a review from thedataking July 25, 2026 05:33
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.

1 participant