@@ -10,19 +10,22 @@ use std::num::NonZero;
10
10
use either:: { Left , Right } ;
11
11
12
12
use hir:: def:: DefKind ;
13
+ use hir:: def_id:: DefId ;
13
14
use rustc_ast:: Mutability ;
14
15
use rustc_data_structures:: fx:: FxHashSet ;
15
16
use rustc_hir as hir;
16
17
use rustc_middle:: mir:: interpret:: {
17
18
ExpectedKind , InterpError , InvalidMetaKind , Misalignment , PointerKind , Provenance ,
18
19
ValidationErrorInfo , ValidationErrorKind , ValidationErrorKind :: * ,
19
20
} ;
20
- use rustc_middle:: ty ;
21
+ use rustc_middle:: query :: TyCtxtAt ;
21
22
use rustc_middle:: ty:: layout:: { LayoutOf , TyAndLayout } ;
23
+ use rustc_middle:: { mir, ty} ;
22
24
use rustc_span:: symbol:: { sym, Symbol } ;
23
25
use rustc_target:: abi:: {
24
26
Abi , FieldIdx , Scalar as ScalarAbi , Size , VariantIdx , Variants , WrappingRange ,
25
27
} ;
28
+ use rustc_target:: spec:: abi:: Abi as CallAbi ;
26
29
27
30
use std:: hash:: Hash ;
28
31
@@ -37,6 +40,7 @@ use super::InterpError::UndefinedBehavior as Ub;
37
40
use super :: InterpError :: Unsupported as Unsup ;
38
41
use super :: UndefinedBehaviorInfo :: * ;
39
42
use super :: UnsupportedOpInfo :: * ;
43
+ use super :: { FnArg , Frame } ;
40
44
41
45
macro_rules! throw_validation_failure {
42
46
( $where: expr, $kind: expr) => { {
@@ -967,7 +971,7 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
967
971
let mut visitor = ValidityVisitor { path, ref_tracking, ctfe_mode, ecx : self } ;
968
972
969
973
// Run it.
970
- match self . run_for_validation ( || visitor. visit_value ( op) ) {
974
+ match visitor. visit_value ( op) {
971
975
Ok ( ( ) ) => Ok ( ( ) ) ,
972
976
// Pass through validation failures and "invalid program" issues.
973
977
Err ( err)
@@ -1022,3 +1026,154 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
1022
1026
self . validate_operand_internal ( op, vec ! [ ] , None , None )
1023
1027
}
1024
1028
}
1029
+
1030
+ pub struct ValidationMachine < ' a , ' mir , ' tcx > (
1031
+ pub & ' a InterpCx < ' mir , ' tcx , crate :: const_eval:: CompileTimeInterpreter < ' mir , ' tcx > > ,
1032
+ ) ;
1033
+
1034
+ impl < ' a , ' mir , ' tcx > std:: ops:: Deref for ValidationMachine < ' a , ' mir , ' tcx > {
1035
+ type Target = crate :: const_eval:: CompileTimeInterpreter < ' mir , ' tcx > ;
1036
+
1037
+ fn deref ( & self ) -> & Self :: Target {
1038
+ & self . 0 . machine
1039
+ }
1040
+ }
1041
+
1042
+ impl < ' a , ' mir , ' tcx > Machine < ' mir , ' tcx > for ValidationMachine < ' a , ' mir , ' tcx > {
1043
+ super :: compile_time_machine!( <' mir, ' tcx>) ;
1044
+
1045
+ type MemoryKind = crate :: const_eval:: MemoryKind ;
1046
+
1047
+ const PANIC_ON_ALLOC_FAIL : bool = false ; // will be raised as a proper error
1048
+
1049
+ #[ inline( always) ]
1050
+ fn enforce_alignment ( ecx : & InterpCx < ' mir , ' tcx , Self > ) -> bool {
1051
+ Machine :: enforce_alignment ( ecx. machine . 0 )
1052
+ }
1053
+
1054
+ #[ inline( always) ]
1055
+ fn enforce_validity ( ecx : & InterpCx < ' mir , ' tcx , Self > , layout : TyAndLayout < ' tcx > ) -> bool {
1056
+ ecx. tcx . sess . opts . unstable_opts . extra_const_ub_checks || layout. abi . is_uninhabited ( )
1057
+ }
1058
+
1059
+ fn load_mir (
1060
+ _ecx : & InterpCx < ' mir , ' tcx , Self > ,
1061
+ instance : ty:: InstanceDef < ' tcx > ,
1062
+ ) -> InterpResult < ' tcx , & ' tcx mir:: Body < ' tcx > > {
1063
+ unreachable ! ( "validation tried to load mir of {instance:?}" )
1064
+ }
1065
+
1066
+ fn find_mir_or_eval_fn (
1067
+ _ecx : & mut InterpCx < ' mir , ' tcx , Self > ,
1068
+ orig_instance : ty:: Instance < ' tcx > ,
1069
+ _abi : CallAbi ,
1070
+ _args : & [ FnArg < ' tcx > ] ,
1071
+ _dest : & MPlaceTy < ' tcx > ,
1072
+ _ret : Option < mir:: BasicBlock > ,
1073
+ _unwind : mir:: UnwindAction , // unwinding is not supported in consts
1074
+ ) -> InterpResult < ' tcx , Option < ( & ' mir mir:: Body < ' tcx > , ty:: Instance < ' tcx > ) > > {
1075
+ unreachable ! ( "validation tried to evaluate mir of {orig_instance:?}" )
1076
+ }
1077
+
1078
+ fn panic_nounwind ( _ecx : & mut InterpCx < ' mir , ' tcx , Self > , msg : & str ) -> InterpResult < ' tcx > {
1079
+ unreachable ! ( "validation tried to panic: {msg}" )
1080
+ }
1081
+
1082
+ fn call_intrinsic (
1083
+ _ecx : & mut InterpCx < ' mir , ' tcx , Self > ,
1084
+ instance : ty:: Instance < ' tcx > ,
1085
+ _args : & [ OpTy < ' tcx > ] ,
1086
+ _dest : & MPlaceTy < ' tcx , Self :: Provenance > ,
1087
+ _target : Option < mir:: BasicBlock > ,
1088
+ _unwind : mir:: UnwindAction ,
1089
+ ) -> InterpResult < ' tcx > {
1090
+ unreachable ! ( "validation tried to evaluate intrinsic {instance:?}" )
1091
+ }
1092
+
1093
+ fn assert_panic (
1094
+ _ecx : & mut InterpCx < ' mir , ' tcx , Self > ,
1095
+ msg : & mir:: AssertMessage < ' tcx > ,
1096
+ _unwind : mir:: UnwindAction ,
1097
+ ) -> InterpResult < ' tcx > {
1098
+ unreachable ! ( "validation tried to panic: {msg:?}" )
1099
+ }
1100
+
1101
+ fn binary_ptr_op (
1102
+ _ecx : & InterpCx < ' mir , ' tcx , Self > ,
1103
+ _bin_op : mir:: BinOp ,
1104
+ _left : & ImmTy < ' tcx > ,
1105
+ _right : & ImmTy < ' tcx > ,
1106
+ ) -> InterpResult < ' tcx , ( ImmTy < ' tcx > , bool ) > {
1107
+ unreachable ! ( "validation does not do binary pointer ops" ) ;
1108
+ }
1109
+
1110
+ fn increment_const_eval_counter ( _ecx : & mut InterpCx < ' mir , ' tcx , Self > ) -> InterpResult < ' tcx > {
1111
+ unreachable ! ( "validation does not interpret statements" )
1112
+ }
1113
+
1114
+ #[ inline( always) ]
1115
+ fn expose_ptr ( _ecx : & mut InterpCx < ' mir , ' tcx , Self > , _ptr : Pointer ) -> InterpResult < ' tcx > {
1116
+ unreachable ! ( "validation does not exposing pointers" )
1117
+ }
1118
+
1119
+ #[ inline( always) ]
1120
+ fn init_frame_extra (
1121
+ _ecx : & mut InterpCx < ' mir , ' tcx , Self > ,
1122
+ _frame : Frame < ' mir , ' tcx > ,
1123
+ ) -> InterpResult < ' tcx , Frame < ' mir , ' tcx > > {
1124
+ unreachable ! ( "validation does not create stack frames" )
1125
+ }
1126
+
1127
+ #[ inline( always) ]
1128
+ fn stack < ' b > (
1129
+ ecx : & ' b InterpCx < ' mir , ' tcx , Self > ,
1130
+ ) -> & ' b [ Frame < ' mir , ' tcx , Self :: Provenance , Self :: FrameExtra > ] {
1131
+ ecx. machine . 0 . stack ( )
1132
+ }
1133
+
1134
+ #[ inline( always) ]
1135
+ fn stack_mut < ' b > (
1136
+ _ecx : & ' b mut InterpCx < ' mir , ' tcx , Self > ,
1137
+ ) -> & ' b mut Vec < Frame < ' mir , ' tcx , Self :: Provenance , Self :: FrameExtra > > {
1138
+ unreachable ! ( "validation cannot mutate stack" )
1139
+ }
1140
+
1141
+ fn before_access_global (
1142
+ _tcx : TyCtxtAt < ' tcx > ,
1143
+ _machine : & Self ,
1144
+ _alloc_id : AllocId ,
1145
+ _alloc : mir:: interpret:: ConstAllocation < ' tcx > ,
1146
+ _static_def_id : Option < DefId > ,
1147
+ is_write : bool ,
1148
+ ) -> InterpResult < ' tcx > {
1149
+ assert ! ( !is_write) ;
1150
+ // Do nothing, validation may read globals.
1151
+ Ok ( ( ) )
1152
+ }
1153
+
1154
+ fn retag_ptr_value (
1155
+ _ecx : & mut InterpCx < ' mir , ' tcx , Self > ,
1156
+ kind : mir:: RetagKind ,
1157
+ val : & ImmTy < ' tcx , mir:: interpret:: CtfeProvenance > ,
1158
+ ) -> InterpResult < ' tcx , ImmTy < ' tcx , mir:: interpret:: CtfeProvenance > > {
1159
+ unreachable ! ( "validation does not retag pointers: {val:?}, {kind:?}" )
1160
+ }
1161
+
1162
+ fn before_memory_write (
1163
+ _tcx : TyCtxtAt < ' tcx > ,
1164
+ _machine : & mut Self ,
1165
+ _alloc_extra : & mut Self :: AllocExtra ,
1166
+ ( _alloc_id, _immutable) : ( AllocId , bool ) ,
1167
+ _range : mir:: interpret:: AllocRange ,
1168
+ ) -> InterpResult < ' tcx > {
1169
+ unreachable ! ( "validation does not write to memory" )
1170
+ }
1171
+
1172
+ fn before_alloc_read (
1173
+ _ecx : & InterpCx < ' mir , ' tcx , Self > ,
1174
+ _alloc_id : AllocId ,
1175
+ ) -> InterpResult < ' tcx > {
1176
+ // Do nothing, validation may read all memory
1177
+ Ok ( ( ) )
1178
+ }
1179
+ }
0 commit comments