refactor: reorganize_definitions: use the fallback/C ABI instead of Rust - #1924
Conversation
|
According to https://doc.rust-lang.org/reference/items/external-blocks.html#r-items.extern.abi.default, |
| pub mod first { | ||
| #[c2rust::header_src = "/home/user/some/workspace/first.h:1"] | ||
| pub mod first_h { | ||
| // An `extern` block without an explicit ABI string defaults to "C", |
There was a problem hiding this comment.
The transpiler always emits an explicit .extern_("C") (c2rust-transpile/src/translator/mod.rs:1231, :1459, :2009, :2236, :2781), so an implicit extern block can't come from transpiled code.
There was a problem hiding this comment.
Right, which is why we probably didn't catch this. Do we want to be defensive here, or punt this PR?
thedataking
left a comment
There was a problem hiding this comment.
From offline discussion: we don't have a C pattern that is not UB and would trigger this pattern. We assume that the transpiler operates on valid C and that the refactorer operates on whatever Rust the transpiler outputs.
Did you mean to reply to this PR or #1935 ? Edit: if you meant 1935, could you approve 1924 so we can land it, since it's a legitimate bug fix? |
401842b to
d17fbe9
Compare
d17fbe9 to
cc214be
Compare
cc214be to
ddc9bbd
Compare
ddc9bbd to
d8aec07
Compare
d8aec07 to
1d944a8
Compare
1d944a8 to
9f5743c
Compare
9f5743c to
141dd0b
Compare
141dd0b to
b5dfa00
Compare
b5dfa00 to
53f3d1f
Compare
634c092 to
368089d
Compare
368089d to
dae85f6
Compare
My bad. Reviewing this one. |
thedataking
left a comment
There was a problem hiding this comment.
From offline discussion:
- we shouldn't add tests here since it gives the impression that this bug can be triggered
- would be better to
expect(...)here so this fails loudly. - alternatively, just fix the Abi to FALLBACK, don't add comments or tests.
dae85f6 to
010ee5f
Compare
010ee5f to
4d14595
Compare
4d14595 to
56e1808
Compare
56e1808 to
fe13ec8
Compare
fe13ec8 to
473fc3d
Compare
`Regression test: `test_reorganize_implicit_extern` (`tests/snapshots/reorganize_implicit_extern.rs`); on pre-fix code its implicit-`extern` declaration fails to merge with the `extern "C"` duplicate, producing an `extern "Rust"` block and a spurious `compute_1` rename.
Both sites now use `Abi::FALLBACK` (= `Abi::C { unwind: false }`).
`Regression test: `test_reorganize_implicit_extern`
(`tests/snapshots/reorganize_implicit_extern.rs`); on pre-fix code its
implicit-`extern` declaration fails to merge with the `extern "C"` duplicate,
producing an `extern "Rust"` block and a spurious `compute_1` rename.
`reorganize_definitions.rs:843-847` and `:1779-1782` both do:
```rust
let abi = m.abi.and_then(|abi| abi::lookup(&abi.symbol.as_str())).unwrap_or(Abi::Rust);
```
Rust's default ABI for `extern {}` blocks is `"C"` (rustc's own lowering uses
`Abi::FALLBACK`, which is `Abi::C`). Consequences:
- An implicit `extern { fn foo(); }` block never dedups against an
`extern "C" { fn foo(); }` declaration — the ABI-mismatch `continue` at
`:2144` in `find_foreign_item` skips it.
- Worse, its items are re-emitted by `into_items` via
`mk().extern_(Abi::Rust)` (`:1990`), silently changing the declared ABI of
foreign functions.
Latent only because transpiled code usually writes `extern "C"` explicitly.
Fix: fall back to `Abi::C { unwind: false }` (or `Abi::FALLBACK`).
473fc3d to
286a13f
Compare
Both sites now use
Abi::FALLBACK(=Abi::C { unwind: false }).Regression test:test_reorganize_implicit_extern(tests/snapshots/reorganize_implicit_extern.rs); on pre-fix code its implicit-externdeclaration fails to merge with theextern "C"duplicate, producing anextern "Rust"block and a spuriouscompute_1` rename.reorganize_definitions.rs:843-847and:1779-1782both do:Rust's default ABI for
extern {}blocks is"C"(rustc's own lowering usesAbi::FALLBACK, which isAbi::C). Consequences:extern { fn foo(); }block never dedups against anextern "C" { fn foo(); }declaration — the ABI-mismatchcontinueat:2144infind_foreign_itemskips it.into_itemsviamk().extern_(Abi::Rust)(:1990), silently changing the declared ABI offoreign functions.
Latent only because transpiled code usually writes
extern "C"explicitly.Fix: fall back to
Abi::C { unwind: false }(orAbi::FALLBACK).