Skip to content

Commit 51ea9bb

Browse files
committed
Auto merge of rust-lang#96253 - Dylan-DPC:rollup-87hpds5, r=Dylan-DPC
Rollup of 6 pull requests Successful merges: - rust-lang#93313 (Check if call return type is visibly uninhabited when building MIR) - rust-lang#96160 (Miri/interpreter debugging tweaks) - rust-lang#96167 (Replace sys/unix/weak AtomicUsize with AtomicPtr) - rust-lang#96168 (Improve AddrParseError description) - rust-lang#96206 (Use sys::unix::locks::futex* on wasm+atomics.) - rust-lang#96234 (remove_dir_all_recursive: treat ELOOP the same as ENOTDIR) Failed merges: r? `@ghost` `@rustbot` modify labels: rollup
2 parents 3e69bda + 2443cf2 commit 51ea9bb

31 files changed

+267
-491
lines changed

Diff for: compiler/rustc_const_eval/src/interpret/eval_context.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -679,7 +679,7 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
679679
return_place: Option<&PlaceTy<'tcx, M::PointerTag>>,
680680
return_to_block: StackPopCleanup,
681681
) -> InterpResult<'tcx> {
682-
debug!("body: {:#?}", body);
682+
trace!("body: {:#?}", body);
683683
// first push a stack frame so we have access to the local substs
684684
let pre_frame = Frame {
685685
body,
@@ -836,7 +836,7 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
836836
return Ok(());
837837
}
838838

839-
debug!("locals: {:#?}", frame.locals);
839+
trace!("locals: {:#?}", frame.locals);
840840

841841
// Cleanup: deallocate all locals that are backed by an allocation.
842842
for local in &frame.locals {

Diff for: compiler/rustc_const_eval/src/interpret/memory.rs

+21-4
Original file line numberDiff line numberDiff line change
@@ -870,9 +870,17 @@ impl<'tcx, 'a, Tag: Provenance, Extra> AllocRefMut<'a, 'tcx, Tag, Extra> {
870870
range: AllocRange,
871871
val: ScalarMaybeUninit<Tag>,
872872
) -> InterpResult<'tcx> {
873+
let range = self.range.subrange(range);
874+
debug!(
875+
"write_scalar in {} at {:#x}, size {}: {:?}",
876+
self.alloc_id,
877+
range.start.bytes(),
878+
range.size.bytes(),
879+
val
880+
);
873881
Ok(self
874882
.alloc
875-
.write_scalar(&self.tcx, self.range.subrange(range), val)
883+
.write_scalar(&self.tcx, range, val)
876884
.map_err(|e| e.to_interp_error(self.alloc_id))?)
877885
}
878886

@@ -895,10 +903,19 @@ impl<'tcx, 'a, Tag: Provenance, Extra> AllocRefMut<'a, 'tcx, Tag, Extra> {
895903

896904
impl<'tcx, 'a, Tag: Provenance, Extra> AllocRef<'a, 'tcx, Tag, Extra> {
897905
pub fn read_scalar(&self, range: AllocRange) -> InterpResult<'tcx, ScalarMaybeUninit<Tag>> {
898-
Ok(self
906+
let range = self.range.subrange(range);
907+
let res = self
899908
.alloc
900-
.read_scalar(&self.tcx, self.range.subrange(range))
901-
.map_err(|e| e.to_interp_error(self.alloc_id))?)
909+
.read_scalar(&self.tcx, range)
910+
.map_err(|e| e.to_interp_error(self.alloc_id))?;
911+
debug!(
912+
"read_scalar in {} at {:#x}, size {}: {:?}",
913+
self.alloc_id,
914+
range.start.bytes(),
915+
range.size.bytes(),
916+
res
917+
);
918+
Ok(res)
902919
}
903920

904921
pub fn read_ptr_sized(&self, offset: Size) -> InterpResult<'tcx, ScalarMaybeUninit<Tag>> {

Diff for: compiler/rustc_middle/src/mir/interpret/allocation.rs

+8
Original file line numberDiff line numberDiff line change
@@ -515,6 +515,9 @@ impl<Tag: Copy, Extra> Allocation<Tag, Extra> {
515515
if Tag::ERR_ON_PARTIAL_PTR_OVERWRITE {
516516
return Err(AllocError::PartialPointerOverwrite(first));
517517
}
518+
warn!(
519+
"Partial pointer overwrite! De-initializing memory at offsets {first:?}..{start:?}."
520+
);
518521
self.init_mask.set_range(first, start, false);
519522
}
520523
if last > end {
@@ -523,10 +526,15 @@ impl<Tag: Copy, Extra> Allocation<Tag, Extra> {
523526
last - cx.data_layout().pointer_size,
524527
));
525528
}
529+
warn!(
530+
"Partial pointer overwrite! De-initializing memory at offsets {end:?}..{last:?}."
531+
);
526532
self.init_mask.set_range(end, last, false);
527533
}
528534

529535
// Forget all the relocations.
536+
// Since relocations do not overlap, we know that removing until `last` (exclusive) is fine,
537+
// i.e., this will not remove any other relocations just after the ones we care about.
530538
self.relocations.0.remove_range(first..last);
531539

532540
Ok(())

Diff for: compiler/rustc_mir_build/src/build/expr/into.rs

+9-4
Original file line numberDiff line numberDiff line change
@@ -255,10 +255,15 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
255255
func: fun,
256256
args,
257257
cleanup: None,
258-
// FIXME(varkor): replace this with an uninhabitedness-based check.
259-
// This requires getting access to the current module to call
260-
// `tcx.is_ty_uninhabited_from`, which is currently tricky to do.
261-
destination: if expr.ty.is_never() {
258+
// The presence or absence of a return edge affects control-flow sensitive
259+
// MIR checks and ultimately whether code is accepted or not. We can only
260+
// omit the return edge if a return type is visibly uninhabited to a module
261+
// that makes the call.
262+
destination: if this.tcx.is_ty_uninhabited_from(
263+
this.parent_module,
264+
expr.ty,
265+
this.param_env,
266+
) {
262267
None
263268
} else {
264269
Some((destination, success))

Diff for: compiler/rustc_mir_build/src/build/mod.rs

+4-1
Original file line numberDiff line numberDiff line change
@@ -350,6 +350,7 @@ struct Builder<'a, 'tcx> {
350350

351351
def_id: DefId,
352352
hir_id: hir::HirId,
353+
parent_module: DefId,
353354
check_overflow: bool,
354355
fn_span: Span,
355356
arg_count: usize,
@@ -807,15 +808,17 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
807808
);
808809

809810
let lint_level = LintLevel::Explicit(hir_id);
811+
let param_env = tcx.param_env(def.did);
810812
let mut builder = Builder {
811813
thir,
812814
tcx,
813815
infcx,
814816
typeck_results: tcx.typeck_opt_const_arg(def),
815817
region_scope_tree: tcx.region_scope_tree(def.did),
816-
param_env: tcx.param_env(def.did),
818+
param_env,
817819
def_id: def.did.to_def_id(),
818820
hir_id,
821+
parent_module: tcx.parent_module(hir_id).to_def_id(),
819822
check_overflow,
820823
cfg: CFG { basic_blocks: IndexVec::new() },
821824
fn_span: span,

Diff for: library/std/src/net/parser.rs

+28-11
Original file line numberDiff line numberDiff line change
@@ -59,12 +59,12 @@ impl<'a> Parser<'a> {
5959

6060
/// Run a parser, but fail if the entire input wasn't consumed.
6161
/// Doesn't run atomically.
62-
fn parse_with<T, F>(&mut self, inner: F) -> Result<T, AddrParseError>
62+
fn parse_with<T, F>(&mut self, inner: F, kind: AddrKind) -> Result<T, AddrParseError>
6363
where
6464
F: FnOnce(&mut Parser<'_>) -> Option<T>,
6565
{
6666
let result = inner(self);
67-
if self.state.is_empty() { result } else { None }.ok_or(AddrParseError(()))
67+
if self.state.is_empty() { result } else { None }.ok_or(AddrParseError(kind))
6868
}
6969

7070
/// Peek the next character from the input
@@ -278,7 +278,7 @@ impl<'a> Parser<'a> {
278278
impl FromStr for IpAddr {
279279
type Err = AddrParseError;
280280
fn from_str(s: &str) -> Result<IpAddr, AddrParseError> {
281-
Parser::new(s).parse_with(|p| p.read_ip_addr())
281+
Parser::new(s).parse_with(|p| p.read_ip_addr(), AddrKind::Ip)
282282
}
283283
}
284284

@@ -288,9 +288,9 @@ impl FromStr for Ipv4Addr {
288288
fn from_str(s: &str) -> Result<Ipv4Addr, AddrParseError> {
289289
// don't try to parse if too long
290290
if s.len() > 15 {
291-
Err(AddrParseError(()))
291+
Err(AddrParseError(AddrKind::Ipv4))
292292
} else {
293-
Parser::new(s).parse_with(|p| p.read_ipv4_addr())
293+
Parser::new(s).parse_with(|p| p.read_ipv4_addr(), AddrKind::Ipv4)
294294
}
295295
}
296296
}
@@ -299,34 +299,44 @@ impl FromStr for Ipv4Addr {
299299
impl FromStr for Ipv6Addr {
300300
type Err = AddrParseError;
301301
fn from_str(s: &str) -> Result<Ipv6Addr, AddrParseError> {
302-
Parser::new(s).parse_with(|p| p.read_ipv6_addr())
302+
Parser::new(s).parse_with(|p| p.read_ipv6_addr(), AddrKind::Ipv6)
303303
}
304304
}
305305

306306
#[stable(feature = "socket_addr_from_str", since = "1.5.0")]
307307
impl FromStr for SocketAddrV4 {
308308
type Err = AddrParseError;
309309
fn from_str(s: &str) -> Result<SocketAddrV4, AddrParseError> {
310-
Parser::new(s).parse_with(|p| p.read_socket_addr_v4())
310+
Parser::new(s).parse_with(|p| p.read_socket_addr_v4(), AddrKind::SocketV4)
311311
}
312312
}
313313

314314
#[stable(feature = "socket_addr_from_str", since = "1.5.0")]
315315
impl FromStr for SocketAddrV6 {
316316
type Err = AddrParseError;
317317
fn from_str(s: &str) -> Result<SocketAddrV6, AddrParseError> {
318-
Parser::new(s).parse_with(|p| p.read_socket_addr_v6())
318+
Parser::new(s).parse_with(|p| p.read_socket_addr_v6(), AddrKind::SocketV6)
319319
}
320320
}
321321

322322
#[stable(feature = "rust1", since = "1.0.0")]
323323
impl FromStr for SocketAddr {
324324
type Err = AddrParseError;
325325
fn from_str(s: &str) -> Result<SocketAddr, AddrParseError> {
326-
Parser::new(s).parse_with(|p| p.read_socket_addr())
326+
Parser::new(s).parse_with(|p| p.read_socket_addr(), AddrKind::Socket)
327327
}
328328
}
329329

330+
#[derive(Debug, Clone, PartialEq, Eq)]
331+
enum AddrKind {
332+
Ip,
333+
Ipv4,
334+
Ipv6,
335+
Socket,
336+
SocketV4,
337+
SocketV6,
338+
}
339+
330340
/// An error which can be returned when parsing an IP address or a socket address.
331341
///
332342
/// This error is used as the error type for the [`FromStr`] implementation for
@@ -353,7 +363,7 @@ impl FromStr for SocketAddr {
353363
/// ```
354364
#[stable(feature = "rust1", since = "1.0.0")]
355365
#[derive(Debug, Clone, PartialEq, Eq)]
356-
pub struct AddrParseError(());
366+
pub struct AddrParseError(AddrKind);
357367

358368
#[stable(feature = "addr_parse_error_error", since = "1.4.0")]
359369
impl fmt::Display for AddrParseError {
@@ -367,6 +377,13 @@ impl fmt::Display for AddrParseError {
367377
impl Error for AddrParseError {
368378
#[allow(deprecated)]
369379
fn description(&self) -> &str {
370-
"invalid IP address syntax"
380+
match self.0 {
381+
AddrKind::Ip => "invalid IP address syntax",
382+
AddrKind::Ipv4 => "invalid IPv4 address syntax",
383+
AddrKind::Ipv6 => "invalid IPv6 address syntax",
384+
AddrKind::Socket => "invalid socket address syntax",
385+
AddrKind::SocketV4 => "invalid IPv4 socket address syntax",
386+
AddrKind::SocketV6 => "invalid IPv6 socket address syntax",
387+
}
371388
}
372389
}

Diff for: library/std/src/sys/unix/fs.rs

+2-1
Original file line numberDiff line numberDiff line change
@@ -1647,8 +1647,9 @@ mod remove_dir_impl {
16471647
fn remove_dir_all_recursive(parent_fd: Option<RawFd>, path: &CStr) -> io::Result<()> {
16481648
// try opening as directory
16491649
let fd = match openat_nofollow_dironly(parent_fd, &path) {
1650-
Err(err) if err.raw_os_error() == Some(libc::ENOTDIR) => {
1650+
Err(err) if matches!(err.raw_os_error(), Some(libc::ENOTDIR | libc::ELOOP)) => {
16511651
// not a directory - don't traverse further
1652+
// (for symlinks, older Linux kernels may return ELOOP instead of ENOTDIR)
16521653
return match parent_fd {
16531654
// unlink...
16541655
Some(parent_fd) => {

Diff for: library/std/src/sys/unix/weak.rs

+15-17
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,8 @@
2525
use crate::ffi::CStr;
2626
use crate::marker::PhantomData;
2727
use crate::mem;
28-
use crate::sync::atomic::{self, AtomicUsize, Ordering};
28+
use crate::ptr;
29+
use crate::sync::atomic::{self, AtomicPtr, Ordering};
2930

3031
// We can use true weak linkage on ELF targets.
3132
#[cfg(not(any(target_os = "macos", target_os = "ios")))]
@@ -83,25 +84,25 @@ pub(crate) macro dlsym {
8384
}
8485
pub(crate) struct DlsymWeak<F> {
8586
name: &'static str,
86-
addr: AtomicUsize,
87+
func: AtomicPtr<libc::c_void>,
8788
_marker: PhantomData<F>,
8889
}
8990

9091
impl<F> DlsymWeak<F> {
9192
pub(crate) const fn new(name: &'static str) -> Self {
92-
DlsymWeak { name, addr: AtomicUsize::new(1), _marker: PhantomData }
93+
DlsymWeak { name, func: AtomicPtr::new(ptr::invalid_mut(1)), _marker: PhantomData }
9394
}
9495

9596
#[inline]
9697
pub(crate) fn get(&self) -> Option<F> {
9798
unsafe {
9899
// Relaxed is fine here because we fence before reading through the
99100
// pointer (see the comment below).
100-
match self.addr.load(Ordering::Relaxed) {
101-
1 => self.initialize(),
102-
0 => None,
103-
addr => {
104-
let func = mem::transmute_copy::<usize, F>(&addr);
101+
match self.func.load(Ordering::Relaxed) {
102+
func if func.addr() == 1 => self.initialize(),
103+
func if func.is_null() => None,
104+
func => {
105+
let func = mem::transmute_copy::<*mut libc::c_void, F>(&func);
105106
// The caller is presumably going to read through this value
106107
// (by calling the function we've dlsymed). This means we'd
107108
// need to have loaded it with at least C11's consume
@@ -129,25 +130,22 @@ impl<F> DlsymWeak<F> {
129130
// Cold because it should only happen during first-time initialization.
130131
#[cold]
131132
unsafe fn initialize(&self) -> Option<F> {
132-
assert_eq!(mem::size_of::<F>(), mem::size_of::<usize>());
133+
assert_eq!(mem::size_of::<F>(), mem::size_of::<*mut libc::c_void>());
133134

134135
let val = fetch(self.name);
135136
// This synchronizes with the acquire fence in `get`.
136-
self.addr.store(val, Ordering::Release);
137+
self.func.store(val, Ordering::Release);
137138

138-
match val {
139-
0 => None,
140-
addr => Some(mem::transmute_copy::<usize, F>(&addr)),
141-
}
139+
if val.is_null() { None } else { Some(mem::transmute_copy::<*mut libc::c_void, F>(&val)) }
142140
}
143141
}
144142

145-
unsafe fn fetch(name: &str) -> usize {
143+
unsafe fn fetch(name: &str) -> *mut libc::c_void {
146144
let name = match CStr::from_bytes_with_nul(name.as_bytes()) {
147145
Ok(cstr) => cstr,
148-
Err(..) => return 0,
146+
Err(..) => return ptr::null_mut(),
149147
};
150-
libc::dlsym(libc::RTLD_DEFAULT, name.as_ptr()) as usize
148+
libc::dlsym(libc::RTLD_DEFAULT, name.as_ptr())
151149
}
152150

153151
#[cfg(not(any(target_os = "linux", target_os = "android")))]

0 commit comments

Comments
 (0)