Skip to content

Issue an error when using no_mangle on language items #140203

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

Conversation

alexandruradovici
Copy link
Contributor

@alexandruradovici alexandruradovici commented Apr 23, 2025

This pull requests adds the code to issue an error or a warning when using no_mangle on language items. This should detail why the undefined symbol error is issued for the code described in #139923.

The pull request adds two ui tests, one testing the error and the other one the warning.

I would love some feedback here, as I am not sure that the error and warning are issues using the right API.

@rustbot
Copy link
Collaborator

rustbot commented Apr 23, 2025

r? @petrochenkov

rustbot has assigned @petrochenkov.
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 A-attributes Area: Attributes (`#[…]`, `#![…]`) S-waiting-on-review Status: Awaiting review from the assignee but also interested parties. T-compiler Relevant to the compiler team, which will review and decide on the PR/issue. labels Apr 23, 2025
@alexandruradovici
Copy link
Contributor Author

r? @bjorn3

@rust-log-analyzer

This comment has been minimized.

@alexandruradovici
Copy link
Contributor Author

alexandruradovici commented Apr 23, 2025

This fails due to a test that defines #[panic_handler] in a wrong place that also defines #[no_mangle].

#[panic_handler] //~ ERROR `panic_impl` lang item must be applied to a function
#[no_mangle]
static X: u32 = 42;

This somehow seems to be an error priority issue, the error that this pull request issues is correct.

I am not sure exactly how to avoid this, as I don't think checking that the target is a function is correct, as some language items are not functions.

@Noratrieb
Copy link
Member

This fails due to a test that defines #[panic_handler] in a wrong place that also defines #[no_mangle].

#[panic_handler] //~ ERROR `panic_impl` lang item must be applied to a function
#[no_mangle]
static X: u32 = 42;

This somehow seems to be an error priority issue, the error that this pull request issues is correct.

I am not sure exactly how to avoid this, as I don't think checking that the target is a function is correct, as some language items are not functions.

you can probably just fix the test if you look at the history of the test and ensure that what it's trying to test is still tested

@alexandruradovici
Copy link
Contributor Author

alexandruradovici commented Apr 25, 2025

Thank you @Noratrieb

I deleted the no_mangle attribute from the ui/panic-handler/panic-handler-wrong-location. I am not sure why that was placed there, but as it now is an error, I think this should be correct. I might be wrong though, so any feedback is welcome.

My understanding is that the test should verify that the panic_handler attribute is used on a function. The no_mangle attribute should impact it in any way. The test still issues the same error, panic_impl lang item must be applied to a function, when the no_mangle is deleted.

@alexandruradovici alexandruradovici marked this pull request as ready for review April 28, 2025 08:32
@rustbot
Copy link
Collaborator

rustbot commented Apr 28, 2025

Some changes occurred in compiler/rustc_codegen_ssa/src/codegen_attrs.rs

cc @jdonszelmann

Some changes occurred in compiler/rustc_codegen_ssa

cc @WaffleLapkin

if WEAK_LANG_ITEMS.contains(&lang_item) {
codegen_fn_attrs.flags |= CodegenFnAttrFlags::RUSTC_STD_INTERNAL_SYMBOL;
if has_no_mangle {
Copy link
Member

Choose a reason for hiding this comment

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

This code is only running when you are defining a lang item. I think it should prevent all combinations of #[rustc_std_internal_symbol] and #[no_mangle]. Can you move it below the lang_items::extract if?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Just to make sure I understand this correctly, you're suggesting to add another if after the lang_items::extract:

if codegen_fn_attrs.flags.contains(CodegenFnAttrFlags::NO_MANGLE) {
  if is_weak_symbol {
   // issue error
  } else 
  if codegen_fn_attrs.flags.contains(CodegenFnAttrFlags::RUSTC_STD_INTERNAL_SYMBOL) {
    // issue warning
  } 
}

Copy link
Member

Choose a reason for hiding this comment

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

Looking at it a bit more careful, I think keeping the error in the same location would be fine. The warning should be moved out of the lang item if however.

Also I noticed that you didn't make the warning a future incompat warning: https://rustc-dev-guide.rust-lang.org/diagnostics.html#future-incompatible-lints

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Looking at it a bit more careful, I think keeping the error in the same location would be fine. The warning should be moved out of the lang item if however.

Got it.

Also I noticed that you didn't make the warning a future incompat warning: https://rustc-dev-guide.rust-lang.org/diagnostics.html#future-incompatible-lints

Yep, I wasn't sure if this was the indented way, I'll change it. I have two questions here:

  • what issue should I reference?
  • what should be the reason? FutureReleaseErrorDontReportInDeps?

Copy link
Member

Choose a reason for hiding this comment

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

FutureReleaseErrorReportInDeps should be fine as reason. We don't need to emit a future incompat error for long given that #[rustc_std_internal_symbol] is unstable. As for the issue, that would be a newly created tracking issue for this future incompat warning.

Copy link
Member

Choose a reason for hiding this comment

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

On the other hand, the nightly versions already issue linking errors.

Yeah. I think emitting an error immediately for this case is fine.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Do you have an example of a language item that would emit a warning? I am not able to find one that would fit the criteria and I want to have a test for it.

Copy link
Member

@bjorn3 bjorn3 Apr 30, 2025

Choose a reason for hiding this comment

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

I think the only lang items for which #[no_mangle] is actively harmful are those that are weak lang items or those that are generic. Weak lang items would be a hard error and generic lang items don't allow #[no_mangle] already I think. Maybe just omit the warning case?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I think I agree, as it turns out really difficult to get a case where the warning is issued.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I modified the code to issue just the error.

@rust-log-analyzer

This comment has been minimized.

)
.with_note("The linker requires specific names for internal language items.")
.with_note("If you are trying to prevent mangling to ease debugging, many")
.with_note("debuggers support a command such as `rbreak {sym}` to")
Copy link
Member

Choose a reason for hiding this comment

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

You need to use format!() for the {sym} to be replaced by the value of sym.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I don't think @ppannuto purpose was rot replace these. In any case, we would need the mangled name. Is there any way to get it, as I am assuming that mangling is performed later on.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I used the local name to replace sym as anyway this would be a regular expression match, but it is the name before the #[rustc_std_internal_symbol]

Comment on lines 633 to 637
let label = if let Some(lang_item) = lang_item {
format!("should be the {} item", lang_item.name())
} else {
format!("should be the internal language item")
};
Copy link
Member

Choose a reason for hiding this comment

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

I don't think this label is useful.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I wanted a way to show the user the problematic item, not just the attribute.

Comment on lines 650 to 653
if let Some(span) = span {
let label_attr = format!("this defines it as the `{}` item", lang_item.name());
err = err.with_span_label(span, label_attr);
}
Copy link
Member

Choose a reason for hiding this comment

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

This leaks the internal lang item name for #[panic_handler].

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Is there any other way to say what language item this is? I have not seen any way of saying which language item it is.

Copy link
Member

Choose a reason for hiding this comment

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

For #[panic_handler] we should say anything about lang items at all (it would be leaking an internal implementation detail) and for the rest I'm not sure it is all that useful anyway.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I deleted it for now.

Comment on lines 654 to 649
if let Some(link_name) = lang_item.link_name() {
let renamed =
format!("In this case it is automatically renamed to `{}`", link_name);
err = err.with_note(renamed);
}
Copy link
Member

Choose a reason for hiding this comment

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

This is showing the name before #[rustc_std_internal_symbol] mangling.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Is there any way to get the mangled name? I am assuming no, as the mangling is done later on.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I tried this:

let instance = Instance::mono(tcx, did.into());
let name = tcx.symbol_name(instance).name;

but it throws a cycle detected error.

@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 Apr 30, 2025
@alexandruradovici alexandruradovici changed the title Issue an error or warning when using no_mangle on language items Issue an error when using no_mangle on language items Apr 30, 2025
@rust-log-analyzer

This comment has been minimized.

Copy link
Member

@bjorn3 bjorn3 left a comment

Choose a reason for hiding this comment

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

r=me with the commented out code removed.

@bjorn3
Copy link
Member

bjorn3 commented Apr 30, 2025

Would you mind squashing your changes?

@alexandruradovici alexandruradovici force-pushed the error_for_no_mangle_weak_language_items branch from 43114d3 to 51a0bf0 Compare April 30, 2025 11:52
@alexandruradovici
Copy link
Contributor Author

Would you mind squashing your changes?

Done

add suggestion on how to add a panic breakpoint

Co-authored-by: Pat Pannuto <pat.pannuto@gmail.com>
delete no_mangle from ui/panic-handler/panic-handler-wrong-location test

issue an error for the usage of #[no_mangle] on internal language items

delete the comments

add newline

rephrase note

Co-authored-by: bjorn3 <17426603+bjorn3@users.noreply.github.com>
update error not to leak implementation details

delete no_mangle_span

Co-authored-by: bjorn3 <17426603+bjorn3@users.noreply.github.com>
delete commented code
@alexandruradovici alexandruradovici force-pushed the error_for_no_mangle_weak_language_items branch from 51a0bf0 to 07c7e5f Compare April 30, 2025 11:54
@bjorn3
Copy link
Member

bjorn3 commented Apr 30, 2025

@bors r+

@bors
Copy link
Collaborator

bors commented Apr 30, 2025

📌 Commit 07c7e5f has been approved by bjorn3

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-author Status: This is awaiting some action (such as code changes or more information) from the author. labels Apr 30, 2025
bors added a commit to rust-lang-ci/rust that referenced this pull request Apr 30, 2025
…iaskrgr

Rollup of 9 pull requests

Successful merges:

 - rust-lang#134232 (Share the naked asm impl between cg_ssa and cg_clif)
 - rust-lang#139624 (Don't allow flattened format_args in const.)
 - rust-lang#140090 (Check bare function idents for non snake-case name)
 - rust-lang#140203 (Issue an error when using `no_mangle` on language items)
 - rust-lang#140450 (ast: Remove token visiting from AST visitor)
 - rust-lang#140498 (Misc tweaks to HIR typeck (mostly w.r.t. checking calls))
 - rust-lang#140504 (transmutability: ensure_sufficient_stack when answering query)
 - rust-lang#140506 (unstable-book: fix capitalization)
 - rust-lang#140516 (Replace use of rustc_type_ir by rustc_middle)

Failed merges:

 - rust-lang#140374 (Resolve instance for SymFn in global/naked asm)

r? `@ghost`
`@rustbot` modify labels: rollup
@bors bors merged commit 1a64f2c into rust-lang:master Apr 30, 2025
6 checks passed
@rustbot rustbot added this to the 1.88.0 milestone Apr 30, 2025
rust-timer added a commit to rust-lang-ci/rust that referenced this pull request Apr 30, 2025
Rollup merge of rust-lang#140203 - Wyliodrin:error_for_no_mangle_weak_language_items, r=bjorn3

Issue an error when using `no_mangle` on language items

This pull requests adds the code to issue an error or a warning when using `no_mangle` on language items. This should detail why the `undefined symbol` error is issued for the code described in rust-lang#139923.

The pull request adds two ui tests, one testing the error and the other one the warning.

I would love some feedback here, as I am not sure that the error and warning are issues using the right API.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
A-attributes Area: Attributes (`#[…]`, `#![…]`) 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