Skip to content

Commit e55ab24

Browse files
committed
Auto merge of rust-lang#140537 - matthiaskrgr:rollup-ajofln5, r=matthiaskrgr
Rollup of 7 pull requests Successful merges: - rust-lang#134034 (handle paren in macro expand for let-init-else expr) - rust-lang#139186 (Refactor `diy_float`) - rust-lang#140062 (std: mention `remove_dir_all` can emit `DirectoryNotEmpty` when concurrently written into) - rust-lang#140430 (Improve test coverage of HIR pretty printing.) - rust-lang#140485 (Optimize the codegen for `Span::from_expansion`) - rust-lang#140505 (linker: Quote symbol names in .def files) - rust-lang#140521 (interpret: better error message for out-of-bounds pointer arithmetic and accesses) r? `@ghost` `@rustbot` modify labels: rollup
2 parents 6e23095 + b30d7b6 commit e55ab24

File tree

97 files changed

+1315
-338
lines changed

Some content is hidden

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

97 files changed

+1315
-338
lines changed

compiler/rustc_codegen_ssa/src/back/linker.rs

+3-1
Original file line numberDiff line numberDiff line change
@@ -816,7 +816,9 @@ impl<'a> Linker for GccLinker<'a> {
816816
writeln!(f, "EXPORTS")?;
817817
for symbol in symbols {
818818
debug!(" _{symbol}");
819-
writeln!(f, " {symbol}")?;
819+
// Quote the name in case it's reserved by linker in some way
820+
// (this accounts for names with dots in particular).
821+
writeln!(f, " \"{symbol}\"")?;
820822
}
821823
};
822824
if let Err(error) = res {

compiler/rustc_const_eval/messages.ftl

+35-35
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,27 @@ const_eval_already_reported =
1212
const_eval_assume_false =
1313
`assume` called with `false`
1414
15+
const_eval_bad_pointer_op = {$operation ->
16+
[MemoryAccess] memory access failed
17+
[InboundsPointerArithmetic] in-bounds pointer arithmetic failed
18+
*[Dereferenceable] pointer not dereferenceable
19+
}
20+
const_eval_bad_pointer_op_attempting = {const_eval_bad_pointer_op}: {$operation ->
21+
[MemoryAccess] attempting to access {$inbounds_size ->
22+
[1] 1 byte
23+
*[x] {$inbounds_size} bytes
24+
}
25+
[InboundsPointerArithmetic] attempting to offset pointer by {$inbounds_size ->
26+
[1] 1 byte
27+
*[x] {$inbounds_size} bytes
28+
}
29+
*[Dereferenceable] pointer must {$inbounds_size ->
30+
[0] point to some allocation
31+
[1] be dereferenceable for 1 byte
32+
*[x] be dereferenceable for {$inbounds_size} bytes
33+
}
34+
}
35+
1536
const_eval_bounds_check_failed =
1637
indexing out of bounds: the len is {$len} but the index is {$index}
1738
const_eval_call_nonzero_intrinsic =
@@ -39,9 +60,9 @@ const_eval_copy_nonoverlapping_overlapping =
3960
`copy_nonoverlapping` called on overlapping ranges
4061
4162
const_eval_dangling_int_pointer =
42-
{$bad_pointer_message}: {const_eval_expected_inbounds_pointer}, but got {$pointer} which is a dangling pointer (it has no provenance)
63+
{const_eval_bad_pointer_op_attempting}, but got {$pointer} which is a dangling pointer (it has no provenance)
4364
const_eval_dangling_null_pointer =
44-
{$bad_pointer_message}: {const_eval_expected_inbounds_pointer}, but got a null pointer
65+
{const_eval_bad_pointer_op_attempting}, but got null pointer
4566
4667
const_eval_dangling_ptr_in_final = encountered dangling pointer in final value of {const_eval_intern_kind}
4768
const_eval_dead_local =
@@ -77,21 +98,6 @@ const_eval_error = {$error_kind ->
7798
const_eval_exact_div_has_remainder =
7899
exact_div: {$a} cannot be divided by {$b} without remainder
79100
80-
const_eval_expected_inbounds_pointer =
81-
expected a pointer to {$inbounds_size_abs ->
82-
[0] some allocation
83-
*[x] {$inbounds_size_is_neg ->
84-
[false] {$inbounds_size_abs ->
85-
[1] 1 byte of memory
86-
*[x] {$inbounds_size_abs} bytes of memory
87-
}
88-
*[true] the end of {$inbounds_size_abs ->
89-
[1] 1 byte of memory
90-
*[x] {$inbounds_size_abs} bytes of memory
91-
}
92-
}
93-
}
94-
95101
const_eval_extern_static =
96102
cannot access extern static `{$did}`
97103
const_eval_extern_type_field = `extern type` field does not have a known offset
@@ -111,7 +117,6 @@ const_eval_frame_note_inner = inside {$where_ ->
111117
112118
const_eval_frame_note_last = the failure occurred here
113119
114-
const_eval_in_bounds_test = out-of-bounds pointer use
115120
const_eval_incompatible_calling_conventions =
116121
calling a function with calling convention {$callee_conv} using calling convention {$caller_conv}
117122
@@ -206,7 +211,6 @@ const_eval_long_running =
206211
207212
const_eval_max_num_nodes_in_const = maximum number of nodes exceeded in constant {$global_const_id}
208213
209-
const_eval_memory_access_test = memory access failed
210214
const_eval_memory_exhausted =
211215
tried to allocate more memory than available to compiler
212216
@@ -287,8 +291,6 @@ const_eval_offset_from_out_of_bounds =
287291
`{$name}` called on two different pointers where the memory range between them is not in-bounds of an allocation
288292
const_eval_offset_from_overflow =
289293
`{$name}` called when first pointer is too far ahead of second
290-
const_eval_offset_from_test =
291-
out-of-bounds `offset_from` origin
292294
const_eval_offset_from_underflow =
293295
`{$name}` called when first pointer is too far before second
294296
const_eval_offset_from_unsigned_overflow =
@@ -312,27 +314,25 @@ const_eval_partial_pointer_overwrite =
312314
unable to overwrite parts of a pointer in memory at {$ptr}
313315
const_eval_pointer_arithmetic_overflow =
314316
overflowing pointer arithmetic: the total offset in bytes does not fit in an `isize`
315-
const_eval_pointer_arithmetic_test = out-of-bounds pointer arithmetic
317+
316318
const_eval_pointer_out_of_bounds =
317-
{$bad_pointer_message}: {const_eval_expected_inbounds_pointer}, but got {$pointer} {$ptr_offset_is_neg ->
318-
[true] which points to before the beginning of the allocation
319-
*[false] {$inbounds_size_is_neg ->
320-
[true] {$ptr_offset_abs ->
321-
[0] which is at the beginning of the allocation
322-
*[other] which does not have enough space to the beginning of the allocation
323-
}
324-
*[false] {$alloc_size_minus_ptr_offset ->
325-
[0] which is at or beyond the end of the allocation of size {$alloc_size ->
319+
{const_eval_bad_pointer_op_attempting}, but got {$pointer} which {$inbounds_size_is_neg ->
320+
[false] {$alloc_size_minus_ptr_offset ->
321+
[0] is at or beyond the end of the allocation of size {$alloc_size ->
326322
[1] 1 byte
327323
*[x] {$alloc_size} bytes
328324
}
329-
[1] which is only 1 byte from the end of the allocation
330-
*[x] which is only {$alloc_size_minus_ptr_offset} bytes from the end of the allocation
325+
[1] is only 1 byte from the end of the allocation
326+
*[x] is only {$alloc_size_minus_ptr_offset} bytes from the end of the allocation
327+
}
328+
*[true] {$ptr_offset_abs ->
329+
[0] is at the beginning of the allocation
330+
*[other] is only {$ptr_offset_abs} bytes from the beginning of the allocation
331331
}
332-
}
333332
}
333+
334334
const_eval_pointer_use_after_free =
335-
{$bad_pointer_message}: {$alloc_id} has been freed, so this pointer is dangling
335+
{const_eval_bad_pointer_op}: {$alloc_id} has been freed, so this pointer is dangling
336336
const_eval_ptr_as_bytes_1 =
337337
this code performed an operation that depends on the underlying bytes representing a pointer
338338
const_eval_ptr_as_bytes_2 =

compiler/rustc_const_eval/src/errors.rs

+10-23
Original file line numberDiff line numberDiff line change
@@ -5,15 +5,14 @@ use either::Either;
55
use rustc_abi::WrappingRange;
66
use rustc_errors::codes::*;
77
use rustc_errors::{
8-
Diag, DiagArgValue, DiagCtxtHandle, DiagMessage, Diagnostic, EmissionGuarantee, Level,
9-
MultiSpan, Subdiagnostic,
8+
Diag, DiagArgValue, DiagMessage, Diagnostic, EmissionGuarantee, Level, MultiSpan, Subdiagnostic,
109
};
1110
use rustc_hir::ConstContext;
1211
use rustc_macros::{Diagnostic, LintDiagnostic, Subdiagnostic};
1312
use rustc_middle::mir::interpret::{
14-
CheckInAllocMsg, CtfeProvenance, ExpectedKind, InterpErrorKind, InvalidMetaKind,
15-
InvalidProgramInfo, Misalignment, Pointer, PointerKind, ResourceExhaustionInfo,
16-
UndefinedBehaviorInfo, UnsupportedOpInfo, ValidationErrorInfo,
13+
CtfeProvenance, ExpectedKind, InterpErrorKind, InvalidMetaKind, InvalidProgramInfo,
14+
Misalignment, Pointer, PointerKind, ResourceExhaustionInfo, UndefinedBehaviorInfo,
15+
UnsupportedOpInfo, ValidationErrorInfo,
1716
};
1817
use rustc_middle::ty::{self, Mutability, Ty};
1918
use rustc_span::{Span, Symbol};
@@ -498,19 +497,6 @@ pub trait ReportErrorExt {
498497
}
499498
}
500499

501-
fn bad_pointer_message(msg: CheckInAllocMsg, dcx: DiagCtxtHandle<'_>) -> String {
502-
use crate::fluent_generated::*;
503-
504-
let msg = match msg {
505-
CheckInAllocMsg::MemoryAccessTest => const_eval_memory_access_test,
506-
CheckInAllocMsg::PointerArithmeticTest => const_eval_pointer_arithmetic_test,
507-
CheckInAllocMsg::OffsetFromTest => const_eval_offset_from_test,
508-
CheckInAllocMsg::InboundsTest => const_eval_in_bounds_test,
509-
};
510-
511-
dcx.eagerly_translate_to_string(msg, [].into_iter())
512-
}
513-
514500
impl<'a> ReportErrorExt for UndefinedBehaviorInfo<'a> {
515501
fn diagnostic_message(&self) -> DiagMessage {
516502
use UndefinedBehaviorInfo::*;
@@ -564,7 +550,6 @@ impl<'a> ReportErrorExt for UndefinedBehaviorInfo<'a> {
564550

565551
fn add_args<G: EmissionGuarantee>(self, diag: &mut Diag<'_, G>) {
566552
use UndefinedBehaviorInfo::*;
567-
let dcx = diag.dcx;
568553
match self {
569554
Ub(_) => {}
570555
Custom(custom) => {
@@ -612,12 +597,10 @@ impl<'a> ReportErrorExt for UndefinedBehaviorInfo<'a> {
612597
diag.arg("vtable_dyn_type", vtable_dyn_type.to_string());
613598
}
614599
PointerUseAfterFree(alloc_id, msg) => {
615-
diag.arg("alloc_id", alloc_id)
616-
.arg("bad_pointer_message", bad_pointer_message(msg, dcx));
600+
diag.arg("alloc_id", alloc_id).arg("operation", format!("{:?}", msg));
617601
}
618602
PointerOutOfBounds { alloc_id, alloc_size, ptr_offset, inbounds_size, msg } => {
619603
diag.arg("alloc_size", alloc_size.bytes());
620-
diag.arg("bad_pointer_message", bad_pointer_message(msg, dcx));
621604
diag.arg("pointer", {
622605
let mut out = format!("{:?}", alloc_id);
623606
if ptr_offset > 0 {
@@ -627,14 +610,17 @@ impl<'a> ReportErrorExt for UndefinedBehaviorInfo<'a> {
627610
}
628611
out
629612
});
613+
diag.arg("inbounds_size", inbounds_size);
630614
diag.arg("inbounds_size_is_neg", inbounds_size < 0);
631615
diag.arg("inbounds_size_abs", inbounds_size.unsigned_abs());
616+
diag.arg("ptr_offset", ptr_offset);
632617
diag.arg("ptr_offset_is_neg", ptr_offset < 0);
633618
diag.arg("ptr_offset_abs", ptr_offset.unsigned_abs());
634619
diag.arg(
635620
"alloc_size_minus_ptr_offset",
636621
alloc_size.bytes().saturating_sub(ptr_offset as u64),
637622
);
623+
diag.arg("operation", format!("{:?}", msg));
638624
}
639625
DanglingIntPointer { addr, inbounds_size, msg } => {
640626
if addr != 0 {
@@ -644,9 +630,10 @@ impl<'a> ReportErrorExt for UndefinedBehaviorInfo<'a> {
644630
);
645631
}
646632

633+
diag.arg("inbounds_size", inbounds_size);
647634
diag.arg("inbounds_size_is_neg", inbounds_size < 0);
648635
diag.arg("inbounds_size_abs", inbounds_size.unsigned_abs());
649-
diag.arg("bad_pointer_message", bad_pointer_message(msg, dcx));
636+
diag.arg("operation", format!("{:?}", msg));
650637
}
651638
AlignmentCheckFailed(Misalignment { required, has }, msg) => {
652639
diag.arg("required", required.bytes());

compiler/rustc_const_eval/src/interpret/intrinsics.rs

+7-3
Original file line numberDiff line numberDiff line change
@@ -348,7 +348,7 @@ impl<'tcx, M: Machine<'tcx>> InterpCx<'tcx, M> {
348348

349349
// Check that the memory between them is dereferenceable at all, starting from the
350350
// origin pointer: `dist` is `a - b`, so it is based on `b`.
351-
self.check_ptr_access_signed(b, dist, CheckInAllocMsg::OffsetFromTest)
351+
self.check_ptr_access_signed(b, dist, CheckInAllocMsg::Dereferenceable)
352352
.map_err_kind(|_| {
353353
// This could mean they point to different allocations, or they point to the same allocation
354354
// but not the entire range between the pointers is in-bounds.
@@ -372,7 +372,7 @@ impl<'tcx, M: Machine<'tcx>> InterpCx<'tcx, M> {
372372
self.check_ptr_access_signed(
373373
a,
374374
dist.checked_neg().unwrap(), // i64::MIN is impossible as no allocation can be that large
375-
CheckInAllocMsg::OffsetFromTest,
375+
CheckInAllocMsg::Dereferenceable,
376376
)
377377
.map_err_kind(|_| {
378378
// Make the error more specific.
@@ -651,7 +651,11 @@ impl<'tcx, M: Machine<'tcx>> InterpCx<'tcx, M> {
651651
offset_bytes: i64,
652652
) -> InterpResult<'tcx, Pointer<Option<M::Provenance>>> {
653653
// The offset must be in bounds starting from `ptr`.
654-
self.check_ptr_access_signed(ptr, offset_bytes, CheckInAllocMsg::PointerArithmeticTest)?;
654+
self.check_ptr_access_signed(
655+
ptr,
656+
offset_bytes,
657+
CheckInAllocMsg::InboundsPointerArithmetic,
658+
)?;
655659
// This also implies that there is no overflow, so we are done.
656660
interp_ok(ptr.wrapping_signed_offset(offset_bytes, self))
657661
}

compiler/rustc_const_eval/src/interpret/memory.rs

+8-8
Original file line numberDiff line numberDiff line change
@@ -351,7 +351,7 @@ impl<'tcx, M: Machine<'tcx>> InterpCx<'tcx, M> {
351351
kind = "static_mem"
352352
)
353353
}
354-
None => err_ub!(PointerUseAfterFree(alloc_id, CheckInAllocMsg::MemoryAccessTest)),
354+
None => err_ub!(PointerUseAfterFree(alloc_id, CheckInAllocMsg::MemoryAccess)),
355355
})
356356
.into();
357357
};
@@ -414,10 +414,10 @@ impl<'tcx, M: Machine<'tcx>> InterpCx<'tcx, M> {
414414
self,
415415
ptr,
416416
size,
417-
CheckInAllocMsg::MemoryAccessTest,
417+
CheckInAllocMsg::MemoryAccess,
418418
|this, alloc_id, offset, prov| {
419-
let (size, align) = this
420-
.get_live_alloc_size_and_align(alloc_id, CheckInAllocMsg::MemoryAccessTest)?;
419+
let (size, align) =
420+
this.get_live_alloc_size_and_align(alloc_id, CheckInAllocMsg::MemoryAccess)?;
421421
interp_ok((size, align, (alloc_id, offset, prov)))
422422
},
423423
)
@@ -613,7 +613,7 @@ impl<'tcx, M: Machine<'tcx>> InterpCx<'tcx, M> {
613613
}
614614
Some(GlobalAlloc::Function { .. }) => throw_ub!(DerefFunctionPointer(id)),
615615
Some(GlobalAlloc::VTable(..)) => throw_ub!(DerefVTablePointer(id)),
616-
None => throw_ub!(PointerUseAfterFree(id, CheckInAllocMsg::MemoryAccessTest)),
616+
None => throw_ub!(PointerUseAfterFree(id, CheckInAllocMsg::MemoryAccess)),
617617
Some(GlobalAlloc::Static(def_id)) => {
618618
assert!(self.tcx.is_static(def_id));
619619
// Thread-local statics do not have a constant address. They *must* be accessed via
@@ -707,7 +707,7 @@ impl<'tcx, M: Machine<'tcx>> InterpCx<'tcx, M> {
707707
self,
708708
ptr,
709709
size_i64,
710-
CheckInAllocMsg::MemoryAccessTest,
710+
CheckInAllocMsg::MemoryAccess,
711711
|this, alloc_id, offset, prov| {
712712
let alloc = this.get_alloc_raw(alloc_id)?;
713713
interp_ok((alloc.size(), alloc.align, (alloc_id, offset, prov, alloc)))
@@ -809,7 +809,7 @@ impl<'tcx, M: Machine<'tcx>> InterpCx<'tcx, M> {
809809
self,
810810
ptr,
811811
size_i64,
812-
CheckInAllocMsg::MemoryAccessTest,
812+
CheckInAllocMsg::MemoryAccess,
813813
|this, alloc_id, offset, prov| {
814814
let (alloc, machine) = this.get_alloc_raw_mut(alloc_id)?;
815815
interp_ok((alloc.size(), alloc.align, (alloc_id, offset, prov, alloc, machine)))
@@ -1615,7 +1615,7 @@ impl<'tcx, M: Machine<'tcx>> InterpCx<'tcx, M> {
16151615
err_ub!(DanglingIntPointer {
16161616
addr: offset,
16171617
inbounds_size: size,
1618-
msg: CheckInAllocMsg::InboundsTest
1618+
msg: CheckInAllocMsg::Dereferenceable
16191619
})
16201620
})
16211621
.into()

compiler/rustc_const_eval/src/interpret/validity.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -510,7 +510,7 @@ impl<'rt, 'tcx, M: Machine<'tcx>> ValidityVisitor<'rt, 'tcx, M> {
510510
self.ecx.check_ptr_access(
511511
place.ptr(),
512512
size,
513-
CheckInAllocMsg::InboundsTest, // will anyway be replaced by validity message
513+
CheckInAllocMsg::Dereferenceable, // will anyway be replaced by validity message
514514
),
515515
self.path,
516516
Ub(DanglingIntPointer { addr: 0, .. }) => NullPtr { ptr_kind },

compiler/rustc_lint/src/unused.rs

+16
Original file line numberDiff line numberDiff line change
@@ -942,6 +942,22 @@ trait UnusedDelimLint {
942942
match s.kind {
943943
StmtKind::Let(ref local) if Self::LINT_EXPR_IN_PATTERN_MATCHING_CTX => {
944944
if let Some((init, els)) = local.kind.init_else_opt() {
945+
if els.is_some()
946+
&& let ExprKind::Paren(paren) = &init.kind
947+
&& !init.span.eq_ctxt(paren.span)
948+
{
949+
// This branch prevents cases where parentheses wrap an expression
950+
// resulting from macro expansion, such as:
951+
// ```
952+
// macro_rules! x {
953+
// () => { None::<i32> };
954+
// }
955+
// let Some(_) = (x!{}) else { return };
956+
// // -> let Some(_) = (None::<i32>) else { return };
957+
// // ~ ~ No Lint
958+
// ```
959+
return;
960+
}
945961
let ctx = match els {
946962
None => UnusedDelimsCtx::AssignedValue,
947963
Some(_) => UnusedDelimsCtx::AssignedValueLetElse,

compiler/rustc_middle/src/mir/interpret/error.rs

+3-5
Original file line numberDiff line numberDiff line change
@@ -221,13 +221,11 @@ pub enum InvalidProgramInfo<'tcx> {
221221
#[derive(Debug, Copy, Clone)]
222222
pub enum CheckInAllocMsg {
223223
/// We are access memory.
224-
MemoryAccessTest,
224+
MemoryAccess,
225225
/// We are doing pointer arithmetic.
226-
PointerArithmeticTest,
227-
/// We are doing pointer offset_from.
228-
OffsetFromTest,
226+
InboundsPointerArithmetic,
229227
/// None of the above -- generic/unspecific inbounds test.
230-
InboundsTest,
228+
Dereferenceable,
231229
}
232230

233231
/// Details of which pointer is not aligned.

compiler/rustc_span/src/span_encoding.rs

+15-2
Original file line numberDiff line numberDiff line change
@@ -306,8 +306,21 @@ impl Span {
306306
/// Returns `true` if this span comes from any kind of macro, desugaring or inlining.
307307
#[inline]
308308
pub fn from_expansion(self) -> bool {
309-
// If the span is fully inferred then ctxt > MAX_CTXT
310-
self.inline_ctxt().map_or(true, |ctxt| !ctxt.is_root())
309+
let ctxt = match_span_kind! {
310+
self,
311+
// All branches here, except `InlineParent`, actually return `span.ctxt_or_parent_or_marker`.
312+
// Since `Interned` is selected if the field contains `CTXT_INTERNED_MARKER` returning that value
313+
// as the context allows the compiler to optimize out the branch that selects between either
314+
// `Interned` and `PartiallyInterned`.
315+
//
316+
// Interned contexts can never be the root context and `CTXT_INTERNED_MARKER` has a different value
317+
// than the root context so this works for checking is this is an expansion.
318+
InlineCtxt(span) => SyntaxContext::from_u16(span.ctxt),
319+
InlineParent(_span) => SyntaxContext::root(),
320+
PartiallyInterned(span) => SyntaxContext::from_u16(span.ctxt),
321+
Interned(_span) => SyntaxContext::from_u16(CTXT_INTERNED_MARKER),
322+
};
323+
!ctxt.is_root()
311324
}
312325

313326
/// Returns `true` if this is a dummy span with any hygienic context.

0 commit comments

Comments
 (0)