Skip to content

Commit 3f9db90

Browse files
committed
Auto merge of rust-lang#11507 - J-ZhengLi:issue11485, r=dswij
trigger [`transmute_null_to_fn`] on chain of casts fixes: rust-lang#11485 changelog: trigger [`transmute_null_to_fn`] on chain of casts
2 parents 59636a2 + 1d76eed commit 3f9db90

File tree

3 files changed

+55
-12
lines changed

3 files changed

+55
-12
lines changed

clippy_lints/src/transmute/transmute_null_to_fn.rs

Lines changed: 19 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -28,35 +28,43 @@ pub(super) fn check<'tcx>(cx: &LateContext<'tcx>, expr: &'tcx Expr<'_>, arg: &'t
2828
return false;
2929
}
3030

31-
match arg.kind {
31+
let casts_peeled = peel_casts(arg);
32+
match casts_peeled.kind {
3233
// Catching:
3334
// transmute over constants that resolve to `null`.
34-
ExprKind::Path(ref _qpath) if matches!(constant(cx, cx.typeck_results(), arg), Some(Constant::RawPtr(0))) => {
35+
ExprKind::Path(ref _qpath)
36+
if matches!(
37+
constant(cx, cx.typeck_results(), casts_peeled),
38+
Some(Constant::RawPtr(0))
39+
) =>
40+
{
3541
lint_expr(cx, expr);
3642
true
3743
},
38-
39-
// Catching:
40-
// `std::mem::transmute(0 as *const i32)`
41-
ExprKind::Cast(inner_expr, _cast_ty) if is_integer_literal(inner_expr, 0) => {
42-
lint_expr(cx, expr);
43-
true
44-
},
45-
4644
// Catching:
4745
// `std::mem::transmute(std::ptr::null::<i32>())`
4846
ExprKind::Call(func1, []) if is_path_diagnostic_item(cx, func1, sym::ptr_null) => {
4947
lint_expr(cx, expr);
5048
true
5149
},
52-
5350
_ => {
5451
// FIXME:
5552
// Also catch transmutations of variables which are known nulls.
5653
// To do this, MIR const propagation seems to be the better tool.
5754
// Whenever MIR const prop routines are more developed, this will
5855
// become available. As of this writing (25/03/19) it is not yet.
56+
if is_integer_literal(casts_peeled, 0) {
57+
lint_expr(cx, expr);
58+
return true;
59+
}
5960
false
6061
},
6162
}
6263
}
64+
65+
fn peel_casts<'tcx>(expr: &'tcx Expr<'tcx>) -> &'tcx Expr<'tcx> {
66+
match &expr.kind {
67+
ExprKind::Cast(inner_expr, _) => peel_casts(inner_expr),
68+
_ => expr,
69+
}
70+
}

tests/ui/transmute_null_to_fn.rs

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,17 @@ fn transmute_const() {
2525
}
2626
}
2727

28+
fn issue_11485() {
29+
unsafe {
30+
let _: fn() = std::mem::transmute(0 as *const u8 as *const ());
31+
//~^ ERROR: transmuting a known null pointer into a function pointer
32+
let _: fn() = std::mem::transmute(std::ptr::null::<()>() as *const u8);
33+
//~^ ERROR: transmuting a known null pointer into a function pointer
34+
let _: fn() = std::mem::transmute(ZPTR as *const u8);
35+
//~^ ERROR: transmuting a known null pointer into a function pointer
36+
}
37+
}
38+
2839
fn main() {
2940
one_liners();
3041
transmute_const();

tests/ui/transmute_null_to_fn.stderr

Lines changed: 25 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,5 +24,29 @@ LL | let _: fn() = std::mem::transmute(ZPTR);
2424
|
2525
= help: try wrapping your function pointer type in `Option<T>` instead, and using `None` as a null pointer value
2626

27-
error: aborting due to 3 previous errors
27+
error: transmuting a known null pointer into a function pointer
28+
--> $DIR/transmute_null_to_fn.rs:30:23
29+
|
30+
LL | let _: fn() = std::mem::transmute(0 as *const u8 as *const ());
31+
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ this transmute results in undefined behavior
32+
|
33+
= help: try wrapping your function pointer type in `Option<T>` instead, and using `None` as a null pointer value
34+
35+
error: transmuting a known null pointer into a function pointer
36+
--> $DIR/transmute_null_to_fn.rs:32:23
37+
|
38+
LL | let _: fn() = std::mem::transmute(std::ptr::null::<()>() as *const u8);
39+
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ this transmute results in undefined behavior
40+
|
41+
= help: try wrapping your function pointer type in `Option<T>` instead, and using `None` as a null pointer value
42+
43+
error: transmuting a known null pointer into a function pointer
44+
--> $DIR/transmute_null_to_fn.rs:34:23
45+
|
46+
LL | let _: fn() = std::mem::transmute(ZPTR as *const u8);
47+
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ this transmute results in undefined behavior
48+
|
49+
= help: try wrapping your function pointer type in `Option<T>` instead, and using `None` as a null pointer value
50+
51+
error: aborting due to 6 previous errors
2852

0 commit comments

Comments
 (0)