Skip to content

Commit 38b7f81

Browse files
committed
Make some diagnostics behave consistently
1 parent 672b35c commit 38b7f81

File tree

4 files changed

+50
-38
lines changed

4 files changed

+50
-38
lines changed

compiler/rustc_const_eval/src/interpret/validity.rs

+40-28
Original file line numberDiff line numberDiff line change
@@ -608,14 +608,8 @@ impl<'rt, 'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> ValidityVisitor<'rt, 'mir, '
608608
if place.layout.is_unsized() {
609609
self.check_wide_ptr_meta(place.meta(), place.layout)?;
610610
}
611-
if self.ref_tracking.is_some()
612-
&& let Some(alloc_id) = place.ptr().provenance.and_then(|p| p.get_alloc_id())
613-
&& let AllocKind::Dead = self.ecx.get_alloc_info(alloc_id).2
614-
{
615-
throw_validation_failure!(
616-
self.path,
617-
DanglingPtrUseAfterFree { ptr_kind: PointerKind::Ref(Mutability::Not) }
618-
)
611+
if let Some(ref_tracking) = &mut self.ref_tracking {
612+
self.ecx.track_relocation(place.ptr(), ref_tracking, &self.path, None)
619613
}
620614
Ok(true)
621615
}
@@ -993,6 +987,17 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
993987
// Construct a visitor
994988
let mut visitor = ValidityVisitor { path, ref_tracking, ctfe_mode, ecx: self };
995989

990+
if visitor.ref_tracking.is_some()
991+
&& let Left(place) = op.as_mplace_or_imm()
992+
&& let Some(alloc_id) = place.ptr().provenance.and_then(|p| p.get_alloc_id())
993+
&& let AllocKind::Dead = self.get_alloc_info(alloc_id).2
994+
{
995+
throw_validation_failure!(
996+
visitor.path,
997+
DanglingPtrUseAfterFree { ptr_kind: PointerKind::Ref(Mutability::Not) }
998+
)
999+
}
1000+
9961001
// Run it.
9971002
match self.run_for_validation(|| visitor.visit_value(op)) {
9981003
Ok(()) => Ok(visitor.path),
@@ -1050,33 +1055,40 @@ impl<'mir, 'tcx> InterpCx<'mir, 'tcx, crate::const_eval::CompileTimeInterpreter<
10501055
&& let Some((_, alloc)) = self.memory.alloc_map().get(&prov.alloc_id())
10511056
{
10521057
for &(offset, prov) in alloc.provenance().ptrs().iter() {
1053-
if let AllocKind::Dead = self.get_alloc_info(prov.alloc_id()).2 {
1054-
throw_validation_failure!(
1055-
path,
1056-
DanglingPtrUseAfterFree { ptr_kind: PointerKind::Ref(Mutability::Not) }
1057-
)
1058-
} else {
1059-
let ptr = Pointer::new(Some(prov), Size::ZERO);
1060-
let ty = self.tcx.types.unit;
1061-
let layout = self.layout_of(ty).unwrap();
1062-
let op = self.ptr_to_mplace(ptr, layout);
1063-
ref_tracking.track(op, || {
1064-
// We need to clone the path anyway, make sure it gets created
1065-
// with enough space for the additional `Deref`.
1066-
let mut new_path = Vec::with_capacity(path.len() + 1);
1067-
new_path.extend(path.iter().copied());
1068-
new_path.push(PathElem::Offset(offset));
1069-
new_path.push(PathElem::Deref);
1070-
new_path
1071-
})
1072-
}
1058+
let ptr = Pointer::new(Some(prov), Size::ZERO);
1059+
self.track_relocation(ptr, ref_tracking, &path, Some(offset));
10731060
}
10741061
}
10751062
Ok(())
10761063
}
10771064
}
10781065

10791066
impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
1067+
fn track_relocation(
1068+
&self,
1069+
ptr: Pointer<Option<M::Provenance>>,
1070+
ref_tracking: &mut RefTracking<MPlaceTy<'tcx, M::Provenance>, Vec<PathElem>>,
1071+
path: &Vec<PathElem>,
1072+
offset: Option<Size>,
1073+
) {
1074+
let ty = self.tcx.types.unit;
1075+
let layout = self.layout_of(ty).unwrap();
1076+
let op = self.ptr_to_mplace(ptr, layout);
1077+
ref_tracking.track(op, || {
1078+
// We need to clone the path anyway, make sure it gets created
1079+
// with enough space for the additional `Deref`.
1080+
let mut new_path = Vec::with_capacity(path.len() + 1);
1081+
new_path.extend(path.iter().copied());
1082+
if let Some(offset) = offset
1083+
&& offset != Size::ZERO
1084+
{
1085+
new_path.push(PathElem::Offset(offset));
1086+
}
1087+
new_path.push(PathElem::Deref);
1088+
new_path
1089+
})
1090+
}
1091+
10801092
/// This function checks the data at `op` to be runtime-valid.
10811093
/// `op` is assumed to cover valid memory if it is an indirect operand.
10821094
/// It will error if the bits at the destination do not match the ones described by the layout.

tests/ui/consts/const-mut-refs/mut_ref_in_final_dynamic_check.stderr

+2-2
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,7 @@ error[E0080]: it is undefined behavior to use this value
3535
--> $DIR/mut_ref_in_final_dynamic_check.rs:36:1
3636
|
3737
LL | const DANGLING: Option<&mut i32> = helper_dangling();
38-
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ constructing invalid value at .<enum-tag>: encountered a dangling reference (use-after-free)
38+
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ constructing invalid value at .<enum-variant(Some)>.0: encountered a dangling reference (use-after-free)
3939
|
4040
= note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rustc repository if you believe it should not be considered undefined behavior.
4141
= note: the raw bytes of the constant (size: $SIZE, align: $ALIGN) {
@@ -46,7 +46,7 @@ error[E0080]: it is undefined behavior to use this value
4646
--> $DIR/mut_ref_in_final_dynamic_check.rs:37:1
4747
|
4848
LL | static DANGLING_STATIC: Option<&mut i32> = helper_dangling();
49-
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ constructing invalid value at .<enum-tag>: encountered a dangling reference (use-after-free)
49+
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ constructing invalid value at .<enum-variant(Some)>.0: encountered a dangling reference (use-after-free)
5050
|
5151
= note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rustc repository if you believe it should not be considered undefined behavior.
5252
= note: the raw bytes of the constant (size: $SIZE, align: $ALIGN) {

tests/ui/consts/dangling_raw_ptr.stderr

+4-4
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ error[E0080]: it is undefined behavior to use this value
22
--> $DIR/dangling_raw_ptr.rs:6:1
33
|
44
LL | const FOO: *const u32 = {
5-
| ^^^^^^^^^^^^^^^^^^^^^ constructing invalid value: encountered a dangling reference (use-after-free)
5+
| ^^^^^^^^^^^^^^^^^^^^^ constructing invalid value at .<deref>: encountered a dangling reference (use-after-free)
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 rustc repository if you believe it should not be considered undefined behavior.
88
= note: the raw bytes of the constant (size: $SIZE, align: $ALIGN) {
@@ -13,7 +13,7 @@ error[E0080]: it is undefined behavior to use this value
1313
--> $DIR/dangling_raw_ptr.rs:15:1
1414
|
1515
LL | const BAR: Union = {
16-
| ^^^^^^^^^^^^^^^^ constructing invalid value: encountered a dangling reference (use-after-free)
16+
| ^^^^^^^^^^^^^^^^ constructing invalid value at .<offset(0)>.<deref>: encountered a dangling reference (use-after-free)
1717
|
1818
= note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rustc repository if you believe it should not be considered undefined behavior.
1919
= note: the raw bytes of the constant (size: $SIZE, align: $ALIGN) {
@@ -24,7 +24,7 @@ error[E0080]: it is undefined behavior to use this value
2424
--> $DIR/dangling_raw_ptr.rs:20:1
2525
|
2626
LL | const BAZ: Union = {
27-
| ^^^^^^^^^^^^^^^^ constructing invalid value at .<offset(0)>.<deref>: encountered a dangling reference (use-after-free)
27+
| ^^^^^^^^^^^^^^^^ constructing invalid value at .<offset(0)>.<deref>.<offset(0)>.<deref>: encountered a dangling reference (use-after-free)
2828
|
2929
= note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rustc repository if you believe it should not be considered undefined behavior.
3030
= note: the raw bytes of the constant (size: $SIZE, align: $ALIGN) {
@@ -35,7 +35,7 @@ error[E0080]: it is undefined behavior to use this value
3535
--> $DIR/dangling_raw_ptr.rs:25:1
3636
|
3737
LL | const FOOMP: *const u32 = {
38-
| ^^^^^^^^^^^^^^^^^^^^^^^ constructing invalid value at .<offset(0)>.<deref>: encountered a dangling reference (use-after-free)
38+
| ^^^^^^^^^^^^^^^^^^^^^^^ constructing invalid value at .<deref>.<offset(0)>.<deref>: encountered a dangling reference (use-after-free)
3939
|
4040
= note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rustc repository if you believe it should not be considered undefined behavior.
4141
= note: the raw bytes of the constant (size: $SIZE, align: $ALIGN) {

tests/ui/consts/std/cell.stderr

+4-4
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ error[E0080]: it is undefined behavior to use this value
22
--> $DIR/cell.rs:11:1
33
|
44
LL | static FOO: Wrap<*mut u32> = Wrap(Cell::new(42).as_ptr());
5-
| ^^^^^^^^^^^^^^^^^^^^^^^^^^ constructing invalid value at .0: encountered a dangling reference (use-after-free)
5+
| ^^^^^^^^^^^^^^^^^^^^^^^^^^ constructing invalid value at .0.<deref>: encountered a dangling reference (use-after-free)
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 rustc repository if you believe it should not be considered undefined behavior.
88
= note: the raw bytes of the constant (size: $SIZE, align: $ALIGN) {
@@ -13,7 +13,7 @@ error[E0080]: it is undefined behavior to use this value
1313
--> $DIR/cell.rs:13:1
1414
|
1515
LL | const FOO_CONST: Wrap<*mut u32> = Wrap(Cell::new(42).as_ptr());
16-
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ constructing invalid value at .0: encountered a dangling reference (use-after-free)
16+
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ constructing invalid value at .0.<deref>: encountered a dangling reference (use-after-free)
1717
|
1818
= note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rustc repository if you believe it should not be considered undefined behavior.
1919
= note: the raw bytes of the constant (size: $SIZE, align: $ALIGN) {
@@ -24,7 +24,7 @@ error[E0080]: it is undefined behavior to use this value
2424
--> $DIR/cell.rs:27:1
2525
|
2626
LL | const FOO4_CONST: Wrap<*mut u32> = Wrap(FOO3_CONST.0.as_ptr());
27-
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ constructing invalid value at .0: encountered a dangling reference (use-after-free)
27+
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ constructing invalid value at .0.<deref>: encountered a dangling reference (use-after-free)
2828
|
2929
= note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rustc repository if you believe it should not be considered undefined behavior.
3030
= note: the raw bytes of the constant (size: $SIZE, align: $ALIGN) {
@@ -35,7 +35,7 @@ error[E0080]: it is undefined behavior to use this value
3535
--> $DIR/cell.rs:32:1
3636
|
3737
LL | const FOO2: *mut u32 = Cell::new(42).as_ptr();
38-
| ^^^^^^^^^^^^^^^^^^^^ constructing invalid value: encountered a dangling reference (use-after-free)
38+
| ^^^^^^^^^^^^^^^^^^^^ constructing invalid value at .<deref>: encountered a dangling reference (use-after-free)
3939
|
4040
= note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rustc repository if you believe it should not be considered undefined behavior.
4141
= note: the raw bytes of the constant (size: $SIZE, align: $ALIGN) {

0 commit comments

Comments
 (0)