Skip to content

Commit 3873d4d

Browse files
committed
Auto merge of #158595 - JonathanBrouwer:rollup-vgnGLp0, r=JonathanBrouwer
Rollup of 7 pull requests Successful merges: - #158073 (bootstrap: fix panic when repo path contains spaces by switching to CARGO_ENCODED_RUSTFLAGS) - #158256 (Avoid parser panics bubbling out to proc macros) - #158561 (Avoid building rustdoc for tests without doctests) - #158562 (Improve tracing of steps in bootstrap) - #157445 (Allow section override when using patchable-function-entries) - #158327 (Move attribute and keyword docs from `std` to `core`) - #158591 (Fix spacing issue for unused parentheses lint)
2 parents 0966944 + cdfa297 commit 3873d4d

35 files changed

Lines changed: 472 additions & 179 deletions

File tree

compiler/rustc_attr_parsing/src/attributes/codegen_attrs.rs

Lines changed: 37 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -8,9 +8,9 @@ use rustc_span::edition::Edition::Edition2024;
88
use super::prelude::*;
99
use crate::attributes::AttributeSafety;
1010
use crate::session_diagnostics::{
11-
EmptyExportName, NakedFunctionIncompatibleAttribute, NullOnExport, NullOnObjcClass,
12-
NullOnObjcSelector, ObjcClassExpectedStringLiteral, ObjcSelectorExpectedStringLiteral,
13-
SanitizeInvalidStatic, TargetFeatureOnLangItem,
11+
EmptyExportName, EmptySection, NakedFunctionIncompatibleAttribute, NullOnExport,
12+
NullOnObjcClass, NullOnObjcSelector, NullOnSection, ObjcClassExpectedStringLiteral,
13+
ObjcSelectorExpectedStringLiteral, SanitizeInvalidStatic, TargetFeatureOnLangItem,
1414
};
1515
use crate::target_checking::Policy::AllowSilent;
1616

@@ -795,82 +795,94 @@ pub(crate) struct PatchableFunctionEntryParser;
795795
impl SingleAttributeParser for PatchableFunctionEntryParser {
796796
const PATH: &[Symbol] = &[sym::patchable_function_entry];
797797
const ALLOWED_TARGETS: AllowedTargets<'_> = AllowedTargets::AllowList(&[Allow(Target::Fn)]);
798-
const TEMPLATE: AttributeTemplate = template!(List: &["prefix_nops = m, entry_nops = n"]);
798+
const TEMPLATE: AttributeTemplate =
799+
template!(List: &["prefix_nops = m, entry_nops = n, section = \"section\""]);
799800
const STABILITY: AttributeStability = unstable!(patchable_function_entry);
800801

801802
fn convert(cx: &mut AcceptContext<'_, '_>, args: &ArgParser) -> Option<AttributeKind> {
802803
let meta_item_list = cx.expect_list(args, cx.attr_span)?;
803804

804805
let mut prefix = None;
805806
let mut entry = None;
807+
let mut section = None;
806808

807809
if meta_item_list.len() == 0 {
808810
cx.adcx().expected_at_least_one_argument(meta_item_list.span);
809811
return None;
810812
}
811813

812-
let mut errored = false;
813-
814814
for item in meta_item_list.mixed() {
815815
let Some((ident, value)) = cx.expect_name_value(item, item.span(), None) else {
816-
continue;
816+
return None;
817817
};
818818

819819
let attrib_to_write = match ident.name {
820820
sym::prefix_nops => {
821821
// Duplicate prefixes are not allowed
822822
if prefix.is_some() {
823-
errored = true;
824823
cx.adcx().duplicate_key(ident.span, sym::prefix_nops);
825-
continue;
824+
return None;
826825
}
827826
&mut prefix
828827
}
829828
sym::entry_nops => {
830829
// Duplicate entries are not allowed
831830
if entry.is_some() {
832-
errored = true;
833831
cx.adcx().duplicate_key(ident.span, sym::entry_nops);
834-
continue;
832+
return None;
835833
}
836834
&mut entry
837835
}
836+
sym::section => {
837+
// Duplicate entries are not allowed
838+
if section.is_some() {
839+
cx.adcx().duplicate_key(ident.span, sym::section);
840+
return None;
841+
}
842+
// Only a string type value is allowed.
843+
let Some(value_str) = value.value_as_str() else {
844+
cx.adcx().expect_string_literal(value);
845+
return None;
846+
};
847+
// The section name does not allow null characters.
848+
if value_str.as_str().contains('\0') {
849+
cx.emit_err(NullOnSection { span: value.value_span });
850+
}
851+
// The section name is not allowed to be empty, LLVM does
852+
// not allow them.
853+
if value_str.is_empty() {
854+
cx.emit_err(EmptySection { span: value.value_span });
855+
}
856+
section = Some(value_str);
857+
// Integer parsing is not needed, process next item.
858+
continue;
859+
}
838860
_ => {
839-
errored = true;
840861
cx.adcx().expected_specific_argument(
841862
ident.span,
842863
&[sym::prefix_nops, sym::entry_nops],
843864
);
844-
continue;
865+
return None;
845866
}
846867
};
847868

848869
let rustc_ast::LitKind::Int(val, _) = value.value_as_lit().kind else {
849-
errored = true;
850870
cx.adcx().expected_integer_literal(value.value_span);
851-
continue;
871+
return None;
852872
};
853873

854874
let Ok(val) = val.get().try_into() else {
855-
errored = true;
856875
cx.adcx().expected_integer_literal_in_range(
857876
value.value_span,
858877
u8::MIN as isize,
859878
u8::MAX as isize,
860879
);
861-
continue;
880+
return None;
862881
};
863882

864883
*attrib_to_write = Some(val);
865884
}
866885

867-
if errored {
868-
None
869-
} else {
870-
Some(AttributeKind::PatchableFunctionEntry {
871-
prefix: prefix.unwrap_or(0),
872-
entry: entry.unwrap_or(0),
873-
})
874-
}
886+
Some(AttributeKind::PatchableFunctionEntry { prefix, entry, section })
875887
}
876888
}

compiler/rustc_attr_parsing/src/session_diagnostics.rs

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -292,6 +292,13 @@ pub(crate) struct EmptyExportName {
292292
pub span: Span,
293293
}
294294

295+
#[derive(Diagnostic)]
296+
#[diag("`section` may not be empty")]
297+
pub(crate) struct EmptySection {
298+
#[primary_span]
299+
pub span: Span,
300+
}
301+
295302
#[derive(Diagnostic)]
296303
#[diag("`export_name` may not contain null characters", code = E0648)]
297304
pub(crate) struct NullOnExport {
@@ -327,6 +334,13 @@ pub(crate) struct NullOnObjcSelector {
327334
pub span: Span,
328335
}
329336

337+
#[derive(Diagnostic)]
338+
#[diag("`section` may not contain null characters", code = E0648)]
339+
pub(crate) struct NullOnSection {
340+
#[primary_span]
341+
pub span: Span,
342+
}
343+
330344
#[derive(Diagnostic)]
331345
#[diag("`objc::class!` expected a string literal")]
332346
pub(crate) struct ObjcClassExpectedStringLiteral {

compiler/rustc_codegen_llvm/src/attributes.rs

Lines changed: 27 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -86,11 +86,26 @@ fn patchable_function_entry_attrs<'ll>(
8686
attr: Option<PatchableFunctionEntry>,
8787
) -> SmallVec<[&'ll Attribute; 2]> {
8888
let mut attrs = SmallVec::new();
89-
let patchable_spec = attr.unwrap_or_else(|| {
90-
PatchableFunctionEntry::from_config(sess.opts.unstable_opts.patchable_function_entry)
91-
});
92-
let entry = patchable_spec.entry();
93-
let prefix = patchable_spec.prefix();
89+
90+
let mut entry = sess.opts.unstable_opts.patchable_function_entry.entry();
91+
let mut prefix = sess.opts.unstable_opts.patchable_function_entry.prefix();
92+
let mut section = sess.opts.unstable_opts.patchable_function_entry.section();
93+
let section_sym;
94+
95+
// Apply attribute specified overrides, if any.
96+
if let Some(patchable_spec) = attr {
97+
if let Some(sym) = patchable_spec.section() {
98+
section_sym = sym;
99+
section = Some(section_sym.as_str());
100+
}
101+
// Override the nop counts if either is present. If only one is present, the
102+
// other count is implied to be 0.
103+
if patchable_spec.entry().is_some() || patchable_spec.prefix().is_some() {
104+
entry = patchable_spec.entry().unwrap_or(0);
105+
prefix = patchable_spec.prefix().unwrap_or(0);
106+
}
107+
}
108+
94109
if entry > 0 {
95110
attrs.push(llvm::CreateAttrStringValue(
96111
cx.llcx,
@@ -105,6 +120,13 @@ fn patchable_function_entry_attrs<'ll>(
105120
&format!("{}", prefix),
106121
));
107122
}
123+
if let Some(section) = section {
124+
attrs.push(llvm::CreateAttrStringValue(
125+
cx.llcx,
126+
"patchable-function-entry-section",
127+
section,
128+
));
129+
}
108130
attrs
109131
}
110132

compiler/rustc_codegen_llvm/src/context.rs

Lines changed: 3 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,6 @@ use rustc_data_structures::base_n::{ALPHANUMERIC_ONLY, ToBaseN};
1414
use rustc_data_structures::fx::FxHashMap;
1515
use rustc_data_structures::small_c_str::SmallCStr;
1616
use rustc_hir::def_id::DefId;
17-
use rustc_middle::middle::codegen_fn_attrs::PatchableFunctionEntry;
1817
use rustc_middle::mono::CodegenUnit;
1918
use rustc_middle::ty::layout::{
2019
FnAbiError, FnAbiOfHelpers, FnAbiRequest, HasTypingEnv, LayoutError, LayoutOfHelpers,
@@ -343,14 +342,13 @@ pub(crate) unsafe fn create_module<'ll>(
343342

344343
// Add "kcfi-offset" module flag with -Z patchable-function-entry (See
345344
// https://reviews.llvm.org/D141172).
346-
let pfe =
347-
PatchableFunctionEntry::from_config(sess.opts.unstable_opts.patchable_function_entry);
348-
if pfe.prefix() > 0 {
345+
let patchable_prefix_nops = sess.opts.unstable_opts.patchable_function_entry.prefix();
346+
if patchable_prefix_nops > 0 {
349347
llvm::add_module_flag_u32(
350348
llmod,
351349
llvm::ModuleFlagMergeBehavior::Override,
352350
"kcfi-offset",
353-
pfe.prefix().into(),
351+
patchable_prefix_nops.into(),
354352
);
355353
}
356354

compiler/rustc_codegen_ssa/src/codegen_attrs.rs

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -290,9 +290,11 @@ fn process_builtin_attrs(
290290
AttributeKind::RustcOffloadKernel => {
291291
codegen_fn_attrs.flags |= CodegenFnAttrFlags::OFFLOAD_KERNEL
292292
}
293-
AttributeKind::PatchableFunctionEntry { prefix, entry } => {
293+
AttributeKind::PatchableFunctionEntry { prefix, entry, section } => {
294294
codegen_fn_attrs.patchable_function_entry =
295-
Some(PatchableFunctionEntry::from_prefix_and_entry(*prefix, *entry));
295+
Some(PatchableFunctionEntry::from_prefix_entry_and_section(
296+
*prefix, *entry, *section,
297+
));
296298
}
297299
AttributeKind::InstrumentFn(instrument_fn) => {
298300
codegen_fn_attrs.instrument_fn = match instrument_fn {

compiler/rustc_expand/src/proc_macro_server.rs

Lines changed: 13 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -490,9 +490,11 @@ impl server::Server for Rustc<'_, '_> {
490490
fn literal_from_str(&mut self, s: &str) -> Result<Literal<Self::Span, Self::Symbol>, String> {
491491
let name = FileName::proc_macro_source_code(s);
492492

493-
let mut parser =
493+
let mut parser = rustc_errors::catch_fatal_errors(|| {
494494
new_parser_from_source_str(self.psess(), name, s.to_owned(), StripTokens::Nothing)
495-
.map_err(cancel_diags_into_string)?;
495+
})
496+
.map_err(|_| String::from("failed to parse to literal"))?
497+
.map_err(cancel_diags_into_string)?;
496498

497499
let first_span = parser.token.span.data();
498500
let minus_present = parser.eat(exp!(Minus));
@@ -569,12 +571,15 @@ impl server::Server for Rustc<'_, '_> {
569571
}
570572

571573
fn ts_from_str(&mut self, src: &str) -> Result<Self::TokenStream, String> {
572-
source_str_to_stream(
573-
self.psess(),
574-
FileName::proc_macro_source_code(src),
575-
src.to_string(),
576-
Some(self.call_site),
577-
)
574+
rustc_errors::catch_fatal_errors(|| {
575+
source_str_to_stream(
576+
self.psess(),
577+
FileName::proc_macro_source_code(src),
578+
src.to_string(),
579+
Some(self.call_site),
580+
)
581+
})
582+
.map_err(|_| String::from("failed to parse to tokenstream"))?
578583
.map_err(cancel_diags_into_string)
579584
}
580585

compiler/rustc_hir/src/attrs/data_structures.rs

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1271,8 +1271,9 @@ pub enum AttributeKind {
12711271

12721272
/// Represents `#[patchable_function_entry]`
12731273
PatchableFunctionEntry {
1274-
prefix: u8,
1275-
entry: u8,
1274+
prefix: Option<u8>,
1275+
entry: Option<u8>,
1276+
section: Option<Symbol>,
12761277
},
12771278

12781279
/// Represents `#[path]`

compiler/rustc_interface/src/tests.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -866,7 +866,7 @@ fn test_unstable_options_tracking_hash() {
866866
tracked!(panic_in_drop, PanicStrategy::Abort);
867867
tracked!(
868868
patchable_function_entry,
869-
PatchableFunctionEntry::from_total_and_prefix_nops(10, 5)
869+
PatchableFunctionEntry::from_parts(10, 5, None)
870870
.expect("total must be greater than or equal to prefix")
871871
);
872872
tracked!(plt, Some(true));

compiler/rustc_lint/src/unused.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -338,7 +338,7 @@ trait UnusedDelimLint {
338338
&& !snip.starts_with(' ')
339339
{
340340
" "
341-
} else if let Ok(snip) = sm.span_to_prev_source(value_span)
341+
} else if let Ok(snip) = sm.span_to_next_source(value_span)
342342
&& snip.starts_with(|c: char| c.is_alphanumeric())
343343
{
344344
" "

compiler/rustc_middle/src/middle/codegen_fn_attrs.rs

Lines changed: 17 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -114,7 +114,7 @@ pub struct CodegenFnAttrs {
114114
// FIXME(#82232, #143834): temporarily renamed to mitigate `#[align]` nameres ambiguity
115115
pub alignment: Option<Align>,
116116
/// The `#[patchable_function_entry(...)]` attribute. Indicates how many nops should be around
117-
/// the function entry.
117+
/// the function entry, or override default section to record entry location.
118118
pub patchable_function_entry: Option<PatchableFunctionEntry>,
119119
/// The `#[rustc_objc_class = "..."]` attribute.
120120
pub objc_class: Option<Symbol>,
@@ -162,24 +162,33 @@ pub struct TargetFeature {
162162
#[derive(Copy, Clone, Debug, TyEncodable, TyDecodable, StableHash)]
163163
pub struct PatchableFunctionEntry {
164164
/// Nops to prepend to the function
165-
prefix: u8,
165+
prefix: Option<u8>,
166166
/// Nops after entry, but before body
167-
entry: u8,
167+
entry: Option<u8>,
168+
/// Optional, specific section to record entry location in
169+
section: Option<Symbol>,
168170
}
169171

170172
impl PatchableFunctionEntry {
171-
pub fn from_config(config: rustc_session::config::PatchableFunctionEntry) -> Self {
172-
Self { prefix: config.prefix(), entry: config.entry() }
173+
pub fn from_prefix_entry_and_section(
174+
prefix: Option<u8>,
175+
entry: Option<u8>,
176+
section: Option<Symbol>,
177+
) -> Self {
178+
Self { prefix, entry, section }
173179
}
174180
pub fn from_prefix_and_entry(prefix: u8, entry: u8) -> Self {
175-
Self { prefix, entry }
181+
Self { prefix: Some(prefix), entry: Some(entry), section: None }
176182
}
177-
pub fn prefix(&self) -> u8 {
183+
pub fn prefix(&self) -> Option<u8> {
178184
self.prefix
179185
}
180-
pub fn entry(&self) -> u8 {
186+
pub fn entry(&self) -> Option<u8> {
181187
self.entry
182188
}
189+
pub fn section(&self) -> Option<Symbol> {
190+
self.section
191+
}
183192
}
184193

185194
#[derive(Clone, Copy, PartialEq, Eq, TyEncodable, TyDecodable, StableHash)]

0 commit comments

Comments
 (0)