Skip to content

Commit 40557f6

Browse files
committed
Auto merge of #158419 - jhpratt:rollup-38sJqWx, r=jhpratt
Rollup of 10 pull requests Successful merges: - #158410 (Update LLVM for Mach-O __LINKEDIT alignment fix.) - #157397 (cmse: clear padding when crossing the secure boundary) - #158036 (Add -Zinstrument-mcount=fentry to -Zinstrument-mcount) - #158330 (llvm: use intrinsics for f16, f32 minimum/maximum) - #158359 (fix(tests): allow either branch direction in ilog_known_base) - #158067 (LLVM 23: Adapt codegen test to moved assume) - #158261 (Move part of the target checking for `#[may_dangle]` to the parser) - #158358 (Fix invalid E0609 raw pointer deref suggestion inside macros) - #158392 (delegation: add tests for defaults and infers in generics) - #158394 (Generate synthetic generic args only for delegation's child segment)
2 parents bd08c9e + d109bb0 commit 40557f6

58 files changed

Lines changed: 1261 additions & 148 deletions

File tree

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

compiler/rustc_abi/src/layout/ty.rs

Lines changed: 87 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,8 @@
11
use std::fmt;
2-
use std::ops::Deref;
2+
use std::ops::{Deref, Range};
33

44
use rustc_data_structures::intern::Interned;
5+
use rustc_data_structures::range_set::RangeSet;
56
use rustc_macros::StableHash;
67

78
use crate::layout::{FieldIdx, VariantIdx};
@@ -282,4 +283,89 @@ impl<'a, Ty> TyAndLayout<'a, Ty> {
282283
}
283284
found
284285
}
286+
287+
/// The ranges of bytes that are always ignored by the representation relation of this type.
288+
///
289+
/// In other words, for any sequence of bytes, if we reset the these padding bytes to uninit,
290+
/// then these two sequences of bytes represent the same value (or they are both invalid).
291+
/// This is the "guaranteed" padding. There may be more bytes that are padding for some
292+
/// but not all variants of this type; those are not included.
293+
/// (E.g. `Option<i8>` has no guaranteed padding so the empty range set is returned, but its `None` value still has padding).
294+
pub fn padding_ranges<C>(&self, cx: &C) -> Vec<Range<Size>>
295+
where
296+
Ty: TyAbiInterface<'a, C> + Copy,
297+
{
298+
let mut data = RangeSet::new();
299+
self.add_data_ranges(cx, Size::ZERO, &mut data);
300+
301+
// Find gaps between the data ranges.
302+
let mut uninit_ranges = Vec::new();
303+
let mut covered_until = Size::ZERO;
304+
for &(offset, size) in data.0.iter() {
305+
if offset > covered_until {
306+
uninit_ranges.push(covered_until..offset);
307+
}
308+
covered_until = Ord::max(covered_until, offset + size);
309+
}
310+
311+
// Add trailing padding.
312+
if self.size > covered_until {
313+
uninit_ranges.push(covered_until..self.size);
314+
}
315+
316+
uninit_ranges
317+
}
318+
319+
/// Extend `out` with all ranges of bytes that *may* carry relevant data for values of this type.
320+
/// For enums and unions there are offsets that are initialized for some
321+
/// variants but not for others; those offset *will* get added to `out`.
322+
fn add_data_ranges<C>(self, cx: &C, base_offset: Size, out: &mut RangeSet<Size>)
323+
where
324+
Ty: TyAbiInterface<'a, C> + Copy,
325+
{
326+
if self.is_zst() {
327+
return;
328+
}
329+
330+
match &self.variants {
331+
Variants::Empty => { /* done */ }
332+
Variants::Single { index: _ } => match &self.fields {
333+
FieldsShape::Primitive => {
334+
out.add_range(base_offset, self.size);
335+
}
336+
&FieldsShape::Union(field_count) => {
337+
for field in 0..field_count.get() {
338+
let field = self.field(cx, field);
339+
field.add_data_ranges(cx, base_offset, out);
340+
}
341+
}
342+
&FieldsShape::Array { stride, count } => {
343+
let elem = self.field(cx, 0);
344+
345+
// For scalars we know there is no padding between the elements,
346+
// so the entire array is a single big data range.
347+
if elem.backend_repr.is_scalar() {
348+
out.add_range(base_offset, elem.size * count);
349+
} else {
350+
// FIXME: this is really inefficient for large arrays.
351+
for idx in 0..count {
352+
elem.add_data_ranges(cx, base_offset + idx * stride, out);
353+
}
354+
}
355+
}
356+
FieldsShape::Arbitrary { offsets, in_memory_order: _ } => {
357+
for (field, &offset) in offsets.iter_enumerated() {
358+
let field = self.field(cx, field.as_usize());
359+
field.add_data_ranges(cx, base_offset + offset, out);
360+
}
361+
}
362+
},
363+
Variants::Multiple { variants, .. } => {
364+
for variant in variants.indices() {
365+
let variant = self.for_variant(cx, variant);
366+
variant.add_data_ranges(cx, base_offset, out);
367+
}
368+
}
369+
}
370+
}
285371
}

compiler/rustc_abi/src/lib.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -792,7 +792,7 @@ impl FromStr for Endian {
792792
}
793793

794794
/// Size of a type in bytes.
795-
#[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
795+
#[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash, Default)]
796796
#[cfg_attr(feature = "nightly", derive(Encodable_NoContext, Decodable_NoContext, StableHash))]
797797
pub struct Size {
798798
raw: u64,

compiler/rustc_attr_parsing/src/attributes/semantics.rs

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,17 @@
11
use rustc_feature::AttributeStability;
2+
use rustc_hir::target::GenericParamKind;
23

34
use super::prelude::*;
45

56
pub(crate) struct MayDangleParser;
67
impl NoArgsAttributeParser for MayDangleParser {
78
const PATH: &[Symbol] = &[sym::may_dangle];
8-
const ALLOWED_TARGETS: AllowedTargets<'_> = AllowedTargets::AllowList(ALL_TARGETS); //FIXME Still checked fully in `check_attr.rs`
9+
const ALLOWED_TARGETS: AllowedTargets<'_> = AllowedTargets::AllowList(&[
10+
Allow(Target::GenericParam { kind: GenericParamKind::Type, has_default: false }),
11+
Allow(Target::GenericParam { kind: GenericParamKind::Type, has_default: true }),
12+
Allow(Target::GenericParam { kind: GenericParamKind::Lifetime, has_default: false }),
13+
Allow(Target::GenericParam { kind: GenericParamKind::Lifetime, has_default: true }),
14+
]);
915
const STABILITY: AttributeStability = unstable!(dropck_eyepatch);
1016
const CREATE: fn(span: Span) -> AttributeKind = AttributeKind::MayDangle;
1117
}

compiler/rustc_attr_parsing/src/target_checking.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -416,6 +416,7 @@ pub(crate) fn allowed_targets_applied(
416416

417417
// ensure a consistent order
418418
target_strings.sort();
419+
target_strings.dedup();
419420

420421
// If there is now only 1 target left, show that as the only possible target
421422
let only_target = target_strings.len() == 1;

compiler/rustc_codegen_llvm/src/attributes.rs

Lines changed: 25 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,9 @@ use rustc_middle::middle::codegen_fn_attrs::{
77
TargetFeature,
88
};
99
use rustc_middle::ty::{self, Instance, TyCtxt};
10-
use rustc_session::config::{BranchProtection, FunctionReturn, OptLevel, PAuthKey, PacRet};
10+
use rustc_session::config::{
11+
BranchProtection, FunctionReturn, InstrumentMcount, OptLevel, PAuthKey, PacRet,
12+
};
1113
use rustc_span::sym;
1214
use rustc_symbol_mangling::mangle_internal_symbol;
1315
use rustc_target::spec::{Arch, FramePointer, SanitizerSet, StackProbeType, StackProtector};
@@ -177,7 +179,7 @@ pub(crate) fn frame_pointer(sess: &Session) -> FramePointer {
177179
let opts = &sess.opts;
178180
// "mcount" function relies on stack pointer.
179181
// See <https://sourceware.org/binutils/docs/gprof/Implementation.html>.
180-
if opts.unstable_opts.instrument_mcount {
182+
if opts.unstable_opts.instrument_mcount == InstrumentMcount::Mcount {
181183
fp.ratchet(FramePointer::Always);
182184
}
183185
fp.ratchet(opts.cg.force_frame_pointers);
@@ -214,7 +216,7 @@ fn instrument_function_attr<'ll>(
214216
instrument_fn: InstrumentFnAttr,
215217
) -> SmallVec<[&'ll Attribute; 4]> {
216218
let mut attrs = SmallVec::new();
217-
if sess.opts.unstable_opts.instrument_mcount {
219+
if sess.opts.unstable_opts.instrument_mcount != InstrumentMcount::Disabled {
218220
// Similar to `clang -pg` behavior. Handled by the
219221
// `post-inline-ee-instrument` LLVM pass.
220222

@@ -224,18 +226,26 @@ fn instrument_function_attr<'ll>(
224226
};
225227

226228
if instrument_entry {
227-
// The function name varies on platforms.
228-
// See test/CodeGen/mcount.c in clang.
229-
let mcount_name = match &sess.target.llvm_mcount_intrinsic {
230-
Some(llvm_mcount_intrinsic) => llvm_mcount_intrinsic.as_ref(),
231-
None => sess.target.mcount.as_ref(),
232-
};
233-
234-
attrs.push(llvm::CreateAttrStringValue(
235-
cx.llcx,
236-
"instrument-function-entry-inlined",
237-
mcount_name,
238-
));
229+
match sess.opts.unstable_opts.instrument_mcount {
230+
InstrumentMcount::Mcount => {
231+
// The function name varies on platforms.
232+
// See test/CodeGen/mcount.c in clang.
233+
let mcount_name = match &sess.target.llvm_mcount_intrinsic {
234+
Some(llvm_mcount_intrinsic) => llvm_mcount_intrinsic.as_ref(),
235+
None => sess.target.mcount.as_ref(),
236+
};
237+
238+
attrs.push(llvm::CreateAttrStringValue(
239+
cx.llcx,
240+
"instrument-function-entry-inlined",
241+
mcount_name,
242+
));
243+
}
244+
InstrumentMcount::Fentry => {
245+
attrs.push(llvm::CreateAttrStringValue(cx.llcx, "fentry-call", "true"));
246+
}
247+
InstrumentMcount::Disabled => {}
248+
}
239249
}
240250
}
241251
if let Some(options) = &sess.opts.unstable_opts.instrument_xray {

compiler/rustc_codegen_llvm/src/intrinsic.rs

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -114,17 +114,17 @@ fn call_simple_intrinsic<'ll, 'tcx>(
114114
sym::fmuladdf64 => ("llvm.fmuladd", &[bx.type_f64()]),
115115
sym::fmuladdf128 => ("llvm.fmuladd", &[bx.type_f128()]),
116116

117+
sym::minimumf16 => ("llvm.minimum", &[bx.type_f16()]),
118+
sym::minimumf32 => ("llvm.minimum", &[bx.type_f32()]),
117119
// FIXME: LLVM currently mis-compile those intrinsics, re-enable them
118120
// when llvm/llvm-project#{139380,139381,140445} are fixed.
119-
//sym::minimumf16 => ("llvm.minimum", &[bx.type_f16()]),
120-
//sym::minimumf32 => ("llvm.minimum", &[bx.type_f32()]),
121121
//sym::minimumf64 => ("llvm.minimum", &[bx.type_f64()]),
122122
//sym::minimumf128 => ("llvm.minimum", &[cx.type_f128()]),
123123
//
124+
sym::maximumf16 => ("llvm.maximum", &[bx.type_f16()]),
125+
sym::maximumf32 => ("llvm.maximum", &[bx.type_f32()]),
124126
// FIXME: LLVM currently mis-compile those intrinsics, re-enable them
125127
// when llvm/llvm-project#{139380,139381,140445} are fixed.
126-
//sym::maximumf16 => ("llvm.maximum", &[bx.type_f16()]),
127-
//sym::maximumf32 => ("llvm.maximum", &[bx.type_f32()]),
128128
//sym::maximumf64 => ("llvm.maximum", &[bx.type_f64()]),
129129
//sym::maximumf128 => ("llvm.maximum", &[cx.type_f128()]),
130130
//

compiler/rustc_codegen_ssa/src/back/link.rs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -35,8 +35,8 @@ use rustc_middle::middle::debugger_visualizer::DebuggerVisualizerFile;
3535
use rustc_middle::middle::dependency_format::Linkage;
3636
use rustc_middle::middle::exported_symbols::SymbolExportKind;
3737
use rustc_session::config::{
38-
self, CFGuard, CrateType, DebugInfo, LinkerFeaturesCli, OutFileName, OutputFilenames,
39-
OutputType, PrintKind, SplitDwarfKind, Strip,
38+
self, CFGuard, CrateType, DebugInfo, InstrumentMcount, LinkerFeaturesCli, OutFileName,
39+
OutputFilenames, OutputType, PrintKind, SplitDwarfKind, Strip,
4040
};
4141
use rustc_session::lint::builtin::LINKER_MESSAGES;
4242
use rustc_session::output::{check_file_is_writeable, invalid_output_for_target, out_filename};
@@ -2953,7 +2953,7 @@ fn add_order_independent_options(
29532953
cmd.pgo_gen();
29542954
}
29552955

2956-
if sess.opts.unstable_opts.instrument_mcount {
2956+
if sess.opts.unstable_opts.instrument_mcount != InstrumentMcount::Disabled {
29572957
cmd.enable_profiling();
29582958
}
29592959

compiler/rustc_codegen_ssa/src/mir/block.rs

Lines changed: 71 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,9 @@
11
use std::cmp;
2+
use std::ops::Range;
23

3-
use rustc_abi::{Align, BackendRepr, ExternAbi, HasDataLayout, Reg, Size, WrappingRange};
4+
use rustc_abi::{
5+
Align, ArmCall, BackendRepr, CanonAbi, ExternAbi, HasDataLayout, Reg, Size, WrappingRange,
6+
};
47
use rustc_ast as ast;
58
use rustc_ast::{InlineAsmOptions, InlineAsmTemplatePiece};
69
use rustc_data_structures::packed::Pu128;
@@ -597,6 +600,20 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
597600
}
598601
ZeroSized => bug!("ZST return value shouldn't be in PassMode::Cast"),
599602
};
603+
604+
if self.fn_abi.conv == CanonAbi::Arm(ArmCall::CCmseNonSecureEntry) {
605+
// The return value of an `extern "cmse-nonsecure-entry"` function crosses the
606+
// secure boundary. Zero padding bytes so information does not leak.
607+
//
608+
// This only zeroes "guaranteed" padding. There may be more bytes that are
609+
// padding for some but not all variants of this type; those are not zeroed.
610+
//
611+
// Returning a value with value-dependent padding will instead trigger a lint.
612+
let ret_layout = self.fn_abi.ret.layout;
613+
let uninit_ranges = ret_layout.padding_ranges(bx.cx());
614+
self.zero_byte_ranges(bx, llslot, ret_layout.size, &uninit_ranges);
615+
}
616+
600617
load_cast(bx, cast_ty, llslot, self.fn_abi.ret.layout.align.abi)
601618
}
602619
};
@@ -1341,6 +1358,7 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
13411358

13421359
self.codegen_argument(
13431360
bx,
1361+
fn_abi.conv,
13441362
op,
13451363
by_move,
13461364
&mut llargs,
@@ -1351,6 +1369,7 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
13511369
let num_untupled = untuple.map(|tup| {
13521370
self.codegen_arguments_untupled(
13531371
bx,
1372+
fn_abi.conv,
13541373
&tup.node,
13551374
&mut llargs,
13561375
&fn_abi.args[first_args.len()..],
@@ -1380,6 +1399,7 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
13801399
let last_arg = fn_abi.args.last().unwrap();
13811400
self.codegen_argument(
13821401
bx,
1402+
fn_abi.conv,
13831403
location,
13841404
/* by_move */ false,
13851405
&mut llargs,
@@ -1696,9 +1716,31 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
16961716
}
16971717
}
16981718

1719+
fn zero_byte_ranges(
1720+
&mut self,
1721+
bx: &mut Bx,
1722+
ptr: Bx::Value,
1723+
limit: Size,
1724+
ranges: &[Range<Size>],
1725+
) {
1726+
let zero = bx.const_u8(0);
1727+
1728+
for range in ranges {
1729+
let end = cmp::min(range.end, limit);
1730+
if range.start >= end {
1731+
continue;
1732+
}
1733+
let offset = bx.const_usize(range.start.bytes());
1734+
let len = bx.const_usize((end - range.start).bytes());
1735+
let ptr = bx.inbounds_ptradd(ptr, offset);
1736+
bx.memset(ptr, zero, len, Align::ONE, MemFlags::empty());
1737+
}
1738+
}
1739+
16991740
fn codegen_argument(
17001741
&mut self,
17011742
bx: &mut Bx,
1743+
conv: CanonAbi,
17021744
op: OperandRef<'tcx, Bx::Value>,
17031745
by_move: bool,
17041746
llargs: &mut Vec<Bx::Value>,
@@ -1822,6 +1864,23 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
18221864
MemFlags::empty(),
18231865
None,
18241866
);
1867+
1868+
// The arguments of an `extern "cmse-nonsecure-call"` function cross the secure
1869+
// boundary. Zero padding bytes so information does not leak.
1870+
//
1871+
// This only zeroes "guaranteed" padding. There may be more bytes that are
1872+
// padding for some but not all variants of this type; those are not zeroed.
1873+
//
1874+
// Passing an argument with value-dependent padding will instead trigger a lint.
1875+
if conv == CanonAbi::Arm(ArmCall::CCmseNonSecureCall) {
1876+
self.zero_byte_ranges(
1877+
bx,
1878+
llscratch,
1879+
Size::from_bytes(copy_bytes),
1880+
&arg.layout.padding_ranges(bx.cx()),
1881+
);
1882+
}
1883+
18251884
// ...and then load it with the ABI type.
18261885
llval = load_cast(bx, cast, llscratch, scratch_align);
18271886
bx.lifetime_end(llscratch, scratch_size);
@@ -1848,6 +1907,7 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
18481907
fn codegen_arguments_untupled(
18491908
&mut self,
18501909
bx: &mut Bx,
1910+
conv: CanonAbi,
18511911
operand: &mir::Operand<'tcx>,
18521912
llargs: &mut Vec<Bx::Value>,
18531913
args: &[ArgAbi<'tcx, Ty<'tcx>>],
@@ -1867,6 +1927,7 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
18671927
let field = bx.load_operand(field_ptr);
18681928
self.codegen_argument(
18691929
bx,
1930+
conv,
18701931
field,
18711932
by_move,
18721933
llargs,
@@ -1878,7 +1939,15 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
18781939
// If the tuple is immediate, the elements are as well.
18791940
for i in 0..tuple.layout.fields.count() {
18801941
let op = tuple.extract_field(self, bx, i);
1881-
self.codegen_argument(bx, op, by_move, llargs, &args[i], lifetime_ends_after_call);
1942+
self.codegen_argument(
1943+
bx,
1944+
conv,
1945+
op,
1946+
by_move,
1947+
llargs,
1948+
&args[i],
1949+
lifetime_ends_after_call,
1950+
);
18821951
}
18831952
}
18841953
tuple.layout.fields.count()

0 commit comments

Comments
 (0)