Skip to content

Commit d9d6b3b

Browse files
committed
turns out that dangling pointer branch is dead code; remove it and improve the error that actually gets shown a bit
1 parent 317c6ac commit d9d6b3b

File tree

5 files changed

+97
-49
lines changed

5 files changed

+97
-49
lines changed

src/librustc_mir/interpret/validity.rs

+9-12
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ use std::hash::Hash;
1111

1212
use super::{
1313
GlobalAlloc, InterpResult, InterpError,
14-
OpTy, Machine, InterpCx, ValueVisitor, MPlaceTy, AllocCheck,
14+
OpTy, Machine, InterpCx, ValueVisitor, MPlaceTy,
1515
};
1616

1717
macro_rules! validation_failure {
@@ -502,17 +502,14 @@ impl<'rt, 'mir, 'tcx, M: Machine<'mir, 'tcx>> ValueVisitor<'mir, 'tcx, M>
502502
if lo == 1 && hi == max_hi {
503503
// Only NULL is the niche. So make sure the ptr is NOT NULL.
504504
if self.ecx.memory.ptr_may_be_null(ptr) {
505-
// These conditions are just here to improve the diagnostics so we can
506-
// differentiate between null pointers and dangling pointers.
507-
if self.ref_tracking_for_consts.is_some() &&
508-
self.ecx.memory.get_size_and_align(ptr.alloc_id, AllocCheck::Live)
509-
.is_err()
510-
{
511-
return validation_failure!(
512-
"a dangling pointer", self.path
513-
);
514-
}
515-
return validation_failure!("a potentially NULL pointer", self.path);
505+
return validation_failure!(
506+
"a potentially NULL pointer",
507+
self.path,
508+
format!(
509+
"something that cannot possibly fail to be {}",
510+
wrapping_range_format(&layout.valid_range, max_hi)
511+
)
512+
);
516513
}
517514
return Ok(());
518515
} else {

src/test/ui/consts/const-eval/ub-enum.rs

+22-10
Original file line numberDiff line numberDiff line change
@@ -1,17 +1,31 @@
11
#![allow(const_err)] // make sure we cannot allow away the errors tested here
22

3+
4+
#[repr(transparent)]
5+
#[derive(Copy, Clone)]
6+
struct Wrap<T>(T);
7+
38
#[repr(usize)]
49
#[derive(Copy, Clone)]
510
enum Enum {
611
A = 0,
712
}
813
union TransmuteEnum {
914
in1: &'static u8,
15+
in2: usize,
1016
out1: Enum,
17+
out2: Wrap<Enum>,
1118
}
1219

13-
// A pointer is guaranteed non-null
14-
const BAD_ENUM: Enum = unsafe { TransmuteEnum { in1: &1 }.out1 };
20+
const GOOD_ENUM: Enum = unsafe { TransmuteEnum { in2: 0 }.out1 };
21+
22+
const BAD_ENUM: Enum = unsafe { TransmuteEnum { in2: 1 }.out1 };
23+
//~^ ERROR is undefined behavior
24+
25+
const BAD_ENUM_PTR: Enum = unsafe { TransmuteEnum { in1: &1 }.out1 };
26+
//~^ ERROR is undefined behavior
27+
28+
const BAD_ENUM_WRAPPED: Wrap<Enum> = unsafe { TransmuteEnum { in1: &1 }.out2 };
1529
//~^ ERROR is undefined behavior
1630

1731
// (Potentially) invalid enum discriminant
@@ -20,9 +34,7 @@ const BAD_ENUM: Enum = unsafe { TransmuteEnum { in1: &1 }.out1 };
2034
enum Enum2 {
2135
A = 2,
2236
}
23-
#[repr(transparent)]
24-
#[derive(Copy, Clone)]
25-
struct Wrap<T>(T);
37+
2638
union TransmuteEnum2 {
2739
in1: usize,
2840
in2: &'static u8,
@@ -33,17 +45,17 @@ union TransmuteEnum2 {
3345
}
3446
const BAD_ENUM2: Enum2 = unsafe { TransmuteEnum2 { in1: 0 }.out1 };
3547
//~^ ERROR is undefined behavior
36-
const BAD_ENUM3: Enum2 = unsafe { TransmuteEnum2 { in2: &0 }.out1 };
48+
const BAD_ENUM2_PTR: Enum2 = unsafe { TransmuteEnum2 { in2: &0 }.out1 };
3749
//~^ ERROR is undefined behavior
38-
const BAD_ENUM4: Wrap<Enum2> = unsafe { TransmuteEnum2 { in2: &0 }.out2 };
50+
const BAD_ENUM2_WRAPPED: Wrap<Enum2> = unsafe { TransmuteEnum2 { in2: &0 }.out2 };
3951
//~^ ERROR is undefined behavior
4052

4153
// Undef enum discriminant.
42-
const BAD_ENUM_UNDEF : Enum2 = unsafe { TransmuteEnum2 { in3: () }.out1 };
54+
const BAD_ENUM2_UNDEF : Enum2 = unsafe { TransmuteEnum2 { in3: () }.out1 };
4355
//~^ ERROR is undefined behavior
4456

4557
// Pointer value in an enum with a niche that is not just 0.
46-
const BAD_ENUM_PTR: Option<Enum2> = unsafe { TransmuteEnum2 { in2: &0 }.out3 };
58+
const BAD_ENUM2_OPTION_PTR: Option<Enum2> = unsafe { TransmuteEnum2 { in2: &0 }.out3 };
4759
//~^ ERROR is undefined behavior
4860

4961
// Invalid enum field content (mostly to test printing of paths for enum tuple
@@ -53,7 +65,7 @@ union TransmuteChar {
5365
b: char,
5466
}
5567
// Need to create something which does not clash with enum layout optimizations.
56-
const BAD_ENUM_CHAR: Option<(char, char)> = Some(('x', unsafe { TransmuteChar { a: !0 }.b }));
68+
const BAD_OPTION_CHAR: Option<(char, char)> = Some(('x', unsafe { TransmuteChar { a: !0 }.b }));
5769
//~^ ERROR is undefined behavior
5870

5971
fn main() {
+36-20
Original file line numberDiff line numberDiff line change
@@ -1,59 +1,75 @@
11
error[E0080]: it is undefined behavior to use this value
2-
--> $DIR/ub-enum.rs:14:1
2+
--> $DIR/ub-enum.rs:22:1
33
|
4-
LL | const BAD_ENUM: Enum = unsafe { TransmuteEnum { in1: &1 }.out1 };
5-
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ type validation failed: encountered a pointer, but expected a valid enum discriminant
4+
LL | const BAD_ENUM: Enum = unsafe { TransmuteEnum { in2: 1 }.out1 };
5+
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ type validation failed: encountered 1, but expected a valid enum discriminant
66
|
77
= note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rust compiler repository if you believe it should not be considered undefined behavior
88

99
error[E0080]: it is undefined behavior to use this value
10-
--> $DIR/ub-enum.rs:34:1
10+
--> $DIR/ub-enum.rs:25:1
11+
|
12+
LL | const BAD_ENUM_PTR: Enum = unsafe { TransmuteEnum { in1: &1 }.out1 };
13+
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ type validation failed: encountered a pointer, but expected a valid enum discriminant
14+
|
15+
= note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rust compiler repository if you believe it should not be considered undefined behavior
16+
17+
error[E0080]: it is undefined behavior to use this value
18+
--> $DIR/ub-enum.rs:28:1
19+
|
20+
LL | const BAD_ENUM_WRAPPED: Wrap<Enum> = unsafe { TransmuteEnum { in1: &1 }.out2 };
21+
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ type validation failed: encountered a pointer, but expected something that cannot possibly fail to be less or equal to 0
22+
|
23+
= note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rust compiler repository if you believe it should not be considered undefined behavior
24+
25+
error[E0080]: it is undefined behavior to use this value
26+
--> $DIR/ub-enum.rs:46:1
1127
|
1228
LL | const BAD_ENUM2: Enum2 = unsafe { TransmuteEnum2 { in1: 0 }.out1 };
1329
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ type validation failed: encountered 0, but expected a valid enum discriminant
1430
|
1531
= note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rust compiler repository if you believe it should not be considered undefined behavior
1632

1733
error[E0080]: it is undefined behavior to use this value
18-
--> $DIR/ub-enum.rs:36:1
34+
--> $DIR/ub-enum.rs:48:1
1935
|
20-
LL | const BAD_ENUM3: Enum2 = unsafe { TransmuteEnum2 { in2: &0 }.out1 };
21-
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ type validation failed: encountered a pointer, but expected a valid enum discriminant
36+
LL | const BAD_ENUM2_PTR: Enum2 = unsafe { TransmuteEnum2 { in2: &0 }.out1 };
37+
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ type validation failed: encountered a pointer, but expected a valid enum discriminant
2238
|
2339
= note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rust compiler repository if you believe it should not be considered undefined behavior
2440

2541
error[E0080]: it is undefined behavior to use this value
26-
--> $DIR/ub-enum.rs:38:1
42+
--> $DIR/ub-enum.rs:50:1
2743
|
28-
LL | const BAD_ENUM4: Wrap<Enum2> = unsafe { TransmuteEnum2 { in2: &0 }.out2 };
29-
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ type validation failed: encountered a pointer, but expected something that cannot possibly fail to be in the range 2..=2
44+
LL | const BAD_ENUM2_WRAPPED: Wrap<Enum2> = unsafe { TransmuteEnum2 { in2: &0 }.out2 };
45+
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ type validation failed: encountered a pointer, but expected something that cannot possibly fail to be in the range 2..=2
3046
|
3147
= note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rust compiler repository if you believe it should not be considered undefined behavior
3248

3349
error[E0080]: it is undefined behavior to use this value
34-
--> $DIR/ub-enum.rs:42:1
50+
--> $DIR/ub-enum.rs:54:1
3551
|
36-
LL | const BAD_ENUM_UNDEF : Enum2 = unsafe { TransmuteEnum2 { in3: () }.out1 };
37-
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ type validation failed: encountered uninitialized bytes, but expected a valid enum discriminant
52+
LL | const BAD_ENUM2_UNDEF : Enum2 = unsafe { TransmuteEnum2 { in3: () }.out1 };
53+
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ type validation failed: encountered uninitialized bytes, but expected a valid enum discriminant
3854
|
3955
= note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rust compiler repository if you believe it should not be considered undefined behavior
4056

4157
error[E0080]: it is undefined behavior to use this value
42-
--> $DIR/ub-enum.rs:46:1
58+
--> $DIR/ub-enum.rs:58:1
4359
|
44-
LL | const BAD_ENUM_PTR: Option<Enum2> = unsafe { TransmuteEnum2 { in2: &0 }.out3 };
45-
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ type validation failed: encountered a pointer, but expected a valid enum discriminant
60+
LL | const BAD_ENUM2_OPTION_PTR: Option<Enum2> = unsafe { TransmuteEnum2 { in2: &0 }.out3 };
61+
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ type validation failed: encountered a pointer, but expected a valid enum discriminant
4662
|
4763
= note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rust compiler repository if you believe it should not be considered undefined behavior
4864

4965
error[E0080]: it is undefined behavior to use this value
50-
--> $DIR/ub-enum.rs:56:1
66+
--> $DIR/ub-enum.rs:68:1
5167
|
52-
LL | const BAD_ENUM_CHAR: Option<(char, char)> = Some(('x', unsafe { TransmuteChar { a: !0 }.b }));
53-
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ type validation failed: encountered 4294967295 at .<downcast-variant(Some)>.0.1, but expected something less or equal to 1114111
68+
LL | const BAD_OPTION_CHAR: Option<(char, char)> = Some(('x', unsafe { TransmuteChar { a: !0 }.b }));
69+
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ type validation failed: encountered 4294967295 at .<downcast-variant(Some)>.0.1, but expected something less or equal to 1114111
5470
|
5571
= note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rust compiler repository if you believe it should not be considered undefined behavior
5672

57-
error: aborting due to 7 previous errors
73+
error: aborting due to 9 previous errors
5874

5975
For more information about this error, try `rustc --explain E0080`.

src/test/ui/consts/const-eval/ub-nonnull.rs

+10
Original file line numberDiff line numberDiff line change
@@ -5,9 +5,19 @@ use std::mem;
55
use std::ptr::NonNull;
66
use std::num::{NonZeroU8, NonZeroUsize};
77

8+
const NON_NULL: NonNull<u8> = unsafe { mem::transmute(1usize) };
9+
const NON_NULL_PTR: NonNull<u8> = unsafe { mem::transmute(&1) };
10+
811
const NULL_PTR: NonNull<u8> = unsafe { mem::transmute(0usize) };
912
//~^ ERROR it is undefined behavior to use this value
1013

14+
const OUT_OF_BOUNDS_PTR: NonNull<u8> = { unsafe {
15+
//~^ ERROR it is undefined behavior to use this value
16+
let ptr: &(u8, u8, u8) = mem::transmute(&0u8); // &0 gets promoted so it does not dangle
17+
let out_of_bounds_ptr = &ptr.2; // use address-of-field for pointer arithmetic
18+
mem::transmute(out_of_bounds_ptr)
19+
} };
20+
1121
const NULL_U8: NonZeroU8 = unsafe { mem::transmute(0u8) };
1222
//~^ ERROR it is undefined behavior to use this value
1323
const NULL_USIZE: NonZeroUsize = unsafe { mem::transmute(0usize) };
Original file line numberDiff line numberDiff line change
@@ -1,51 +1,64 @@
11
error[E0080]: it is undefined behavior to use this value
2-
--> $DIR/ub-nonnull.rs:8:1
2+
--> $DIR/ub-nonnull.rs:11:1
33
|
44
LL | const NULL_PTR: NonNull<u8> = unsafe { mem::transmute(0usize) };
55
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ type validation failed: encountered 0, but expected something greater or equal to 1
66
|
77
= note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rust compiler repository if you believe it should not be considered undefined behavior
88

99
error[E0080]: it is undefined behavior to use this value
10-
--> $DIR/ub-nonnull.rs:11:1
10+
--> $DIR/ub-nonnull.rs:14:1
11+
|
12+
LL | / const OUT_OF_BOUNDS_PTR: NonNull<u8> = { unsafe {
13+
LL | |
14+
LL | | let ptr: &(u8, u8, u8) = mem::transmute(&0u8); // &0 gets promoted so it does not dangle
15+
LL | | let out_of_bounds_ptr = &ptr.2; // use address-of-field for pointer arithmetic
16+
LL | | mem::transmute(out_of_bounds_ptr)
17+
LL | | } };
18+
| |____^ type validation failed: encountered a potentially NULL pointer, but expected something that cannot possibly fail to be greater or equal to 1
19+
|
20+
= note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rust compiler repository if you believe it should not be considered undefined behavior
21+
22+
error[E0080]: it is undefined behavior to use this value
23+
--> $DIR/ub-nonnull.rs:21:1
1124
|
1225
LL | const NULL_U8: NonZeroU8 = unsafe { mem::transmute(0u8) };
1326
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ type validation failed: encountered 0, but expected something greater or equal to 1
1427
|
1528
= note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rust compiler repository if you believe it should not be considered undefined behavior
1629

1730
error[E0080]: it is undefined behavior to use this value
18-
--> $DIR/ub-nonnull.rs:13:1
31+
--> $DIR/ub-nonnull.rs:23:1
1932
|
2033
LL | const NULL_USIZE: NonZeroUsize = unsafe { mem::transmute(0usize) };
2134
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ type validation failed: encountered 0, but expected something greater or equal to 1
2235
|
2336
= note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rust compiler repository if you believe it should not be considered undefined behavior
2437

2538
error[E0080]: it is undefined behavior to use this value
26-
--> $DIR/ub-nonnull.rs:20:1
39+
--> $DIR/ub-nonnull.rs:30:1
2740
|
2841
LL | const UNINIT: NonZeroU8 = unsafe { Transmute { uninit: () }.out };
2942
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ type validation failed: encountered uninitialized bytes, but expected something greater or equal to 1
3043
|
3144
= note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rust compiler repository if you believe it should not be considered undefined behavior
3245

3346
error[E0080]: it is undefined behavior to use this value
34-
--> $DIR/ub-nonnull.rs:28:1
47+
--> $DIR/ub-nonnull.rs:38:1
3548
|
3649
LL | const BAD_RANGE1: RestrictedRange1 = unsafe { RestrictedRange1(42) };
3750
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ type validation failed: encountered 42, but expected something in the range 10..=30
3851
|
3952
= note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rust compiler repository if you believe it should not be considered undefined behavior
4053

4154
error[E0080]: it is undefined behavior to use this value
42-
--> $DIR/ub-nonnull.rs:34:1
55+
--> $DIR/ub-nonnull.rs:44:1
4356
|
4457
LL | const BAD_RANGE2: RestrictedRange2 = unsafe { RestrictedRange2(20) };
4558
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ type validation failed: encountered 20, but expected something less or equal to 10, or greater or equal to 30
4659
|
4760
= note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rust compiler repository if you believe it should not be considered undefined behavior
4861

49-
error: aborting due to 6 previous errors
62+
error: aborting due to 7 previous errors
5063

5164
For more information about this error, try `rustc --explain E0080`.

0 commit comments

Comments
 (0)