Skip to content
This repository was archived by the owner on May 28, 2025. It is now read-only.

Commit a46e671

Browse files
committed
Implement requested changes
1 parent 2fc0231 commit a46e671

File tree

2 files changed

+30
-15
lines changed

2 files changed

+30
-15
lines changed

compiler/rustc_mir_transform/src/check_null.rs

Lines changed: 15 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -47,7 +47,7 @@ fn insert_null_check<'tcx>(
4747
kind: StatementKind::Assign(Box::new((sizeof_pointee, rvalue))),
4848
});
4949

50-
// Check that the pointee is a ZST.
50+
// Check that the pointee is not a ZST.
5151
let zero = Operand::Constant(Box::new(ConstOperand {
5252
span: source_info.span,
5353
user_ty: None,
@@ -59,11 +59,11 @@ fn insert_null_check<'tcx>(
5959
source_info,
6060
kind: StatementKind::Assign(Box::new((
6161
is_pointee_no_zst,
62-
Rvalue::BinaryOp(BinOp::Eq, Box::new((Operand::Copy(sizeof_pointee), zero.clone()))),
62+
Rvalue::BinaryOp(BinOp::Ne, Box::new((Operand::Copy(sizeof_pointee), zero.clone()))),
6363
))),
6464
});
6565

66-
// Check if the pointer is null.
66+
// Check whether the pointer is null.
6767
let is_null = local_decls.push(LocalDecl::with_source_info(tcx.types.bool, source_info)).into();
6868
stmts.push(Statement {
6969
source_info,
@@ -73,7 +73,7 @@ fn insert_null_check<'tcx>(
7373
))),
7474
});
7575

76-
// Check if the pointer is null or points to a ZST.
76+
// We want to throw an exception if the pointer is null and doesn't point to a ZST.
7777
let should_throw_exception =
7878
local_decls.push(LocalDecl::with_source_info(tcx.types.bool, source_info)).into();
7979
stmts.push(Statement {
@@ -87,10 +87,20 @@ fn insert_null_check<'tcx>(
8787
))),
8888
});
8989

90+
// The final condition whether this pointer usage is ok or not.
91+
let is_ok = local_decls.push(LocalDecl::with_source_info(tcx.types.bool, source_info)).into();
92+
stmts.push(Statement {
93+
source_info,
94+
kind: StatementKind::Assign(Box::new((
95+
is_ok,
96+
Rvalue::UnaryOp(UnOp::Not, Operand::Copy(should_throw_exception)),
97+
))),
98+
});
99+
90100
// Emit a PointerCheck that asserts on the condition and otherwise triggers
91101
// a AssertKind::NullPointerDereference.
92102
PointerCheck {
93-
cond: Operand::Copy(should_throw_exception),
103+
cond: Operand::Copy(is_ok),
94104
assert_kind: Box::new(AssertKind::NullPointerDereference),
95105
}
96106
}

compiler/rustc_mir_transform/src/check_pointers.rs

Lines changed: 15 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -12,17 +12,22 @@ pub(crate) struct PointerCheck<'tcx> {
1212
pub(crate) assert_kind: Box<AssertKind<Operand<'tcx>>>,
1313
}
1414

15-
/// Utility for adding a check for read/write on every sized, unsafe pointer.
15+
/// Utility for adding a check for read/write on every sized, raw pointer.
1616
///
17-
/// Visits every read/write access to a [Sized], unsafe pointer and inserts a
18-
/// new basic block directly before the pointer access. Then calls `on_finding`
19-
/// to insert the actual logic for a pointer check (e.g. check for alignment).
17+
/// Visits every read/write access to a [Sized], raw pointer and inserts a
18+
/// new basic block directly before the pointer access. (Read/write accesses
19+
/// are determined by the `PlaceContext` of the MIR visitor. In particular,
20+
/// uses of pointers in borrow expressions are *not* visited). Then calls
21+
/// `on_finding` to insert the actual logic for a pointer check (e.g. check for
22+
/// alignment).
2023
/// This utility takes care of the right order of blocks, the only thing a
2124
/// caller must do in `on_finding` is:
2225
/// - Append [Statement]s to `stmts`.
2326
/// - Append [LocalDecl]s to `local_decls`.
2427
/// - Return a [PointerCheck] that contains the condition and an [AssertKind].
25-
/// The AssertKind must be a panic with `#[rustc_nounwind]`.
28+
/// The AssertKind must be a panic with `#[rustc_nounwind]`. The condition
29+
/// should always return the boolean `is_ok`, so evaluate to true in case of
30+
/// success and fail the check otherwise.
2631
/// This utility will insert a terminator block that asserts on the condition
2732
/// and panics on failure.
2833
pub(crate) fn check_pointers<'a, 'tcx, F>(
@@ -151,17 +156,17 @@ impl<'a, 'tcx> Visitor<'tcx> for PointerFinder<'a, 'tcx> {
151156
let pointer = Place::from(place.local);
152157
let pointer_ty = self.local_decls[place.local].ty;
153158

154-
// We only want to check places based on unsafe pointers
159+
// We only want to check places based on raw pointers
155160
if !pointer_ty.is_unsafe_ptr() {
156-
trace!("Indirect, but not based on an unsafe ptr, not checking {:?}", place);
161+
trace!("Indirect, but not based on an raw ptr, not checking {:?}", place);
157162
return;
158163
}
159164

160165
let pointee_ty =
161-
pointer_ty.builtin_deref(true).expect("no builtin_deref for an unsafe pointer");
166+
pointer_ty.builtin_deref(true).expect("no builtin_deref for an raw pointer");
162167
// Ideally we'd support this in the future, but for now we are limited to sized types.
163168
if !pointee_ty.is_sized(self.tcx, self.typing_env) {
164-
debug!("Unsafe pointer, but pointee is not known to be sized: {:?}", pointer_ty);
169+
trace!("Raw pointer, but pointee is not known to be sized: {:?}", pointer_ty);
165170
return;
166171
}
167172

@@ -171,7 +176,7 @@ impl<'a, 'tcx> Visitor<'tcx> for PointerFinder<'a, 'tcx> {
171176
_ => pointee_ty,
172177
};
173178
if self.excluded_pointees.contains(&element_ty) {
174-
debug!("Skipping pointer for type: {:?}", pointee_ty);
179+
trace!("Skipping pointer for type: {:?}", pointee_ty);
175180
return;
176181
}
177182

0 commit comments

Comments
 (0)