Skip to content

Commit ab634f5

Browse files
committed
Don't lint on derefs of null pointers to ZSTs
1 parent 3b9de6f commit ab634f5

File tree

3 files changed

+27
-15
lines changed

3 files changed

+27
-15
lines changed

compiler/rustc_lint/src/builtin.rs

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2726,6 +2726,16 @@ impl<'tcx> LateLintPass<'tcx> for DerefNullPtr {
27262726
fn check_expr(&mut self, cx: &LateContext<'tcx>, expr: &hir::Expr<'_>) {
27272727
/// test if expression is a null ptr
27282728
fn is_null_ptr(cx: &LateContext<'_>, expr: &hir::Expr<'_>) -> bool {
2729+
let pointer_ty = cx.typeck_results().expr_ty(expr);
2730+
let ty::RawPtr(pointee, _) = pointer_ty.kind() else {
2731+
return false;
2732+
};
2733+
if let Ok(layout) = cx.tcx.layout_of(cx.typing_env().as_query_input(*pointee)) {
2734+
if layout.layout.size() == rustc_abi::Size::ZERO {
2735+
return false;
2736+
}
2737+
}
2738+
27292739
match &expr.kind {
27302740
hir::ExprKind::Cast(expr, ty) => {
27312741
if let hir::TyKind::Ptr(_) = ty.kind {

tests/ui/lint/lint-deref-nullptr.rs

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,14 @@
11
// test the deref_nullptr lint
22

3-
#![deny(deref_nullptr)]
4-
53
use std::ptr;
64

75
struct Struct {
86
field: u8,
97
}
108

9+
#[derive(Clone, Copy)]
10+
struct Zst;
11+
1112
fn f() {
1213
unsafe {
1314
let a = 1;
@@ -32,6 +33,11 @@ fn f() {
3233
// ^^ OKAY
3334
let offset = ptr::addr_of!((*ptr::null::<Struct>()).field);
3435
//~^ ERROR dereferencing a null pointer
36+
37+
// Make sure the lint permits derefs of null pointers to ZSTs
38+
let ok: Zst = *ptr::null();
39+
let ok: Zst = *ptr::null_mut();
40+
let ok: Zst = *(0 as *const Zst);
3541
}
3642
}
3743

tests/ui/lint/lint-deref-nullptr.stderr

Lines changed: 9 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1,53 +1,49 @@
11
error: dereferencing a null pointer
2-
--> $DIR/lint-deref-nullptr.rs:15:18
2+
--> $DIR/lint-deref-nullptr.rs:16:18
33
|
44
LL | let ub = *(0 as *const i32);
55
| ^^^^^^^^^^^^^^^^^^ this code causes undefined behavior when executed
66
|
7-
note: the lint level is defined here
8-
--> $DIR/lint-deref-nullptr.rs:3:9
9-
|
10-
LL | #![deny(deref_nullptr)]
11-
| ^^^^^^^^^^^^^
7+
= note: `#[deny(deref_nullptr)]` on by default
128

139
error: dereferencing a null pointer
14-
--> $DIR/lint-deref-nullptr.rs:17:18
10+
--> $DIR/lint-deref-nullptr.rs:18:18
1511
|
1612
LL | let ub = *ptr::null::<i32>();
1713
| ^^^^^^^^^^^^^^^^^^^ this code causes undefined behavior when executed
1814

1915
error: dereferencing a null pointer
20-
--> $DIR/lint-deref-nullptr.rs:19:18
16+
--> $DIR/lint-deref-nullptr.rs:20:18
2117
|
2218
LL | let ub = *ptr::null_mut::<i32>();
2319
| ^^^^^^^^^^^^^^^^^^^^^^^ this code causes undefined behavior when executed
2420

2521
error: dereferencing a null pointer
26-
--> $DIR/lint-deref-nullptr.rs:21:18
22+
--> $DIR/lint-deref-nullptr.rs:22:18
2723
|
2824
LL | let ub = *(ptr::null::<i16>() as *const i32);
2925
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ this code causes undefined behavior when executed
3026

3127
error: dereferencing a null pointer
32-
--> $DIR/lint-deref-nullptr.rs:23:18
28+
--> $DIR/lint-deref-nullptr.rs:24:18
3329
|
3430
LL | let ub = *(ptr::null::<i16>() as *mut i32 as *mut usize as *const u8);
3531
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ this code causes undefined behavior when executed
3632

3733
error: dereferencing a null pointer
38-
--> $DIR/lint-deref-nullptr.rs:25:19
34+
--> $DIR/lint-deref-nullptr.rs:26:19
3935
|
4036
LL | let ub = &*ptr::null::<i32>();
4137
| ^^^^^^^^^^^^^^^^^^^ this code causes undefined behavior when executed
4238

4339
error: dereferencing a null pointer
44-
--> $DIR/lint-deref-nullptr.rs:27:19
40+
--> $DIR/lint-deref-nullptr.rs:28:19
4541
|
4642
LL | let ub = &*ptr::null_mut::<i32>();
4743
| ^^^^^^^^^^^^^^^^^^^^^^^ this code causes undefined behavior when executed
4844

4945
error: dereferencing a null pointer
50-
--> $DIR/lint-deref-nullptr.rs:33:36
46+
--> $DIR/lint-deref-nullptr.rs:34:36
5147
|
5248
LL | let offset = ptr::addr_of!((*ptr::null::<Struct>()).field);
5349
| ^^^^^^^^^^^^^^^^^^^^^^^^ this code causes undefined behavior when executed

0 commit comments

Comments
 (0)