about summary refs log tree commit diff
path: root/compiler/rustc_attr_parsing/src
diff options
context:
space:
mode:
Diffstat (limited to 'compiler/rustc_attr_parsing/src')
-rw-r--r--compiler/rustc_attr_parsing/src/attributes/link_attrs.rs31
-rw-r--r--compiler/rustc_attr_parsing/src/context.rs3
-rw-r--r--compiler/rustc_attr_parsing/src/session_diagnostics.rs7
3 files changed, 39 insertions, 2 deletions
diff --git a/compiler/rustc_attr_parsing/src/attributes/link_attrs.rs b/compiler/rustc_attr_parsing/src/attributes/link_attrs.rs
index 740222178ed..e298053ab76 100644
--- a/compiler/rustc_attr_parsing/src/attributes/link_attrs.rs
+++ b/compiler/rustc_attr_parsing/src/attributes/link_attrs.rs
@@ -1,11 +1,12 @@
 use rustc_attr_data_structures::AttributeKind;
-use rustc_attr_data_structures::AttributeKind::LinkName;
+use rustc_attr_data_structures::AttributeKind::{LinkName, LinkSection};
 use rustc_feature::{AttributeTemplate, template};
 use rustc_span::{Symbol, sym};
 
 use crate::attributes::{AttributeOrder, OnDuplicate, SingleAttributeParser};
 use crate::context::{AcceptContext, Stage};
 use crate::parser::ArgParser;
+use crate::session_diagnostics::NullOnLinkSection;
 
 pub(crate) struct LinkNameParser;
 
@@ -28,3 +29,31 @@ impl<S: Stage> SingleAttributeParser<S> for LinkNameParser {
         Some(LinkName { name, span: cx.attr_span })
     }
 }
+
+pub(crate) struct LinkSectionParser;
+
+impl<S: Stage> SingleAttributeParser<S> for LinkSectionParser {
+    const PATH: &[Symbol] = &[sym::link_section];
+    const ATTRIBUTE_ORDER: AttributeOrder = AttributeOrder::KeepFirst;
+    const ON_DUPLICATE: OnDuplicate<S> = OnDuplicate::WarnButFutureError;
+    const TEMPLATE: AttributeTemplate = template!(NameValueStr: "name");
+
+    fn convert(cx: &mut AcceptContext<'_, '_, S>, args: &ArgParser<'_>) -> Option<AttributeKind> {
+        let Some(nv) = args.name_value() else {
+            cx.expected_name_value(cx.attr_span, None);
+            return None;
+        };
+        let Some(name) = nv.value_as_str() else {
+            cx.expected_string_literal(nv.value_span, Some(nv.value_as_lit()));
+            return None;
+        };
+        if name.as_str().contains('\0') {
+            // `#[link_section = ...]` will be converted to a null-terminated string,
+            // so it may not contain any null characters.
+            cx.emit_err(NullOnLinkSection { span: cx.attr_span });
+            return None;
+        }
+
+        Some(LinkSection { name, span: cx.attr_span })
+    }
+}
diff --git a/compiler/rustc_attr_parsing/src/context.rs b/compiler/rustc_attr_parsing/src/context.rs
index 1ac41b9c7e8..eee6d860550 100644
--- a/compiler/rustc_attr_parsing/src/context.rs
+++ b/compiler/rustc_attr_parsing/src/context.rs
@@ -22,7 +22,7 @@ use crate::attributes::codegen_attrs::{
 use crate::attributes::confusables::ConfusablesParser;
 use crate::attributes::deprecation::DeprecationParser;
 use crate::attributes::inline::{InlineParser, RustcForceInlineParser};
-use crate::attributes::link_attrs::LinkNameParser;
+use crate::attributes::link_attrs::{LinkNameParser, LinkSectionParser};
 use crate::attributes::lint_helpers::{AsPtrParser, PubTransparentParser};
 use crate::attributes::loop_match::{ConstContinueParser, LoopMatchParser};
 use crate::attributes::must_use::MustUseParser;
@@ -123,6 +123,7 @@ attribute_parsers!(
         Single<ExportNameParser>,
         Single<InlineParser>,
         Single<LinkNameParser>,
+        Single<LinkSectionParser>,
         Single<LoopMatchParser>,
         Single<MayDangleParser>,
         Single<MustUseParser>,
diff --git a/compiler/rustc_attr_parsing/src/session_diagnostics.rs b/compiler/rustc_attr_parsing/src/session_diagnostics.rs
index 7cfce579979..53aafaa714f 100644
--- a/compiler/rustc_attr_parsing/src/session_diagnostics.rs
+++ b/compiler/rustc_attr_parsing/src/session_diagnostics.rs
@@ -453,6 +453,13 @@ pub(crate) struct NullOnExport {
 }
 
 #[derive(Diagnostic)]
+#[diag(attr_parsing_null_on_link_section, code = E0648)]
+pub(crate) struct NullOnLinkSection {
+    #[primary_span]
+    pub span: Span,
+}
+
+#[derive(Diagnostic)]
 #[diag(attr_parsing_stability_outside_std, code = E0734)]
 pub(crate) struct StabilityOutsideStd {
     #[primary_span]