Skip to content

Commit 737774e

Browse files
authored
Unrolled build for #143196
Rollup merge of #143196 - Periodic1911:link_section, r=oli-obk Port #[link_section] to the new attribute parsing infrastructure Ports link_section to the new attribute parsing infrastructure for #131229 (comment) r? `@oli-obk` cc `@JonathanBrouwer` `@jdonszelmann`
2 parents ad3b725 + 54cec0c commit 737774e

File tree

14 files changed

+101
-26
lines changed

14 files changed

+101
-26
lines changed

compiler/rustc_attr_data_structures/src/attributes.rs

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -256,6 +256,9 @@ pub enum AttributeKind {
256256
/// Represents `#[link_name]`.
257257
LinkName { name: Symbol, span: Span },
258258

259+
/// Represents [`#[link_section]`](https://doc.rust-lang.org/reference/abi.html#the-link_section-attribute)
260+
LinkSection { name: Symbol, span: Span },
261+
259262
/// Represents `#[loop_match]`.
260263
LoopMatch(Span),
261264

compiler/rustc_attr_data_structures/src/encode_cross_crate.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@ impl AttributeKind {
2424
DocComment { .. } => Yes,
2525
ExportName { .. } => Yes,
2626
Inline(..) => No,
27+
LinkSection { .. } => No,
2728
MacroTransparency(..) => Yes,
2829
Repr(..) => No,
2930
Stability { .. } => Yes,

compiler/rustc_attr_parsing/messages.ftl

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -99,6 +99,8 @@ attr_parsing_non_ident_feature =
9999
100100
attr_parsing_null_on_export = `export_name` may not contain null characters
101101
102+
attr_parsing_null_on_link_section = `link_section` may not contain null characters
103+
102104
attr_parsing_repr_ident =
103105
meta item in `repr` must be an identifier
104106

compiler/rustc_attr_parsing/src/attributes/link_attrs.rs

Lines changed: 30 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,12 @@
11
use rustc_attr_data_structures::AttributeKind;
2-
use rustc_attr_data_structures::AttributeKind::LinkName;
2+
use rustc_attr_data_structures::AttributeKind::{LinkName, LinkSection};
33
use rustc_feature::{AttributeTemplate, template};
44
use rustc_span::{Symbol, sym};
55

66
use crate::attributes::{AttributeOrder, OnDuplicate, SingleAttributeParser};
77
use crate::context::{AcceptContext, Stage};
88
use crate::parser::ArgParser;
9+
use crate::session_diagnostics::NullOnLinkSection;
910

1011
pub(crate) struct LinkNameParser;
1112

@@ -28,3 +29,31 @@ impl<S: Stage> SingleAttributeParser<S> for LinkNameParser {
2829
Some(LinkName { name, span: cx.attr_span })
2930
}
3031
}
32+
33+
pub(crate) struct LinkSectionParser;
34+
35+
impl<S: Stage> SingleAttributeParser<S> for LinkSectionParser {
36+
const PATH: &[Symbol] = &[sym::link_section];
37+
const ATTRIBUTE_ORDER: AttributeOrder = AttributeOrder::KeepFirst;
38+
const ON_DUPLICATE: OnDuplicate<S> = OnDuplicate::WarnButFutureError;
39+
const TEMPLATE: AttributeTemplate = template!(NameValueStr: "name");
40+
41+
fn convert(cx: &mut AcceptContext<'_, '_, S>, args: &ArgParser<'_>) -> Option<AttributeKind> {
42+
let Some(nv) = args.name_value() else {
43+
cx.expected_name_value(cx.attr_span, None);
44+
return None;
45+
};
46+
let Some(name) = nv.value_as_str() else {
47+
cx.expected_string_literal(nv.value_span, Some(nv.value_as_lit()));
48+
return None;
49+
};
50+
if name.as_str().contains('\0') {
51+
// `#[link_section = ...]` will be converted to a null-terminated string,
52+
// so it may not contain any null characters.
53+
cx.emit_err(NullOnLinkSection { span: cx.attr_span });
54+
return None;
55+
}
56+
57+
Some(LinkSection { name, span: cx.attr_span })
58+
}
59+
}

compiler/rustc_attr_parsing/src/context.rs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@ use crate::attributes::codegen_attrs::{
2222
use crate::attributes::confusables::ConfusablesParser;
2323
use crate::attributes::deprecation::DeprecationParser;
2424
use crate::attributes::inline::{InlineParser, RustcForceInlineParser};
25-
use crate::attributes::link_attrs::LinkNameParser;
25+
use crate::attributes::link_attrs::{LinkNameParser, LinkSectionParser};
2626
use crate::attributes::lint_helpers::{AsPtrParser, PubTransparentParser};
2727
use crate::attributes::loop_match::{ConstContinueParser, LoopMatchParser};
2828
use crate::attributes::must_use::MustUseParser;
@@ -123,6 +123,7 @@ attribute_parsers!(
123123
Single<ExportNameParser>,
124124
Single<InlineParser>,
125125
Single<LinkNameParser>,
126+
Single<LinkSectionParser>,
126127
Single<LoopMatchParser>,
127128
Single<MayDangleParser>,
128129
Single<MustUseParser>,

compiler/rustc_attr_parsing/src/session_diagnostics.rs

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -452,6 +452,13 @@ pub(crate) struct NullOnExport {
452452
pub span: Span,
453453
}
454454

455+
#[derive(Diagnostic)]
456+
#[diag(attr_parsing_null_on_link_section, code = E0648)]
457+
pub(crate) struct NullOnLinkSection {
458+
#[primary_span]
459+
pub span: Span,
460+
}
461+
455462
#[derive(Diagnostic)]
456463
#[diag(attr_parsing_stability_outside_std, code = E0734)]
457464
pub(crate) struct StabilityOutsideStd {

compiler/rustc_codegen_ssa/src/codegen_attrs.rs

Lines changed: 3 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -124,6 +124,9 @@ fn codegen_fn_attrs(tcx: TyCtxt<'_>, did: LocalDefId) -> CodegenFnAttrs {
124124
AttributeKind::Naked(_) => codegen_fn_attrs.flags |= CodegenFnAttrFlags::NAKED,
125125
AttributeKind::Align { align, .. } => codegen_fn_attrs.alignment = Some(*align),
126126
AttributeKind::LinkName { name, .. } => codegen_fn_attrs.link_name = Some(*name),
127+
AttributeKind::LinkSection { name, .. } => {
128+
codegen_fn_attrs.link_section = Some(*name)
129+
}
127130
AttributeKind::NoMangle(attr_span) => {
128131
if tcx.opt_item_name(did.to_def_id()).is_some() {
129132
codegen_fn_attrs.flags |= CodegenFnAttrFlags::NO_MANGLE;
@@ -253,16 +256,6 @@ fn codegen_fn_attrs(tcx: TyCtxt<'_>, did: LocalDefId) -> CodegenFnAttrs {
253256
}
254257
}
255258
}
256-
sym::link_section => {
257-
if let Some(val) = attr.value_str() {
258-
if val.as_str().bytes().any(|b| b == 0) {
259-
let msg = format!("illegal null byte in link_section value: `{val}`");
260-
tcx.dcx().span_err(attr.span(), msg);
261-
} else {
262-
codegen_fn_attrs.link_section = Some(val);
263-
}
264-
}
265-
}
266259
sym::link_ordinal => {
267260
link_ordinal_span = Some(attr.span());
268261
if let ordinal @ Some(_) = check_link_ordinal(tcx, attr) {

compiler/rustc_passes/src/check_attr.rs

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -177,6 +177,9 @@ impl<'tcx> CheckAttrVisitor<'tcx> {
177177
Attribute::Parsed(AttributeKind::Align { align, span: repr_span }) => {
178178
self.check_align(span, target, *align, *repr_span)
179179
}
180+
Attribute::Parsed(AttributeKind::LinkSection { span: attr_span, .. }) => {
181+
self.check_link_section(hir_id, *attr_span, span, target)
182+
}
180183
Attribute::Parsed(AttributeKind::Naked(attr_span)) => {
181184
self.check_naked(hir_id, *attr_span, span, target)
182185
}
@@ -286,7 +289,6 @@ impl<'tcx> CheckAttrVisitor<'tcx> {
286289
[sym::ffi_const, ..] => self.check_ffi_const(attr.span(), target),
287290
[sym::link_ordinal, ..] => self.check_link_ordinal(attr, span, target),
288291
[sym::link, ..] => self.check_link(hir_id, attr, span, target),
289-
[sym::link_section, ..] => self.check_link_section(hir_id, attr, span, target),
290292
[sym::macro_use, ..] | [sym::macro_escape, ..] => {
291293
self.check_macro_use(hir_id, attr, target)
292294
}
@@ -1831,23 +1833,23 @@ impl<'tcx> CheckAttrVisitor<'tcx> {
18311833
}
18321834

18331835
/// Checks if `#[link_section]` is applied to a function or static.
1834-
fn check_link_section(&self, hir_id: HirId, attr: &Attribute, span: Span, target: Target) {
1836+
fn check_link_section(&self, hir_id: HirId, attr_span: Span, span: Span, target: Target) {
18351837
match target {
18361838
Target::Static | Target::Fn | Target::Method(..) => {}
18371839
// FIXME(#80564): We permit struct fields, match arms and macro defs to have an
18381840
// `#[link_section]` attribute with just a lint, because we previously
18391841
// erroneously allowed it and some crates used it accidentally, to be compatible
18401842
// with crates depending on them, we can't throw an error here.
18411843
Target::Field | Target::Arm | Target::MacroDef => {
1842-
self.inline_attr_str_error_with_macro_def(hir_id, attr.span(), "link_section");
1844+
self.inline_attr_str_error_with_macro_def(hir_id, attr_span, "link_section");
18431845
}
18441846
_ => {
18451847
// FIXME: #[link_section] was previously allowed on non-functions/statics and some
18461848
// crates used this, so only emit a warning.
18471849
self.tcx.emit_node_span_lint(
18481850
UNUSED_ATTRIBUTES,
18491851
hir_id,
1850-
attr.span(),
1852+
attr_span,
18511853
errors::LinkSection { span },
18521854
);
18531855
}

src/librustdoc/clean/types.rs

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -753,9 +753,12 @@ impl Item {
753753
.other_attrs
754754
.iter()
755755
.filter_map(|attr| {
756+
if let hir::Attribute::Parsed(AttributeKind::LinkSection { name, .. }) = attr {
757+
Some(format!("#[link_section = \"{name}\"]"))
758+
}
756759
// NoMangle is special cased, as it appears in HTML output, and we want to show it in source form, not HIR printing.
757760
// It is also used by cargo-semver-checks.
758-
if let hir::Attribute::Parsed(AttributeKind::NoMangle(..)) = attr {
761+
else if let hir::Attribute::Parsed(AttributeKind::NoMangle(..)) = attr {
759762
Some("#[no_mangle]".to_string())
760763
} else if let hir::Attribute::Parsed(AttributeKind::ExportName { name, .. }) = attr
761764
{
Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
//@ edition: 2021
2+
#![no_std]
3+
4+
//@ is "$.index[?(@.name=='example')].attrs" '["#[link_section = \".text\"]"]'
5+
#[link_section = ".text"]
6+
pub extern "C" fn example() {}
Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
//@ edition: 2024
2+
#![no_std]
3+
4+
// Since the 2024 edition the link_section attribute must use the unsafe qualification.
5+
// However, the unsafe qualification is not shown by rustdoc.
6+
7+
//@ is "$.index[?(@.name=='example')].attrs" '["#[link_section = \".text\"]"]'
8+
#[unsafe(link_section = ".text")]
9+
pub extern "C" fn example() {}

tests/ui/feature-gates/issue-43106-gating-of-builtin-attrs.stderr

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -387,14 +387,6 @@ LL | #![link()]
387387
|
388388
= warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
389389

390-
warning: attribute should be applied to a function or static
391-
--> $DIR/issue-43106-gating-of-builtin-attrs.rs:69:1
392-
|
393-
LL | #![link_section = "1800"]
394-
| ^^^^^^^^^^^^^^^^^^^^^^^^^ not a function or static
395-
|
396-
= warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
397-
398390
warning: attribute should be applied to a function definition
399391
--> $DIR/issue-43106-gating-of-builtin-attrs.rs:62:1
400392
|
@@ -411,6 +403,14 @@ LL | #![link_name = "1900"]
411403
|
412404
= warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
413405

406+
warning: attribute should be applied to a function or static
407+
--> $DIR/issue-43106-gating-of-builtin-attrs.rs:69:1
408+
|
409+
LL | #![link_section = "1800"]
410+
| ^^^^^^^^^^^^^^^^^^^^^^^^^ not a function or static
411+
|
412+
= warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
413+
414414
warning: `#[must_use]` has no effect when applied to a module
415415
--> $DIR/issue-43106-gating-of-builtin-attrs.rs:72:1
416416
|

tests/ui/lint/unused/unused-attr-duplicate.rs

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -102,4 +102,10 @@ pub fn no_mangle_test() {}
102102
#[used] //~ ERROR unused attribute
103103
static FOO: u32 = 0;
104104

105+
#[link_section = ".text"]
106+
//~^ ERROR unused attribute
107+
//~| WARN this was previously accepted
108+
#[link_section = ".bss"]
109+
pub extern "C" fn example() {}
110+
105111
fn main() {}

tests/ui/lint/unused/unused-attr-duplicate.stderr

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -289,5 +289,18 @@ note: attribute also specified here
289289
LL | #[used]
290290
| ^^^^^^^
291291

292-
error: aborting due to 23 previous errors
292+
error: unused attribute
293+
--> $DIR/unused-attr-duplicate.rs:105:1
294+
|
295+
LL | #[link_section = ".text"]
296+
| ^^^^^^^^^^^^^^^^^^^^^^^^^ help: remove this attribute
297+
|
298+
note: attribute also specified here
299+
--> $DIR/unused-attr-duplicate.rs:108:1
300+
|
301+
LL | #[link_section = ".bss"]
302+
| ^^^^^^^^^^^^^^^^^^^^^^^^
303+
= warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
304+
305+
error: aborting due to 24 previous errors
293306

0 commit comments

Comments
 (0)