From b46f946c81477e22c14d92ab93609ade18dc86d6 Mon Sep 17 00:00:00 2001 From: Ralf Jung Date: Sat, 27 Jun 2020 11:57:43 +0200 Subject: [PATCH] supply our own implementation of the CTFE pointer comparison intrinsics --- src/shims/intrinsics.rs | 37 ++++++++++++++++++++++++++---------- tests/run-pass/intrinsics.rs | 7 ++++++- 2 files changed, 33 insertions(+), 11 deletions(-) diff --git a/src/shims/intrinsics.rs b/src/shims/intrinsics.rs index c16fbc278c8..015d9edc11b 100644 --- a/src/shims/intrinsics.rs +++ b/src/shims/intrinsics.rs @@ -6,6 +6,7 @@ use rustc_middle::ty::layout::IntegerExt; use rustc_apfloat::{Float, Round}; use rustc_target::abi::{Align, Integer, LayoutOf}; +use rustc_span::symbol::sym; use crate::*; use helpers::check_arg_count; @@ -20,17 +21,19 @@ fn call_intrinsic( unwind: Option, ) -> InterpResult<'tcx> { let this = self.eval_context_mut(); - if this.emulate_intrinsic(instance, args, ret)? { + let intrinsic_name = this.tcx.item_name(instance.def_id()); + // We want to overwrite some of the intrinsic implementations that CTFE uses. + let prefer_miri_intrinsic = match intrinsic_name { + sym::ptr_guaranteed_eq | sym::ptr_guaranteed_ne => true, + _ => false, + }; + + if !prefer_miri_intrinsic && this.emulate_intrinsic(instance, args, ret)? { return Ok(()); } - let substs = instance.substs; - - // All these intrinsics take raw pointers, so if we access memory directly - // (as opposed to through a place), we have to remember to erase any tag - // that might still hang around! - let intrinsic_name = &*this.tcx.item_name(instance.def_id()).as_str(); // First handle intrinsics without return place. + let intrinsic_name = &*intrinsic_name.as_str(); let (dest, ret) = match ret { None => match intrinsic_name { "miri_start_panic" => return this.handle_miri_start_panic(args, unwind), @@ -42,13 +45,27 @@ fn call_intrinsic( // Then handle terminating intrinsics. match intrinsic_name { + // Miri overwriting CTFE intrinsics. + "ptr_guaranteed_eq" => { + let &[left, right] = check_arg_count(args)?; + let left = this.read_immediate(left)?; + let right = this.read_immediate(right)?; + this.binop_ignore_overflow(mir::BinOp::Eq, left, right, dest)?; + } + "ptr_guaranteed_ne" => { + let &[left, right] = check_arg_count(args)?; + let left = this.read_immediate(left)?; + let right = this.read_immediate(right)?; + this.binop_ignore_overflow(mir::BinOp::Ne, left, right, dest)?; + } + // Raw memory accesses #[rustfmt::skip] | "copy" | "copy_nonoverlapping" => { let &[src, dest, count] = check_arg_count(args)?; - let elem_ty = substs.type_at(0); + let elem_ty = instance.substs.type_at(0); let elem_layout = this.layout_of(elem_ty)?; let count = this.read_scalar(count)?.to_machine_usize(this)?; let elem_align = elem_layout.align.abi; @@ -89,7 +106,7 @@ fn call_intrinsic( "write_bytes" => { let &[ptr, val_byte, count] = check_arg_count(args)?; - let ty = substs.type_at(0); + let ty = instance.substs.type_at(0); let ty_layout = this.layout_of(ty)?; let val_byte = this.read_scalar(val_byte)?.to_u8()?; let ptr = this.read_scalar(ptr)?.not_undef()?; @@ -455,7 +472,7 @@ fn call_intrinsic( "assert_zero_valid" | "assert_uninit_valid" => { let &[] = check_arg_count(args)?; - let ty = substs.type_at(0); + let ty = instance.substs.type_at(0); let layout = this.layout_of(ty)?; // Abort here because the caller might not be panic safe. if layout.abi.is_uninhabited() { diff --git a/tests/run-pass/intrinsics.rs b/tests/run-pass/intrinsics.rs index ffa7f080aa4..8f7dbac6706 100644 --- a/tests/run-pass/intrinsics.rs +++ b/tests/run-pass/intrinsics.rs @@ -1,4 +1,4 @@ -#![feature(core_intrinsics)] +#![feature(core_intrinsics, const_raw_ptr_comparison)] use std::intrinsics; use std::mem::{size_of, size_of_val}; @@ -30,4 +30,9 @@ fn main() { let _v = intrinsics::discriminant_value(&0); let _v = intrinsics::discriminant_value(&true); let _v = intrinsics::discriminant_value(&vec![1,2,3]); + + let addr = &13 as *const i32; + let addr2 = (addr as usize).wrapping_add(usize::MAX).wrapping_add(1); + assert!(addr.guaranteed_eq(addr2 as *const _)); + assert!(addr.guaranteed_ne(0x100 as *const _)); } -- 2.44.0