1
1
use std:: borrow:: { Borrow , Cow } ;
2
2
use std:: fmt;
3
3
use std:: hash:: Hash ;
4
- use std:: ops:: ControlFlow ;
5
4
6
5
use rustc_abi:: { Align , ExternAbi , Size } ;
7
6
use rustc_ast:: Mutability ;
@@ -10,7 +9,7 @@ use rustc_hir::def_id::{DefId, LocalDefId};
10
9
use rustc_hir:: { self as hir, CRATE_HIR_ID , LangItem } ;
11
10
use rustc_middle:: mir:: AssertMessage ;
12
11
use rustc_middle:: query:: TyCtxtAt ;
13
- use rustc_middle:: ty:: layout:: { FnAbiOf , TyAndLayout } ;
12
+ use rustc_middle:: ty:: layout:: TyAndLayout ;
14
13
use rustc_middle:: ty:: { self , Ty , TyCtxt } ;
15
14
use rustc_middle:: { bug, mir} ;
16
15
use rustc_span:: Span ;
@@ -22,9 +21,9 @@ use crate::errors::{LongRunning, LongRunningWarn};
22
21
use crate :: fluent_generated as fluent;
23
22
use crate :: interpret:: {
24
23
self , AllocId , AllocRange , ConstAllocation , CtfeProvenance , FnArg , Frame , GlobalAlloc , ImmTy ,
25
- InterpCx , InterpResult , MPlaceTy , OpTy , Pointer , PointerArithmetic , RangeSet , Scalar ,
26
- StackPopCleanup , compile_time_machine , interp_ok, throw_exhaust, throw_inval, throw_ub,
27
- throw_ub_custom , throw_unsup , throw_unsup_format,
24
+ InterpCx , InterpResult , MPlaceTy , OpTy , Pointer , RangeSet , Scalar , compile_time_machine ,
25
+ interp_ok, throw_exhaust, throw_inval, throw_ub, throw_ub_custom , throw_unsup ,
26
+ throw_unsup_format,
28
27
} ;
29
28
30
29
/// When hitting this many interpreted terminators we emit a deny by default lint
@@ -226,8 +225,8 @@ impl<'tcx> CompileTimeInterpCx<'tcx> {
226
225
& mut self ,
227
226
instance : ty:: Instance < ' tcx > ,
228
227
args : & [ FnArg < ' tcx > ] ,
229
- dest : & MPlaceTy < ' tcx > ,
230
- ret : Option < mir:: BasicBlock > ,
228
+ _dest : & MPlaceTy < ' tcx > ,
229
+ _ret : Option < mir:: BasicBlock > ,
231
230
) -> InterpResult < ' tcx , Option < ty:: Instance < ' tcx > > > {
232
231
let def_id = instance. def_id ( ) ;
233
232
@@ -259,85 +258,10 @@ impl<'tcx> CompileTimeInterpCx<'tcx> {
259
258
) ;
260
259
261
260
return interp_ok ( Some ( new_instance) ) ;
262
- } else if self . tcx . is_lang_item ( def_id, LangItem :: AlignOffset ) {
263
- let args = self . copy_fn_args ( args) ;
264
- // For align_offset, we replace the function call if the pointer has no address.
265
- match self . align_offset ( instance, & args, dest, ret) ? {
266
- ControlFlow :: Continue ( ( ) ) => return interp_ok ( Some ( instance) ) ,
267
- ControlFlow :: Break ( ( ) ) => return interp_ok ( None ) ,
268
- }
269
261
}
270
262
interp_ok ( Some ( instance) )
271
263
}
272
264
273
- /// `align_offset(ptr, target_align)` needs special handling in const eval, because the pointer
274
- /// may not have an address.
275
- ///
276
- /// If `ptr` does have a known address, then we return `Continue(())` and the function call should
277
- /// proceed as normal.
278
- ///
279
- /// If `ptr` doesn't have an address, but its underlying allocation's alignment is at most
280
- /// `target_align`, then we call the function again with an dummy address relative to the
281
- /// allocation.
282
- ///
283
- /// If `ptr` doesn't have an address and `target_align` is stricter than the underlying
284
- /// allocation's alignment, then we return `usize::MAX` immediately.
285
- fn align_offset (
286
- & mut self ,
287
- instance : ty:: Instance < ' tcx > ,
288
- args : & [ OpTy < ' tcx > ] ,
289
- dest : & MPlaceTy < ' tcx > ,
290
- ret : Option < mir:: BasicBlock > ,
291
- ) -> InterpResult < ' tcx , ControlFlow < ( ) > > {
292
- assert_eq ! ( args. len( ) , 2 ) ;
293
-
294
- let ptr = self . read_pointer ( & args[ 0 ] ) ?;
295
- let target_align = self . read_scalar ( & args[ 1 ] ) ?. to_target_usize ( self ) ?;
296
-
297
- if !target_align. is_power_of_two ( ) {
298
- throw_ub_custom ! (
299
- fluent:: const_eval_align_offset_invalid_align,
300
- target_align = target_align,
301
- ) ;
302
- }
303
-
304
- match self . ptr_try_get_alloc_id ( ptr, 0 ) {
305
- Ok ( ( alloc_id, offset, _extra) ) => {
306
- let ( _size, alloc_align, _kind) = self . get_alloc_info ( alloc_id) ;
307
-
308
- if target_align <= alloc_align. bytes ( ) {
309
- // Extract the address relative to the allocation base that is definitely
310
- // sufficiently aligned and call `align_offset` again.
311
- let addr = ImmTy :: from_uint ( offset. bytes ( ) , args[ 0 ] . layout ) . into ( ) ;
312
- let align = ImmTy :: from_uint ( target_align, args[ 1 ] . layout ) . into ( ) ;
313
- let fn_abi = self . fn_abi_of_instance ( instance, ty:: List :: empty ( ) ) ?;
314
-
315
- // Push the stack frame with our own adjusted arguments.
316
- self . init_stack_frame (
317
- instance,
318
- self . load_mir ( instance. def , None ) ?,
319
- fn_abi,
320
- & [ FnArg :: Copy ( addr) , FnArg :: Copy ( align) ] ,
321
- /* with_caller_location = */ false ,
322
- dest,
323
- StackPopCleanup :: Goto { ret, unwind : mir:: UnwindAction :: Unreachable } ,
324
- ) ?;
325
- interp_ok ( ControlFlow :: Break ( ( ) ) )
326
- } else {
327
- // Not alignable in const, return `usize::MAX`.
328
- let usize_max = Scalar :: from_target_usize ( self . target_usize_max ( ) , self ) ;
329
- self . write_scalar ( usize_max, dest) ?;
330
- self . return_to_block ( ret) ?;
331
- interp_ok ( ControlFlow :: Break ( ( ) ) )
332
- }
333
- }
334
- Err ( _addr) => {
335
- // The pointer has an address, continue with function call.
336
- interp_ok ( ControlFlow :: Continue ( ( ) ) )
337
- }
338
- }
339
- }
340
-
341
265
/// See documentation on the `ptr_guaranteed_cmp` intrinsic.
342
266
fn guaranteed_cmp ( & mut self , a : Scalar , b : Scalar ) -> InterpResult < ' tcx , u8 > {
343
267
interp_ok ( match ( a, b) {
0 commit comments