fix: rust-lang/rust#47446
- Add test for issue 47446 - Implement the new lint lint_builtin_mixed_export_name_and_no_mangle - Add suggestion how to fix it
This commit is contained in:
parent
f00f68245e
commit
1696f534ab
9 changed files with 143 additions and 5 deletions
|
@ -3453,6 +3453,7 @@ dependencies = [
|
||||||
"rustc_abi",
|
"rustc_abi",
|
||||||
"rustc_arena",
|
"rustc_arena",
|
||||||
"rustc_ast",
|
"rustc_ast",
|
||||||
|
"rustc_ast_pretty",
|
||||||
"rustc_attr",
|
"rustc_attr",
|
||||||
"rustc_data_structures",
|
"rustc_data_structures",
|
||||||
"rustc_errors",
|
"rustc_errors",
|
||||||
|
|
|
@ -17,6 +17,7 @@ regex = "1.4"
|
||||||
rustc_abi = { path = "../rustc_abi" }
|
rustc_abi = { path = "../rustc_abi" }
|
||||||
rustc_arena = { path = "../rustc_arena" }
|
rustc_arena = { path = "../rustc_arena" }
|
||||||
rustc_ast = { path = "../rustc_ast" }
|
rustc_ast = { path = "../rustc_ast" }
|
||||||
|
rustc_ast_pretty = { path = "../rustc_ast_pretty" }
|
||||||
rustc_attr = { path = "../rustc_attr" }
|
rustc_attr = { path = "../rustc_attr" }
|
||||||
rustc_data_structures = { path = "../rustc_data_structures" }
|
rustc_data_structures = { path = "../rustc_data_structures" }
|
||||||
rustc_errors = { path = "../rustc_errors" }
|
rustc_errors = { path = "../rustc_errors" }
|
||||||
|
|
|
@ -201,6 +201,11 @@ codegen_ssa_missing_memory_ordering = Atomic intrinsic missing memory ordering
|
||||||
codegen_ssa_missing_query_depgraph =
|
codegen_ssa_missing_query_depgraph =
|
||||||
found CGU-reuse attribute but `-Zquery-dep-graph` was not specified
|
found CGU-reuse attribute but `-Zquery-dep-graph` was not specified
|
||||||
|
|
||||||
|
codegen_ssa_mixed_export_name_and_no_mangle = `{$no_mangle_attr}` attribute may not be used in combination with `#[export_name]`
|
||||||
|
.label = `{$no_mangle_attr}` is ignored
|
||||||
|
.note = `#[export_name]` takes precedence
|
||||||
|
.suggestion = remove the `{$no_mangle_attr}` attribute
|
||||||
|
|
||||||
codegen_ssa_msvc_missing_linker = the msvc targets depend on the msvc linker but `link.exe` was not found
|
codegen_ssa_msvc_missing_linker = the msvc targets depend on the msvc linker but `link.exe` was not found
|
||||||
|
|
||||||
codegen_ssa_multiple_external_func_decl = multiple declarations of external function `{$function}` from library `{$library_name}` have different calling conventions
|
codegen_ssa_multiple_external_func_decl = multiple declarations of external function `{$function}` from library `{$library_name}` have different calling conventions
|
||||||
|
|
|
@ -3,11 +3,10 @@ use rustc_attr::{InlineAttr, InstructionSetAttr, OptimizeAttr, list_contains_nam
|
||||||
use rustc_data_structures::fx::FxHashMap;
|
use rustc_data_structures::fx::FxHashMap;
|
||||||
use rustc_errors::codes::*;
|
use rustc_errors::codes::*;
|
||||||
use rustc_errors::{DiagMessage, SubdiagMessage, struct_span_code_err};
|
use rustc_errors::{DiagMessage, SubdiagMessage, struct_span_code_err};
|
||||||
use rustc_hir as hir;
|
|
||||||
use rustc_hir::def::DefKind;
|
use rustc_hir::def::DefKind;
|
||||||
use rustc_hir::def_id::{DefId, LOCAL_CRATE, LocalDefId};
|
use rustc_hir::def_id::{DefId, LOCAL_CRATE, LocalDefId};
|
||||||
use rustc_hir::weak_lang_items::WEAK_LANG_ITEMS;
|
use rustc_hir::weak_lang_items::WEAK_LANG_ITEMS;
|
||||||
use rustc_hir::{LangItem, lang_items};
|
use rustc_hir::{self as hir, HirId, LangItem, lang_items};
|
||||||
use rustc_middle::middle::codegen_fn_attrs::{
|
use rustc_middle::middle::codegen_fn_attrs::{
|
||||||
CodegenFnAttrFlags, CodegenFnAttrs, PatchableFunctionEntry,
|
CodegenFnAttrFlags, CodegenFnAttrs, PatchableFunctionEntry,
|
||||||
};
|
};
|
||||||
|
@ -78,6 +77,7 @@ fn codegen_fn_attrs(tcx: TyCtxt<'_>, did: LocalDefId) -> CodegenFnAttrs {
|
||||||
let mut inline_span = None;
|
let mut inline_span = None;
|
||||||
let mut link_ordinal_span = None;
|
let mut link_ordinal_span = None;
|
||||||
let mut no_sanitize_span = None;
|
let mut no_sanitize_span = None;
|
||||||
|
let mut mixed_export_name_no_mangle_lint_state = MixedExportNameAndNoMangleState::default();
|
||||||
|
|
||||||
for attr in attrs.iter() {
|
for attr in attrs.iter() {
|
||||||
// In some cases, attribute are only valid on functions, but it's the `check_attr`
|
// 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 {
|
||||||
sym::naked => codegen_fn_attrs.flags |= CodegenFnAttrFlags::NAKED,
|
sym::naked => codegen_fn_attrs.flags |= CodegenFnAttrFlags::NAKED,
|
||||||
sym::no_mangle => {
|
sym::no_mangle => {
|
||||||
if tcx.opt_item_name(did.to_def_id()).is_some() {
|
if tcx.opt_item_name(did.to_def_id()).is_some() {
|
||||||
codegen_fn_attrs.flags |= CodegenFnAttrFlags::NO_MANGLE
|
codegen_fn_attrs.flags |= CodegenFnAttrFlags::NO_MANGLE;
|
||||||
|
mixed_export_name_no_mangle_lint_state.track_no_mangle(
|
||||||
|
attr.span,
|
||||||
|
tcx.local_def_id_to_hir_id(did),
|
||||||
|
rustc_ast_pretty::pprust::attribute_to_string(attr),
|
||||||
|
);
|
||||||
} else {
|
} else {
|
||||||
tcx.dcx()
|
tcx.dcx()
|
||||||
.struct_span_err(
|
.struct_span_err(
|
||||||
|
@ -240,6 +245,7 @@ fn codegen_fn_attrs(tcx: TyCtxt<'_>, did: LocalDefId) -> CodegenFnAttrs {
|
||||||
.emit();
|
.emit();
|
||||||
}
|
}
|
||||||
codegen_fn_attrs.export_name = Some(s);
|
codegen_fn_attrs.export_name = Some(s);
|
||||||
|
mixed_export_name_no_mangle_lint_state.track_export_name(attr.span);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
sym::target_feature => {
|
sym::target_feature => {
|
||||||
|
@ -513,6 +519,8 @@ fn codegen_fn_attrs(tcx: TyCtxt<'_>, did: LocalDefId) -> CodegenFnAttrs {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
mixed_export_name_no_mangle_lint_state.lint_if_mixed(tcx);
|
||||||
|
|
||||||
codegen_fn_attrs.inline = attrs.iter().fold(InlineAttr::None, |ia, attr| {
|
codegen_fn_attrs.inline = attrs.iter().fold(InlineAttr::None, |ia, attr| {
|
||||||
if !attr.has_name(sym::inline) {
|
if !attr.has_name(sym::inline) {
|
||||||
return ia;
|
return ia;
|
||||||
|
@ -779,6 +787,49 @@ fn check_link_name_xor_ordinal(
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[derive(Default)]
|
||||||
|
struct MixedExportNameAndNoMangleState {
|
||||||
|
export_name: Option<Span>,
|
||||||
|
hir_id: Option<HirId>,
|
||||||
|
no_mangle: Option<Span>,
|
||||||
|
no_mangle_attr_name: Option<String>,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl MixedExportNameAndNoMangleState {
|
||||||
|
fn track_export_name(&mut self, span: Span) {
|
||||||
|
self.export_name = Some(span);
|
||||||
|
}
|
||||||
|
|
||||||
|
fn track_no_mangle(&mut self, span: Span, hir_id: HirId, attr_name: String) {
|
||||||
|
self.no_mangle = Some(span);
|
||||||
|
self.hir_id = Some(hir_id);
|
||||||
|
self.no_mangle_attr_name = Some(attr_name);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Emit diagnostics if the lint condition is met.
|
||||||
|
fn lint_if_mixed(self, tcx: TyCtxt<'_>) {
|
||||||
|
if let Self {
|
||||||
|
export_name: Some(export_name),
|
||||||
|
no_mangle: Some(no_mangle),
|
||||||
|
hir_id: Some(hir_id),
|
||||||
|
no_mangle_attr_name: Some(no_mangle_attr_name),
|
||||||
|
} = self
|
||||||
|
{
|
||||||
|
tcx.emit_node_span_lint(
|
||||||
|
lint::builtin::UNUSED_ATTRIBUTES,
|
||||||
|
hir_id,
|
||||||
|
no_mangle,
|
||||||
|
errors::MixedExportNameAndNoMangle {
|
||||||
|
no_mangle,
|
||||||
|
no_mangle_attr: no_mangle_attr_name,
|
||||||
|
export_name,
|
||||||
|
removal_span: no_mangle,
|
||||||
|
},
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
pub(crate) fn provide(providers: &mut Providers) {
|
pub(crate) fn provide(providers: &mut Providers) {
|
||||||
*providers = Providers { codegen_fn_attrs, should_inherit_track_caller, ..*providers };
|
*providers = Providers { codegen_fn_attrs, should_inherit_track_caller, ..*providers };
|
||||||
}
|
}
|
||||||
|
|
|
@ -10,7 +10,7 @@ use rustc_errors::codes::*;
|
||||||
use rustc_errors::{
|
use rustc_errors::{
|
||||||
Diag, DiagArgValue, DiagCtxtHandle, Diagnostic, EmissionGuarantee, IntoDiagArg, Level,
|
Diag, DiagArgValue, DiagCtxtHandle, Diagnostic, EmissionGuarantee, IntoDiagArg, Level,
|
||||||
};
|
};
|
||||||
use rustc_macros::{Diagnostic, Subdiagnostic};
|
use rustc_macros::{Diagnostic, LintDiagnostic, Subdiagnostic};
|
||||||
use rustc_middle::ty::Ty;
|
use rustc_middle::ty::Ty;
|
||||||
use rustc_middle::ty::layout::LayoutError;
|
use rustc_middle::ty::layout::LayoutError;
|
||||||
use rustc_span::{Span, Symbol};
|
use rustc_span::{Span, Symbol};
|
||||||
|
@ -1114,3 +1114,15 @@ impl<G: EmissionGuarantee> Diagnostic<'_, G> for TargetFeatureDisableOrEnable<'_
|
||||||
#[derive(Diagnostic)]
|
#[derive(Diagnostic)]
|
||||||
#[diag(codegen_ssa_aix_strip_not_used)]
|
#[diag(codegen_ssa_aix_strip_not_used)]
|
||||||
pub(crate) struct AixStripNotUsed;
|
pub(crate) struct AixStripNotUsed;
|
||||||
|
|
||||||
|
#[derive(LintDiagnostic)]
|
||||||
|
#[diag(codegen_ssa_mixed_export_name_and_no_mangle)]
|
||||||
|
pub(crate) struct MixedExportNameAndNoMangle {
|
||||||
|
#[label]
|
||||||
|
pub no_mangle: Span,
|
||||||
|
pub no_mangle_attr: String,
|
||||||
|
#[note]
|
||||||
|
pub export_name: Span,
|
||||||
|
#[suggestion(style = "verbose", code = "", applicability = "machine-applicable")]
|
||||||
|
pub removal_span: Span,
|
||||||
|
}
|
||||||
|
|
|
@ -219,7 +219,6 @@ pub unsafe extern "C" fn compatible_must_use_attributes() -> u64 {
|
||||||
|
|
||||||
#[export_name = "exported_function_name"]
|
#[export_name = "exported_function_name"]
|
||||||
#[link_section = ".custom_section"]
|
#[link_section = ".custom_section"]
|
||||||
#[no_mangle]
|
|
||||||
#[naked]
|
#[naked]
|
||||||
pub unsafe extern "C" fn compatible_ffi_attributes_1() {
|
pub unsafe extern "C" fn compatible_ffi_attributes_1() {
|
||||||
naked_asm!("", options(raw));
|
naked_asm!("", options(raw));
|
||||||
|
|
14
tests/ui/attributes/mixed_export_name_and_no_mangle.fixed
Normal file
14
tests/ui/attributes/mixed_export_name_and_no_mangle.fixed
Normal file
|
@ -0,0 +1,14 @@
|
||||||
|
// issue: rust-lang/rust#47446
|
||||||
|
//@ run-rustfix
|
||||||
|
//@ check-pass
|
||||||
|
|
||||||
|
#![warn(unused_attributes)]
|
||||||
|
//~^ WARN `#[no_mangle]` attribute may not be used in combination with `#[export_name]` [unused_attributes]
|
||||||
|
#[export_name = "foo"]
|
||||||
|
pub fn bar() {}
|
||||||
|
|
||||||
|
//~^ WARN `#[unsafe(no_mangle)]` attribute may not be used in combination with `#[export_name]` [unused_attributes]
|
||||||
|
#[export_name = "baz"]
|
||||||
|
pub fn bak() {}
|
||||||
|
|
||||||
|
fn main() {}
|
16
tests/ui/attributes/mixed_export_name_and_no_mangle.rs
Normal file
16
tests/ui/attributes/mixed_export_name_and_no_mangle.rs
Normal file
|
@ -0,0 +1,16 @@
|
||||||
|
// issue: rust-lang/rust#47446
|
||||||
|
//@ run-rustfix
|
||||||
|
//@ check-pass
|
||||||
|
|
||||||
|
#![warn(unused_attributes)]
|
||||||
|
#[no_mangle]
|
||||||
|
//~^ WARN `#[no_mangle]` attribute may not be used in combination with `#[export_name]` [unused_attributes]
|
||||||
|
#[export_name = "foo"]
|
||||||
|
pub fn bar() {}
|
||||||
|
|
||||||
|
#[unsafe(no_mangle)]
|
||||||
|
//~^ WARN `#[unsafe(no_mangle)]` attribute may not be used in combination with `#[export_name]` [unused_attributes]
|
||||||
|
#[export_name = "baz"]
|
||||||
|
pub fn bak() {}
|
||||||
|
|
||||||
|
fn main() {}
|
39
tests/ui/attributes/mixed_export_name_and_no_mangle.stderr
Normal file
39
tests/ui/attributes/mixed_export_name_and_no_mangle.stderr
Normal file
|
@ -0,0 +1,39 @@
|
||||||
|
warning: `#[no_mangle]` attribute may not be used in combination with `#[export_name]`
|
||||||
|
--> $DIR/mixed_export_name_and_no_mangle.rs:6:1
|
||||||
|
|
|
||||||
|
LL | #[no_mangle]
|
||||||
|
| ^^^^^^^^^^^^ `#[no_mangle]` is ignored
|
||||||
|
|
|
||||||
|
note: `#[export_name]` takes precedence
|
||||||
|
--> $DIR/mixed_export_name_and_no_mangle.rs:8:1
|
||||||
|
|
|
||||||
|
LL | #[export_name = "foo"]
|
||||||
|
| ^^^^^^^^^^^^^^^^^^^^^^
|
||||||
|
note: the lint level is defined here
|
||||||
|
--> $DIR/mixed_export_name_and_no_mangle.rs:5:9
|
||||||
|
|
|
||||||
|
LL | #![warn(unused_attributes)]
|
||||||
|
| ^^^^^^^^^^^^^^^^^
|
||||||
|
help: remove the `#[no_mangle]` attribute
|
||||||
|
|
|
||||||
|
LL - #[no_mangle]
|
||||||
|
|
|
||||||
|
|
||||||
|
warning: `#[unsafe(no_mangle)]` attribute may not be used in combination with `#[export_name]`
|
||||||
|
--> $DIR/mixed_export_name_and_no_mangle.rs:11:1
|
||||||
|
|
|
||||||
|
LL | #[unsafe(no_mangle)]
|
||||||
|
| ^^^^^^^^^^^^^^^^^^^^ `#[unsafe(no_mangle)]` is ignored
|
||||||
|
|
|
||||||
|
note: `#[export_name]` takes precedence
|
||||||
|
--> $DIR/mixed_export_name_and_no_mangle.rs:13:1
|
||||||
|
|
|
||||||
|
LL | #[export_name = "baz"]
|
||||||
|
| ^^^^^^^^^^^^^^^^^^^^^^
|
||||||
|
help: remove the `#[unsafe(no_mangle)]` attribute
|
||||||
|
|
|
||||||
|
LL - #[unsafe(no_mangle)]
|
||||||
|
|
|
||||||
|
|
||||||
|
warning: 2 warnings emitted
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue