Skip to content

Rollup of 5 pull requests #136754

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 18 commits into from
Feb 9, 2025
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 0 additions & 7 deletions Cargo.lock
Original file line number Diff line number Diff line change
@@ -3287,13 +3287,6 @@ dependencies = [
"tikv-jemalloc-sys",
]

[[package]]
name = "rustc-perf-wrapper"
version = "0.1.0"
dependencies = [
"clap",
]

[[package]]
name = "rustc-rayon"
version = "0.5.1"
1 change: 0 additions & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
@@ -45,7 +45,6 @@ members = [
"src/tools/rustdoc-gui-test",
"src/tools/opt-dist",
"src/tools/coverage-dump",
"src/tools/rustc-perf-wrapper",
"src/tools/wasm-component-ld",
"src/tools/features-status-dump",
]
6 changes: 5 additions & 1 deletion compiler/rustc_codegen_llvm/src/debuginfo/mod.rs
Original file line number Diff line number Diff line change
@@ -97,7 +97,11 @@ impl<'ll, 'tcx> CodegenUnitDebugContext<'ll, 'tcx> {
// Android has the same issue (#22398)
llvm::add_module_flag_u32(
self.llmod,
llvm::ModuleFlagMergeBehavior::Warning,
// In the case where multiple CGUs with different dwarf version
// values are being merged together, such as with cross-crate
// LTO, then we want to use the highest version of dwarf
// we can. This matches Clang's behavior as well.
llvm::ModuleFlagMergeBehavior::Max,
"Dwarf Version",
sess.dwarf_version(),
);
2 changes: 1 addition & 1 deletion compiler/rustc_middle/src/mir/terminator.rs
Original file line number Diff line number Diff line change
@@ -272,7 +272,7 @@ impl<O> AssertKind<O> {
"\"misaligned pointer dereference: address must be a multiple of {{}} but is {{}}\", {required:?}, {found:?}"
)
}
NullPointerDereference => write!(f, "\"null pointer dereference occured\""),
NullPointerDereference => write!(f, "\"null pointer dereference occurred\""),
ResumedAfterReturn(CoroutineKind::Coroutine(_)) => {
write!(f, "\"coroutine resumed after completion\"")
}
2 changes: 2 additions & 0 deletions compiler/rustc_mir_transform/src/check_alignment.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
use rustc_index::IndexVec;
use rustc_middle::mir::interpret::Scalar;
use rustc_middle::mir::visit::PlaceContext;
use rustc_middle::mir::*;
use rustc_middle::ty::{Ty, TyCtxt};
use rustc_session::Session;
@@ -44,6 +45,7 @@ fn insert_alignment_check<'tcx>(
tcx: TyCtxt<'tcx>,
pointer: Place<'tcx>,
pointee_ty: Ty<'tcx>,
_context: PlaceContext,
local_decls: &mut IndexVec<Local, LocalDecl<'tcx>>,
stmts: &mut Vec<Statement<'tcx>>,
source_info: SourceInfo,
69 changes: 46 additions & 23 deletions compiler/rustc_mir_transform/src/check_null.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
use rustc_index::IndexVec;
use rustc_middle::mir::interpret::Scalar;
use rustc_middle::mir::visit::{MutatingUseContext, NonMutatingUseContext, PlaceContext};
use rustc_middle::mir::*;
use rustc_middle::ty::{Ty, TyCtxt};
use rustc_session::Session;
@@ -26,6 +26,7 @@ fn insert_null_check<'tcx>(
tcx: TyCtxt<'tcx>,
pointer: Place<'tcx>,
pointee_ty: Ty<'tcx>,
context: PlaceContext,
local_decls: &mut IndexVec<Local, LocalDecl<'tcx>>,
stmts: &mut Vec<Statement<'tcx>>,
source_info: SourceInfo,
@@ -42,30 +43,51 @@ fn insert_null_check<'tcx>(
let addr = local_decls.push(LocalDecl::with_source_info(tcx.types.usize, source_info)).into();
stmts.push(Statement { source_info, kind: StatementKind::Assign(Box::new((addr, rvalue))) });

// Get size of the pointee (zero-sized reads and writes are allowed).
let rvalue = Rvalue::NullaryOp(NullOp::SizeOf, pointee_ty);
let sizeof_pointee =
local_decls.push(LocalDecl::with_source_info(tcx.types.usize, source_info)).into();
stmts.push(Statement {
source_info,
kind: StatementKind::Assign(Box::new((sizeof_pointee, rvalue))),
});

// Check that the pointee is not a ZST.
let zero = Operand::Constant(Box::new(ConstOperand {
span: source_info.span,
user_ty: None,
const_: Const::Val(ConstValue::Scalar(Scalar::from_target_usize(0, &tcx)), tcx.types.usize),
const_: Const::Val(ConstValue::from_target_usize(0, &tcx), tcx.types.usize),
}));
let is_pointee_no_zst =
local_decls.push(LocalDecl::with_source_info(tcx.types.bool, source_info)).into();
stmts.push(Statement {
source_info,
kind: StatementKind::Assign(Box::new((
is_pointee_no_zst,
Rvalue::BinaryOp(BinOp::Ne, Box::new((Operand::Copy(sizeof_pointee), zero.clone()))),
))),
});

let pointee_should_be_checked = match context {
// Borrows pointing to "null" are UB even if the pointee is a ZST.
PlaceContext::NonMutatingUse(NonMutatingUseContext::SharedBorrow)
| PlaceContext::MutatingUse(MutatingUseContext::Borrow) => {
// Pointer should be checked unconditionally.
Operand::Constant(Box::new(ConstOperand {
span: source_info.span,
user_ty: None,
const_: Const::Val(ConstValue::from_bool(true), tcx.types.bool),
}))
}
// Other usages of null pointers only are UB if the pointee is not a ZST.
_ => {
let rvalue = Rvalue::NullaryOp(NullOp::SizeOf, pointee_ty);
let sizeof_pointee =
local_decls.push(LocalDecl::with_source_info(tcx.types.usize, source_info)).into();
stmts.push(Statement {
source_info,
kind: StatementKind::Assign(Box::new((sizeof_pointee, rvalue))),
});

// Check that the pointee is not a ZST.
let is_pointee_not_zst =
local_decls.push(LocalDecl::with_source_info(tcx.types.bool, source_info)).into();
stmts.push(Statement {
source_info,
kind: StatementKind::Assign(Box::new((
is_pointee_not_zst,
Rvalue::BinaryOp(
BinOp::Ne,
Box::new((Operand::Copy(sizeof_pointee), zero.clone())),
),
))),
});

// Pointer needs to be checked only if pointee is not a ZST.
Operand::Copy(is_pointee_not_zst)
}
};

// Check whether the pointer is null.
let is_null = local_decls.push(LocalDecl::with_source_info(tcx.types.bool, source_info)).into();
@@ -77,7 +99,8 @@ fn insert_null_check<'tcx>(
))),
});

// We want to throw an exception if the pointer is null and doesn't point to a ZST.
// We want to throw an exception if the pointer is null and the pointee is not unconditionally
// allowed (which for all non-borrow place uses, is when the pointee is ZST).
let should_throw_exception =
local_decls.push(LocalDecl::with_source_info(tcx.types.bool, source_info)).into();
stmts.push(Statement {
@@ -86,7 +109,7 @@ fn insert_null_check<'tcx>(
should_throw_exception,
Rvalue::BinaryOp(
BinOp::BitAnd,
Box::new((Operand::Copy(is_null), Operand::Copy(is_pointee_no_zst))),
Box::new((Operand::Copy(is_null), pointee_should_be_checked)),
),
))),
});
14 changes: 8 additions & 6 deletions compiler/rustc_mir_transform/src/check_pointers.rs
Original file line number Diff line number Diff line change
@@ -40,17 +40,18 @@ pub(crate) enum BorrowCheckMode {
/// success and fail the check otherwise.
/// This utility will insert a terminator block that asserts on the condition
/// and panics on failure.
pub(crate) fn check_pointers<'a, 'tcx, F>(
pub(crate) fn check_pointers<'tcx, F>(
tcx: TyCtxt<'tcx>,
body: &mut Body<'tcx>,
excluded_pointees: &'a [Ty<'tcx>],
excluded_pointees: &[Ty<'tcx>],
on_finding: F,
borrow_check_mode: BorrowCheckMode,
) where
F: Fn(
/* tcx: */ TyCtxt<'tcx>,
/* pointer: */ Place<'tcx>,
/* pointee_ty: */ Ty<'tcx>,
/* context: */ PlaceContext,
/* local_decls: */ &mut IndexVec<Local, LocalDecl<'tcx>>,
/* stmts: */ &mut Vec<Statement<'tcx>>,
/* source_info: */ SourceInfo,
@@ -86,7 +87,7 @@ pub(crate) fn check_pointers<'a, 'tcx, F>(
);
finder.visit_statement(statement, location);

for (local, ty) in finder.into_found_pointers() {
for (local, ty, context) in finder.into_found_pointers() {
debug!("Inserting check for {:?}", ty);
let new_block = split_block(basic_blocks, location);

@@ -98,6 +99,7 @@ pub(crate) fn check_pointers<'a, 'tcx, F>(
tcx,
local,
ty,
context,
local_decls,
&mut block_data.statements,
source_info,
@@ -125,7 +127,7 @@ struct PointerFinder<'a, 'tcx> {
tcx: TyCtxt<'tcx>,
local_decls: &'a mut LocalDecls<'tcx>,
typing_env: ty::TypingEnv<'tcx>,
pointers: Vec<(Place<'tcx>, Ty<'tcx>)>,
pointers: Vec<(Place<'tcx>, Ty<'tcx>, PlaceContext)>,
excluded_pointees: &'a [Ty<'tcx>],
borrow_check_mode: BorrowCheckMode,
}
@@ -148,7 +150,7 @@ impl<'a, 'tcx> PointerFinder<'a, 'tcx> {
}
}

fn into_found_pointers(self) -> Vec<(Place<'tcx>, Ty<'tcx>)> {
fn into_found_pointers(self) -> Vec<(Place<'tcx>, Ty<'tcx>, PlaceContext)> {
self.pointers
}

@@ -211,7 +213,7 @@ impl<'a, 'tcx> Visitor<'tcx> for PointerFinder<'a, 'tcx> {
return;
}

self.pointers.push((pointer, pointee_ty));
self.pointers.push((pointer, pointee_ty, context));

self.super_place(place, context, location);
}
2 changes: 1 addition & 1 deletion compiler/stable_mir/src/mir/body.rs
Original file line number Diff line number Diff line change
@@ -307,7 +307,7 @@ impl AssertMessage {
AssertMessage::MisalignedPointerDereference { .. } => {
Ok("misaligned pointer dereference")
}
AssertMessage::NullPointerDereference => Ok("null pointer dereference occured"),
AssertMessage::NullPointerDereference => Ok("null pointer dereference occurred"),
}
}
}
2 changes: 1 addition & 1 deletion compiler/stable_mir/src/mir/pretty.rs
Original file line number Diff line number Diff line change
@@ -299,7 +299,7 @@ fn pretty_assert_message<W: Write>(writer: &mut W, msg: &AssertMessage) -> io::R
)
}
AssertMessage::NullPointerDereference => {
write!(writer, "\"null pointer dereference occured.\"")
write!(writer, "\"null pointer dereference occurred\"")
}
AssertMessage::ResumedAfterReturn(_) | AssertMessage::ResumedAfterPanic(_) => {
write!(writer, "{}", msg.description().unwrap())
2 changes: 1 addition & 1 deletion library/core/src/panicking.rs
Original file line number Diff line number Diff line change
@@ -302,7 +302,7 @@ fn panic_null_pointer_dereference() -> ! {
}

panic_nounwind_fmt(
format_args!("null pointer dereference occured"),
format_args!("null pointer dereference occurred"),
/* force_no_backtrace */ false,
)
}
4 changes: 2 additions & 2 deletions library/std/src/fs.rs
Original file line number Diff line number Diff line change
@@ -2307,8 +2307,8 @@ impl AsInner<fs_imp::DirEntry> for DirEntry {
///
/// # Platform-specific behavior
///
/// This function currently corresponds to the `unlink` function on Unix
/// and the `DeleteFile` function on Windows.
/// This function currently corresponds to the `unlink` function on Unix.
/// On Windows, `DeleteFile` is used or `CreateFileW` and `SetInformationByHandle` for readonly files.
/// Note that, this [may change in the future][changes].
///
/// [changes]: io#platform-specific-behavior
2 changes: 1 addition & 1 deletion library/std/src/fs/tests.rs
Original file line number Diff line number Diff line change
@@ -1384,7 +1384,7 @@ fn file_try_clone() {
}

#[test]
#[cfg(not(windows))]
#[cfg(not(target_vendor = "win7"))]
fn unlink_readonly() {
let tmpdir = tmpdir();
let path = tmpdir.join("file");
Loading