|
1 |
| -use rustc_hir::def::DefKind; |
2 |
| -use rustc_hir::LangItem; |
3 |
| -use rustc_middle::mir; |
4 |
| -use rustc_middle::mir::interpret::PointerArithmetic; |
5 |
| -use rustc_middle::ty::layout::{FnAbiOf, TyAndLayout}; |
6 |
| -use rustc_middle::ty::{self, TyCtxt}; |
7 |
| -use rustc_span::Span; |
8 | 1 | use std::borrow::Borrow;
|
| 2 | +use std::fmt; |
9 | 3 | use std::hash::Hash;
|
10 | 4 | use std::ops::ControlFlow;
|
11 | 5 |
|
| 6 | +use rustc_ast::Mutability; |
12 | 7 | use rustc_data_structures::fx::FxIndexMap;
|
13 | 8 | use rustc_data_structures::fx::IndexEntry;
|
14 |
| -use std::fmt; |
15 |
| - |
16 |
| -use rustc_ast::Mutability; |
| 9 | +use rustc_hir::def::DefKind; |
17 | 10 | use rustc_hir::def_id::DefId;
|
| 11 | +use rustc_hir::LangItem; |
| 12 | +use rustc_middle::mir; |
18 | 13 | use rustc_middle::mir::AssertMessage;
|
| 14 | +use rustc_middle::query::TyCtxtAt; |
| 15 | +use rustc_middle::ty; |
| 16 | +use rustc_middle::ty::layout::{FnAbiOf, TyAndLayout}; |
| 17 | +use rustc_session::lint::builtin::WRITES_THROUGH_IMMUTABLE_POINTER; |
19 | 18 | use rustc_span::symbol::{sym, Symbol};
|
| 19 | +use rustc_span::Span; |
20 | 20 | use rustc_target::abi::{Align, Size};
|
21 | 21 | use rustc_target::spec::abi::Abi as CallAbi;
|
22 | 22 |
|
23 | 23 | use crate::errors::{LongRunning, LongRunningWarn};
|
24 | 24 | use crate::fluent_generated as fluent;
|
25 | 25 | use crate::interpret::{
|
26 |
| - self, compile_time_machine, AllocId, ConstAllocation, FnArg, FnVal, Frame, ImmTy, InterpCx, |
27 |
| - InterpResult, OpTy, PlaceTy, Pointer, Scalar, |
| 26 | + self, compile_time_machine, AllocId, AllocRange, ConstAllocation, CtfeProvenance, FnArg, FnVal, |
| 27 | + Frame, ImmTy, InterpCx, InterpResult, OpTy, PlaceTy, Pointer, PointerArithmetic, Scalar, |
28 | 28 | };
|
29 | 29 |
|
30 | 30 | use super::error::*;
|
@@ -671,7 +671,7 @@ impl<'mir, 'tcx> interpret::Machine<'mir, 'tcx> for CompileTimeInterpreter<'mir,
|
671 | 671 | }
|
672 | 672 |
|
673 | 673 | fn before_access_global(
|
674 |
| - _tcx: TyCtxt<'tcx>, |
| 674 | + _tcx: TyCtxtAt<'tcx>, |
675 | 675 | machine: &Self,
|
676 | 676 | alloc_id: AllocId,
|
677 | 677 | alloc: ConstAllocation<'tcx>,
|
@@ -708,6 +708,45 @@ impl<'mir, 'tcx> interpret::Machine<'mir, 'tcx> for CompileTimeInterpreter<'mir,
|
708 | 708 | }
|
709 | 709 | }
|
710 | 710 | }
|
| 711 | + |
| 712 | + fn retag_ptr_value( |
| 713 | + ecx: &mut InterpCx<'mir, 'tcx, Self>, |
| 714 | + _kind: mir::RetagKind, |
| 715 | + val: &ImmTy<'tcx, CtfeProvenance>, |
| 716 | + ) -> InterpResult<'tcx, ImmTy<'tcx, CtfeProvenance>> { |
| 717 | + if let ty::Ref(_, ty, mutbl) = val.layout.ty.kind() |
| 718 | + && *mutbl == Mutability::Not |
| 719 | + && ty.is_freeze(*ecx.tcx, ecx.param_env) |
| 720 | + { |
| 721 | + // This is a frozen shared reference, mark it immutable. |
| 722 | + let place = ecx.ref_to_mplace(val)?; |
| 723 | + let new_place = place.map_provenance(|p| p.map(CtfeProvenance::as_immutable)); |
| 724 | + Ok(ImmTy::from_immediate(new_place.to_ref(ecx), val.layout)) |
| 725 | + } else { |
| 726 | + Ok(val.clone()) |
| 727 | + } |
| 728 | + } |
| 729 | + |
| 730 | + fn before_memory_write( |
| 731 | + tcx: TyCtxtAt<'tcx>, |
| 732 | + machine: &mut Self, |
| 733 | + _alloc_extra: &mut Self::AllocExtra, |
| 734 | + (_alloc_id, immutable): (AllocId, bool), |
| 735 | + range: AllocRange, |
| 736 | + ) -> InterpResult<'tcx> { |
| 737 | + if range.size == Size::ZERO { |
| 738 | + // Nothing to check. |
| 739 | + return Ok(()); |
| 740 | + } |
| 741 | + // Reject writes through immutable pointers. |
| 742 | + if immutable { |
| 743 | + super::lint(tcx, machine, WRITES_THROUGH_IMMUTABLE_POINTER, |frames| { |
| 744 | + crate::errors::WriteThroughImmutablePointer { frames } |
| 745 | + }); |
| 746 | + } |
| 747 | + // Everything else is fine. |
| 748 | + Ok(()) |
| 749 | + } |
711 | 750 | }
|
712 | 751 |
|
713 | 752 | // Please do not add any code below the above `Machine` trait impl. I (oli-obk) plan more cleanups
|
|
0 commit comments