Skip to content

Commit 25d617f

Browse files
Don't emit null pointer lint for raw ref of null deref
1 parent f27fdb5 commit 25d617f

File tree

3 files changed

+20
-24
lines changed

3 files changed

+20
-24
lines changed

compiler/rustc_lint/src/builtin.rs

+17-9
Original file line numberDiff line numberDiff line change
@@ -2679,8 +2679,8 @@ declare_lint! {
26792679
///
26802680
/// ### Explanation
26812681
///
2682-
/// Dereferencing a null pointer causes [undefined behavior] even as a place expression,
2683-
/// like `&*(0 as *const i32)` or `addr_of!(*(0 as *const i32))`.
2682+
/// Dereferencing a null pointer causes [undefined behavior] if it is accessed
2683+
/// (loaded from or stored to).
26842684
///
26852685
/// [undefined behavior]: https://doc.rust-lang.org/reference/behavior-considered-undefined.html
26862686
pub DEREF_NULLPTR,
@@ -2695,14 +2695,14 @@ impl<'tcx> LateLintPass<'tcx> for DerefNullPtr {
26952695
/// test if expression is a null ptr
26962696
fn is_null_ptr(cx: &LateContext<'_>, expr: &hir::Expr<'_>) -> bool {
26972697
match &expr.kind {
2698-
rustc_hir::ExprKind::Cast(expr, ty) => {
2699-
if let rustc_hir::TyKind::Ptr(_) = ty.kind {
2698+
hir::ExprKind::Cast(expr, ty) => {
2699+
if let hir::TyKind::Ptr(_) = ty.kind {
27002700
return is_zero(expr) || is_null_ptr(cx, expr);
27012701
}
27022702
}
27032703
// check for call to `core::ptr::null` or `core::ptr::null_mut`
2704-
rustc_hir::ExprKind::Call(path, _) => {
2705-
if let rustc_hir::ExprKind::Path(ref qpath) = path.kind {
2704+
hir::ExprKind::Call(path, _) => {
2705+
if let hir::ExprKind::Path(ref qpath) = path.kind {
27062706
if let Some(def_id) = cx.qpath_res(qpath, path.hir_id).opt_def_id() {
27072707
return matches!(
27082708
cx.tcx.get_diagnostic_name(def_id),
@@ -2719,7 +2719,7 @@ impl<'tcx> LateLintPass<'tcx> for DerefNullPtr {
27192719
/// test if expression is the literal `0`
27202720
fn is_zero(expr: &hir::Expr<'_>) -> bool {
27212721
match &expr.kind {
2722-
rustc_hir::ExprKind::Lit(lit) => {
2722+
hir::ExprKind::Lit(lit) => {
27232723
if let LitKind::Int(a, _) = lit.node {
27242724
return a == 0;
27252725
}
@@ -2729,8 +2729,16 @@ impl<'tcx> LateLintPass<'tcx> for DerefNullPtr {
27292729
false
27302730
}
27312731

2732-
if let rustc_hir::ExprKind::Unary(rustc_hir::UnOp::Deref, expr_deref) = expr.kind {
2733-
if is_null_ptr(cx, expr_deref) {
2732+
if let hir::ExprKind::Unary(hir::UnOp::Deref, expr_deref) = expr.kind
2733+
&& is_null_ptr(cx, expr_deref)
2734+
{
2735+
if let hir::Node::Expr(hir::Expr {
2736+
kind: hir::ExprKind::AddrOf(hir::BorrowKind::Raw, ..),
2737+
..
2738+
}) = cx.tcx.parent_hir_node(expr.hir_id)
2739+
{
2740+
// `&raw *NULL` is ok.
2741+
} else {
27342742
cx.emit_span_lint(
27352743
DEREF_NULLPTR,
27362744
expr.span,

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

+2-2
Original file line numberDiff line numberDiff line change
@@ -27,9 +27,9 @@ fn f() {
2727
let ub = &*ptr::null_mut::<i32>();
2828
//~^ ERROR dereferencing a null pointer
2929
ptr::addr_of!(*ptr::null::<i32>());
30-
//~^ ERROR dereferencing a null pointer
30+
// ^^ OKAY
3131
ptr::addr_of_mut!(*ptr::null_mut::<i32>());
32-
//~^ ERROR dereferencing a null pointer
32+
// ^^ OKAY
3333
let offset = ptr::addr_of!((*ptr::null::<Struct>()).field);
3434
//~^ ERROR dereferencing a null pointer
3535
}

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

+1-13
Original file line numberDiff line numberDiff line change
@@ -46,23 +46,11 @@ error: dereferencing a null pointer
4646
LL | let ub = &*ptr::null_mut::<i32>();
4747
| ^^^^^^^^^^^^^^^^^^^^^^^ this code causes undefined behavior when executed
4848

49-
error: dereferencing a null pointer
50-
--> $DIR/lint-deref-nullptr.rs:29:23
51-
|
52-
LL | ptr::addr_of!(*ptr::null::<i32>());
53-
| ^^^^^^^^^^^^^^^^^^^ this code causes undefined behavior when executed
54-
55-
error: dereferencing a null pointer
56-
--> $DIR/lint-deref-nullptr.rs:31:27
57-
|
58-
LL | ptr::addr_of_mut!(*ptr::null_mut::<i32>());
59-
| ^^^^^^^^^^^^^^^^^^^^^^^ this code causes undefined behavior when executed
60-
6149
error: dereferencing a null pointer
6250
--> $DIR/lint-deref-nullptr.rs:33:36
6351
|
6452
LL | let offset = ptr::addr_of!((*ptr::null::<Struct>()).field);
6553
| ^^^^^^^^^^^^^^^^^^^^^^^^ this code causes undefined behavior when executed
6654

67-
error: aborting due to 10 previous errors
55+
error: aborting due to 8 previous errors
6856

0 commit comments

Comments
 (0)