Skip to content
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.

Commit 79254c6

Browse files
authoredDec 10, 2024
Unrolled build for #131558
Rollup merge of #131558 - sassman:feat/warnin-for-no-mangle-together-with-export-name, r=Urgau Lint on combining `#[no_mangle]` and `#[export_name]` This is my very first contribution to the compiler, even though I read the [chapter about lints](https://rustc-dev-guide.rust-lang.org/diagnostics.html) I'm not very certain that this ~~new lint is done right as a builtin lint~~ PR is right. I appreciate any guidance on how to improve the code. - Add test for issue #47446 - ~~Implement the new lint `mixed_export_name_and_no_mangle` as a builtin lint (not sure if that is the right way to go)~~ Extend `unused_attributes` lint - Add suggestion how to fix it <details> <summary>Old proposed new lint</summary> > The `mixed_export_name_and_no_mangle` lint detects usage of both `#[export_name]` and `#[no_mangle]` on the same item which results on `#[no_mangle]` being ignored. > > *warn-by-default* > > ### Example > > ```rust > #[no_mangle] // ignored > #[export_name = "foo"] // takes precedences > pub fn bar() {} > ``` > > ### Explanation > > The compiler will not respect the `#[no_mangle]` attribute when generating the symbol name for the function, as the `#[export_name]` attribute takes precedence. This can lead to confusion and is unnecessary. </details>
2 parents b597d2a + 7951d19 commit 79254c6

9 files changed

+143
-5
lines changed
 

‎Cargo.lock

+1
Original file line numberDiff line numberDiff line change
@@ -3445,6 +3445,7 @@ dependencies = [
34453445
"rustc_abi",
34463446
"rustc_arena",
34473447
"rustc_ast",
3448+
"rustc_ast_pretty",
34483449
"rustc_attr",
34493450
"rustc_data_structures",
34503451
"rustc_errors",

‎compiler/rustc_codegen_ssa/Cargo.toml

+1
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@ regex = "1.4"
1717
rustc_abi = { path = "../rustc_abi" }
1818
rustc_arena = { path = "../rustc_arena" }
1919
rustc_ast = { path = "../rustc_ast" }
20+
rustc_ast_pretty = { path = "../rustc_ast_pretty" }
2021
rustc_attr = { path = "../rustc_attr" }
2122
rustc_data_structures = { path = "../rustc_data_structures" }
2223
rustc_errors = { path = "../rustc_errors" }

‎compiler/rustc_codegen_ssa/messages.ftl

+5
Original file line numberDiff line numberDiff line change
@@ -201,6 +201,11 @@ codegen_ssa_missing_memory_ordering = Atomic intrinsic missing memory ordering
201201
codegen_ssa_missing_query_depgraph =
202202
found CGU-reuse attribute but `-Zquery-dep-graph` was not specified
203203
204+
codegen_ssa_mixed_export_name_and_no_mangle = `{$no_mangle_attr}` attribute may not be used in combination with `#[export_name]`
205+
.label = `{$no_mangle_attr}` is ignored
206+
.note = `#[export_name]` takes precedence
207+
.suggestion = remove the `{$no_mangle_attr}` attribute
208+
204209
codegen_ssa_msvc_missing_linker = the msvc targets depend on the msvc linker but `link.exe` was not found
205210
206211
codegen_ssa_multiple_external_func_decl = multiple declarations of external function `{$function}` from library `{$library_name}` have different calling conventions

‎compiler/rustc_codegen_ssa/src/codegen_attrs.rs

+54-3
Original file line numberDiff line numberDiff line change
@@ -3,11 +3,10 @@ use rustc_attr::{InlineAttr, InstructionSetAttr, OptimizeAttr, list_contains_nam
33
use rustc_data_structures::fx::FxHashMap;
44
use rustc_errors::codes::*;
55
use rustc_errors::{DiagMessage, SubdiagMessage, struct_span_code_err};
6-
use rustc_hir as hir;
76
use rustc_hir::def::DefKind;
87
use rustc_hir::def_id::{DefId, LOCAL_CRATE, LocalDefId};
98
use rustc_hir::weak_lang_items::WEAK_LANG_ITEMS;
10-
use rustc_hir::{LangItem, lang_items};
9+
use rustc_hir::{self as hir, HirId, LangItem, lang_items};
1110
use rustc_middle::middle::codegen_fn_attrs::{
1211
CodegenFnAttrFlags, CodegenFnAttrs, PatchableFunctionEntry,
1312
};
@@ -78,6 +77,7 @@ fn codegen_fn_attrs(tcx: TyCtxt<'_>, did: LocalDefId) -> CodegenFnAttrs {
7877
let mut inline_span = None;
7978
let mut link_ordinal_span = None;
8079
let mut no_sanitize_span = None;
80+
let mut mixed_export_name_no_mangle_lint_state = MixedExportNameAndNoMangleState::default();
8181

8282
for attr in attrs.iter() {
8383
// In some cases, attribute are only valid on functions, but it's the `check_attr`
@@ -116,7 +116,12 @@ fn codegen_fn_attrs(tcx: TyCtxt<'_>, did: LocalDefId) -> CodegenFnAttrs {
116116
sym::naked => codegen_fn_attrs.flags |= CodegenFnAttrFlags::NAKED,
117117
sym::no_mangle => {
118118
if tcx.opt_item_name(did.to_def_id()).is_some() {
119-
codegen_fn_attrs.flags |= CodegenFnAttrFlags::NO_MANGLE
119+
codegen_fn_attrs.flags |= CodegenFnAttrFlags::NO_MANGLE;
120+
mixed_export_name_no_mangle_lint_state.track_no_mangle(
121+
attr.span,
122+
tcx.local_def_id_to_hir_id(did),
123+
attr,
124+
);
120125
} else {
121126
tcx.dcx()
122127
.struct_span_err(
@@ -240,6 +245,7 @@ fn codegen_fn_attrs(tcx: TyCtxt<'_>, did: LocalDefId) -> CodegenFnAttrs {
240245
.emit();
241246
}
242247
codegen_fn_attrs.export_name = Some(s);
248+
mixed_export_name_no_mangle_lint_state.track_export_name(attr.span);
243249
}
244250
}
245251
sym::target_feature => {
@@ -513,6 +519,8 @@ fn codegen_fn_attrs(tcx: TyCtxt<'_>, did: LocalDefId) -> CodegenFnAttrs {
513519
}
514520
}
515521

522+
mixed_export_name_no_mangle_lint_state.lint_if_mixed(tcx);
523+
516524
codegen_fn_attrs.inline = attrs.iter().fold(InlineAttr::None, |ia, attr| {
517525
if !attr.has_name(sym::inline) {
518526
return ia;
@@ -779,6 +787,49 @@ fn check_link_name_xor_ordinal(
779787
}
780788
}
781789

790+
#[derive(Default)]
791+
struct MixedExportNameAndNoMangleState<'a> {
792+
export_name: Option<Span>,
793+
hir_id: Option<HirId>,
794+
no_mangle: Option<Span>,
795+
no_mangle_attr: Option<&'a ast::Attribute>,
796+
}
797+
798+
impl<'a> MixedExportNameAndNoMangleState<'a> {
799+
fn track_export_name(&mut self, span: Span) {
800+
self.export_name = Some(span);
801+
}
802+
803+
fn track_no_mangle(&mut self, span: Span, hir_id: HirId, attr_name: &'a ast::Attribute) {
804+
self.no_mangle = Some(span);
805+
self.hir_id = Some(hir_id);
806+
self.no_mangle_attr = Some(attr_name);
807+
}
808+
809+
/// Emit diagnostics if the lint condition is met.
810+
fn lint_if_mixed(self, tcx: TyCtxt<'_>) {
811+
if let Self {
812+
export_name: Some(export_name),
813+
no_mangle: Some(no_mangle),
814+
hir_id: Some(hir_id),
815+
no_mangle_attr: Some(no_mangle_attr),
816+
} = self
817+
{
818+
tcx.emit_node_span_lint(
819+
lint::builtin::UNUSED_ATTRIBUTES,
820+
hir_id,
821+
no_mangle,
822+
errors::MixedExportNameAndNoMangle {
823+
no_mangle,
824+
no_mangle_attr: rustc_ast_pretty::pprust::attribute_to_string(no_mangle_attr),
825+
export_name,
826+
removal_span: no_mangle,
827+
},
828+
);
829+
}
830+
}
831+
}
832+
782833
pub(crate) fn provide(providers: &mut Providers) {
783834
*providers = Providers { codegen_fn_attrs, should_inherit_track_caller, ..*providers };
784835
}

‎compiler/rustc_codegen_ssa/src/errors.rs

+13-1
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ use rustc_errors::codes::*;
1010
use rustc_errors::{
1111
Diag, DiagArgValue, DiagCtxtHandle, Diagnostic, EmissionGuarantee, IntoDiagArg, Level,
1212
};
13-
use rustc_macros::{Diagnostic, Subdiagnostic};
13+
use rustc_macros::{Diagnostic, LintDiagnostic, Subdiagnostic};
1414
use rustc_middle::ty::Ty;
1515
use rustc_middle::ty::layout::LayoutError;
1616
use rustc_span::{Span, Symbol};
@@ -1114,3 +1114,15 @@ impl<G: EmissionGuarantee> Diagnostic<'_, G> for TargetFeatureDisableOrEnable<'_
11141114
#[derive(Diagnostic)]
11151115
#[diag(codegen_ssa_aix_strip_not_used)]
11161116
pub(crate) struct AixStripNotUsed;
1117+
1118+
#[derive(LintDiagnostic)]
1119+
#[diag(codegen_ssa_mixed_export_name_and_no_mangle)]
1120+
pub(crate) struct MixedExportNameAndNoMangle {
1121+
#[label]
1122+
pub no_mangle: Span,
1123+
pub no_mangle_attr: String,
1124+
#[note]
1125+
pub export_name: Span,
1126+
#[suggestion(style = "verbose", code = "", applicability = "machine-applicable")]
1127+
pub removal_span: Span,
1128+
}

‎tests/ui/asm/naked-functions.rs

-1
Original file line numberDiff line numberDiff line change
@@ -219,7 +219,6 @@ pub unsafe extern "C" fn compatible_must_use_attributes() -> u64 {
219219

220220
#[export_name = "exported_function_name"]
221221
#[link_section = ".custom_section"]
222-
#[no_mangle]
223222
#[naked]
224223
pub unsafe extern "C" fn compatible_ffi_attributes_1() {
225224
naked_asm!("", options(raw));
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
// issue: rust-lang/rust#47446
2+
//@ run-rustfix
3+
//@ check-pass
4+
5+
#![warn(unused_attributes)]
6+
//~^ WARN `#[no_mangle]` attribute may not be used in combination with `#[export_name]` [unused_attributes]
7+
#[export_name = "foo"]
8+
pub fn bar() {}
9+
10+
//~^ WARN `#[unsafe(no_mangle)]` attribute may not be used in combination with `#[export_name]` [unused_attributes]
11+
#[export_name = "baz"]
12+
pub fn bak() {}
13+
14+
fn main() {}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
// issue: rust-lang/rust#47446
2+
//@ run-rustfix
3+
//@ check-pass
4+
5+
#![warn(unused_attributes)]
6+
#[no_mangle]
7+
//~^ WARN `#[no_mangle]` attribute may not be used in combination with `#[export_name]` [unused_attributes]
8+
#[export_name = "foo"]
9+
pub fn bar() {}
10+
11+
#[unsafe(no_mangle)]
12+
//~^ WARN `#[unsafe(no_mangle)]` attribute may not be used in combination with `#[export_name]` [unused_attributes]
13+
#[export_name = "baz"]
14+
pub fn bak() {}
15+
16+
fn main() {}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
warning: `#[no_mangle]` attribute may not be used in combination with `#[export_name]`
2+
--> $DIR/mixed_export_name_and_no_mangle.rs:6:1
3+
|
4+
LL | #[no_mangle]
5+
| ^^^^^^^^^^^^ `#[no_mangle]` is ignored
6+
|
7+
note: `#[export_name]` takes precedence
8+
--> $DIR/mixed_export_name_and_no_mangle.rs:8:1
9+
|
10+
LL | #[export_name = "foo"]
11+
| ^^^^^^^^^^^^^^^^^^^^^^
12+
note: the lint level is defined here
13+
--> $DIR/mixed_export_name_and_no_mangle.rs:5:9
14+
|
15+
LL | #![warn(unused_attributes)]
16+
| ^^^^^^^^^^^^^^^^^
17+
help: remove the `#[no_mangle]` attribute
18+
|
19+
LL - #[no_mangle]
20+
|
21+
22+
warning: `#[unsafe(no_mangle)]` attribute may not be used in combination with `#[export_name]`
23+
--> $DIR/mixed_export_name_and_no_mangle.rs:11:1
24+
|
25+
LL | #[unsafe(no_mangle)]
26+
| ^^^^^^^^^^^^^^^^^^^^ `#[unsafe(no_mangle)]` is ignored
27+
|
28+
note: `#[export_name]` takes precedence
29+
--> $DIR/mixed_export_name_and_no_mangle.rs:13:1
30+
|
31+
LL | #[export_name = "baz"]
32+
| ^^^^^^^^^^^^^^^^^^^^^^
33+
help: remove the `#[unsafe(no_mangle)]` attribute
34+
|
35+
LL - #[unsafe(no_mangle)]
36+
|
37+
38+
warning: 2 warnings emitted
39+

0 commit comments

Comments
 (0)
Failed to load comments.