Skip to content

Commit abc6e24

Browse files
committed
Auto merge of #58475 - alex:usize-overflow-panic, r=<try>
[WIP] Make usize overflow always have debug-assertions semantics This is a prototype for rust-lang/rfcs#2635 to enable us to collect some measurements.
2 parents 02a4e27 + 864dd3c commit abc6e24

File tree

19 files changed

+56
-104
lines changed

19 files changed

+56
-104
lines changed

src/librustc/ty/query/on_disk_cache.rs

+7-8
Original file line numberDiff line numberDiff line change
@@ -105,22 +105,21 @@ impl AbsoluteBytePos {
105105

106106
impl<'sess> OnDiskCache<'sess> {
107107
/// Creates a new OnDiskCache instance from the serialized data in `data`.
108-
pub fn new(sess: &'sess Session, data: Vec<u8>, start_pos: usize) -> OnDiskCache<'sess> {
108+
pub fn new(sess: &'sess Session, data: Vec<u8>) -> OnDiskCache<'sess> {
109109
debug_assert!(sess.opts.incremental.is_some());
110110

111111
// Wrapping in a scope so we can borrow `data`
112112
let footer: Footer = {
113-
let mut decoder = opaque::Decoder::new(&data[..], start_pos);
114-
115113
// Decode the *position* of the footer which can be found in the
116114
// last 8 bytes of the file.
117-
decoder.set_position(data.len() - IntEncodedWithFixedSize::ENCODED_SIZE);
115+
let mut decoder = opaque::Decoder::new(
116+
&data, data.len() - IntEncodedWithFixedSize::ENCODED_SIZE);
118117
let query_result_index_pos = IntEncodedWithFixedSize::decode(&mut decoder)
119118
.expect("Error while trying to decode query result index position.")
120119
.0 as usize;
121120

122121
// Decoder the file footer which contains all the lookup tables, etc.
123-
decoder.set_position(query_result_index_pos);
122+
decoder = opaque::Decoder::new(&data, query_result_index_pos);
124123
decode_tagged(&mut decoder, TAG_FILE_FOOTER)
125124
.expect("Error while trying to decode query result index position.")
126125
};
@@ -540,7 +539,7 @@ impl<'a, 'tcx: 'a, 'x> ty_codec::TyDecoder<'a, 'tcx> for CacheDecoder<'a, 'tcx,
540539

541540
#[inline]
542541
fn peek_byte(&self) -> u8 {
543-
self.opaque.data[self.opaque.position()]
542+
self.opaque.data()[0]
544543
}
545544

546545
fn cached_ty_for_shorthand<F>(&mut self,
@@ -569,9 +568,9 @@ impl<'a, 'tcx: 'a, 'x> ty_codec::TyDecoder<'a, 'tcx> for CacheDecoder<'a, 'tcx,
569568
fn with_position<F, R>(&mut self, pos: usize, f: F) -> R
570569
where F: FnOnce(&mut Self) -> R
571570
{
572-
debug_assert!(pos < self.opaque.data.len());
571+
debug_assert!(pos < self.opaque.original_data.len());
573572

574-
let new_opaque = opaque::Decoder::new(self.opaque.data, pos);
573+
let new_opaque = opaque::Decoder::new(&self.opaque.original_data, pos);
575574
let old_opaque = mem::replace(&mut self.opaque, new_opaque);
576575
let r = f(self);
577576
self.opaque = old_opaque;

src/librustc_codegen_llvm/context.rs

+11-3
Original file line numberDiff line numberDiff line change
@@ -12,13 +12,15 @@ use crate::type_of::PointeeInfo;
1212
use rustc_codegen_ssa::traits::*;
1313
use libc::c_uint;
1414

15+
use syntax::ast;
16+
1517
use rustc_data_structures::base_n;
1618
use rustc_data_structures::small_c_str::SmallCStr;
1719
use rustc::mir::mono::Stats;
1820
use rustc::session::config::{self, DebugInfo};
1921
use rustc::session::Session;
2022
use rustc::ty::layout::{LayoutError, LayoutOf, Size, TyLayout, VariantIdx};
21-
use rustc::ty::{self, Ty, TyCtxt};
23+
use rustc::ty::{self, Ty, TyCtxt, TyKind};
2224
use rustc::util::nodemap::FxHashMap;
2325
use rustc_target::spec::{HasTargetSpec, Target};
2426
use rustc_codegen_ssa::callee::resolve_and_get_fn;
@@ -409,8 +411,14 @@ impl MiscMethods<'tcx> for CodegenCx<'ll, 'tcx> {
409411
&self.tcx.sess
410412
}
411413

412-
fn check_overflow(&self) -> bool {
413-
self.check_overflow
414+
fn check_overflow(&self, ty: Option<Ty<'tcx>>) -> bool {
415+
let type_specific_overflow = match ty {
416+
Some(ty) => {
417+
ty.sty == TyKind::Uint(ast::UintTy::Usize)
418+
},
419+
None => false
420+
};
421+
self.check_overflow || type_specific_overflow
414422
}
415423

416424
fn stats(&self) -> &RefCell<Stats> {

src/librustc_codegen_ssa/mir/block.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -339,7 +339,7 @@ impl<'a, 'tcx: 'a, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
339339
// NOTE: Unlike binops, negation doesn't have its own
340340
// checked operation, just a comparison with the minimum
341341
// value, so we have to check for the assert message.
342-
if !bx.check_overflow() {
342+
if !bx.check_overflow(None) {
343343
if let mir::interpret::EvalErrorKind::OverflowNeg = *msg {
344344
const_cond = Some(expected);
345345
}

src/librustc_codegen_ssa/mir/rvalue.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -670,7 +670,7 @@ impl<'a, 'tcx: 'a, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
670670
// with #[rustc_inherit_overflow_checks] and inlined from
671671
// another crate (mostly core::num generic/#[inline] fns),
672672
// while the current crate doesn't use overflow checks.
673-
if !bx.cx().check_overflow() {
673+
if !bx.cx().check_overflow(Some(input_ty)) {
674674
let val = self.codegen_scalar_binop(bx, op, lhs, rhs, input_ty);
675675
return OperandValue::Pair(val, bx.cx().const_bool(false));
676676
}

src/librustc_codegen_ssa/traits/misc.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ pub trait MiscMethods<'tcx>: BackendTypes {
1212
fn vtables(
1313
&self,
1414
) -> &RefCell<FxHashMap<(Ty<'tcx>, Option<ty::PolyExistentialTraitRef<'tcx>>), Self::Value>>;
15-
fn check_overflow(&self) -> bool;
15+
fn check_overflow(&self, ty: Option<Ty<'tcx>>) -> bool;
1616
fn instances(&self) -> &RefCell<FxHashMap<Instance<'tcx>, Self::Value>>;
1717
fn get_fn(&self, instance: Instance<'tcx>) -> Self::Value;
1818
fn get_param(&self, llfn: Self::Value, index: c_uint) -> Self::Value;

src/librustc_incremental/persist/load.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -200,7 +200,7 @@ pub fn load_query_result_cache<'sess>(sess: &'sess Session) -> OnDiskCache<'sess
200200
}
201201

202202
match load_data(sess.opts.debugging_opts.incremental_info, &query_cache_path(sess)) {
203-
LoadResult::Ok{ data: (bytes, start_pos) } => OnDiskCache::new(sess, bytes, start_pos),
203+
LoadResult::Ok{ data: (bytes, _) } => OnDiskCache::new(sess, bytes),
204204
_ => OnDiskCache::new_empty(sess.source_map())
205205
}
206206
}

src/librustc_metadata/decoder.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -179,7 +179,7 @@ impl<'a, 'tcx: 'a> TyDecoder<'a, 'tcx> for DecodeContext<'a, 'tcx> {
179179

180180
#[inline]
181181
fn peek_byte(&self) -> u8 {
182-
self.opaque.data[self.opaque.position()]
182+
self.opaque.data()[0]
183183
}
184184

185185
#[inline]
@@ -212,7 +212,7 @@ impl<'a, 'tcx: 'a> TyDecoder<'a, 'tcx> for DecodeContext<'a, 'tcx> {
212212
fn with_position<F, R>(&mut self, pos: usize, f: F) -> R
213213
where F: FnOnce(&mut Self) -> R
214214
{
215-
let new_opaque = opaque::Decoder::new(self.opaque.data, pos);
215+
let new_opaque = opaque::Decoder::new(self.opaque.original_data, pos);
216216
let old_opaque = mem::replace(&mut self.opaque, new_opaque);
217217
let old_state = mem::replace(&mut self.lazy_state, LazyState::NoNode);
218218
let r = f(self);

src/librustc_mir/build/expr/as_rvalue.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -84,7 +84,7 @@ impl<'a, 'gcx, 'tcx> Builder<'a, 'gcx, 'tcx> {
8484
ExprKind::Unary { op, arg } => {
8585
let arg = unpack!(block = this.as_operand(block, scope, arg));
8686
// Check for -MIN on signed integers
87-
if this.hir.check_overflow() && op == UnOp::Neg && expr.ty.is_signed() {
87+
if this.hir.check_overflow(expr.ty) && op == UnOp::Neg && expr.ty.is_signed() {
8888
let bool_ty = this.hir.bool_ty();
8989

9090
let minval = this.minval_literal(expr_span, expr.ty);
@@ -410,7 +410,7 @@ impl<'a, 'gcx, 'tcx> Builder<'a, 'gcx, 'tcx> {
410410
) -> BlockAnd<Rvalue<'tcx>> {
411411
let source_info = self.source_info(span);
412412
let bool_ty = self.hir.bool_ty();
413-
if self.hir.check_overflow() && op.is_checkable() && ty.is_integral() {
413+
if self.hir.check_overflow(ty) && op.is_checkable() && ty.is_integral() {
414414
let result_tup = self.hir.tcx().intern_tup(&[ty, bool_ty]);
415415
let result_value = self.temp(result_tup, span);
416416

src/librustc_mir/hair/cx/mod.rs

+3-3
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ use rustc::hir::Node;
1111
use rustc::middle::region;
1212
use rustc::infer::InferCtxt;
1313
use rustc::ty::subst::Subst;
14-
use rustc::ty::{self, Ty, TyCtxt};
14+
use rustc::ty::{self, Ty, TyCtxt, TyKind};
1515
use rustc::ty::subst::{Kind, Substs};
1616
use rustc::ty::layout::VariantIdx;
1717
use syntax::ast;
@@ -218,8 +218,8 @@ impl<'a, 'gcx, 'tcx> Cx<'a, 'gcx, 'tcx> {
218218
self.tables
219219
}
220220

221-
pub fn check_overflow(&self) -> bool {
222-
self.check_overflow
221+
pub fn check_overflow(&self, ty: Ty<'tcx>) -> bool {
222+
self.check_overflow || ty.sty == TyKind::Uint(ast::UintTy::Usize)
223223
}
224224

225225
pub fn type_is_copy_modulo_regions(&self, ty: Ty<'tcx>, span: Span) -> bool {

src/libserialize/leb128.rs

+4-4
Original file line numberDiff line numberDiff line change
@@ -114,10 +114,10 @@ pub fn write_signed_leb128(out: &mut Vec<u8>, value: i128) {
114114
}
115115

116116
#[inline]
117-
pub fn read_signed_leb128(data: &[u8], start_position: usize) -> (i128, usize) {
117+
pub fn read_signed_leb128(data: &[u8]) -> (i128, usize) {
118118
let mut result = 0;
119119
let mut shift = 0;
120-
let mut position = start_position;
120+
let mut position = 0;
121121
let mut byte;
122122

123123
loop {
@@ -136,7 +136,7 @@ pub fn read_signed_leb128(data: &[u8], start_position: usize) -> (i128, usize) {
136136
result |= -(1 << shift);
137137
}
138138

139-
(result, position - start_position)
139+
(result, position)
140140
}
141141

142142
macro_rules! impl_test_unsigned_leb128 {
@@ -176,7 +176,7 @@ fn test_signed_leb128() {
176176
}
177177
let mut pos = 0;
178178
for &x in &values {
179-
let (value, bytes_read) = read_signed_leb128(&mut stream, pos);
179+
let (value, bytes_read) = read_signed_leb128(&mut stream[pos..]);
180180
pos += bytes_read;
181181
assert_eq!(x, value);
182182
}

src/libserialize/lib.rs

+1
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@ Core encoding and decoding interfaces.
1515
#![feature(specialization)]
1616
#![feature(never_type)]
1717
#![feature(nll)]
18+
#![feature(ptr_wrapping_offset_from)]
1819
#![cfg_attr(test, feature(test))]
1920

2021
pub use self::serialize::{Decoder, Encoder, Decodable, Encodable};

src/libserialize/opaque.rs

+22-26
Original file line numberDiff line numberDiff line change
@@ -157,59 +157,55 @@ impl Encoder {
157157
// -----------------------------------------------------------------------------
158158

159159
pub struct Decoder<'a> {
160-
pub data: &'a [u8],
161-
position: usize,
160+
pub original_data: &'a [u8],
161+
data: &'a [u8],
162162
}
163163

164164
impl<'a> Decoder<'a> {
165165
#[inline]
166-
pub fn new(data: &'a [u8], position: usize) -> Decoder<'a> {
166+
pub fn new(data: &'a [u8], pos: usize) -> Decoder<'a> {
167167
Decoder {
168-
data,
169-
position,
168+
original_data: data,
169+
data: &data[pos..],
170170
}
171171
}
172172

173173
#[inline]
174-
pub fn position(&self) -> usize {
175-
self.position
174+
pub fn data(&self) -> &[u8] {
175+
self.data
176176
}
177177

178178
#[inline]
179-
pub fn set_position(&mut self, pos: usize) {
180-
self.position = pos
179+
pub fn position(&self) -> usize {
180+
self.data.as_ptr().wrapping_offset_from(self.original_data.as_ptr()) as usize
181181
}
182182

183183
#[inline]
184184
pub fn advance(&mut self, bytes: usize) {
185-
self.position += bytes;
185+
self.data = &self.data[bytes..];
186186
}
187187

188188
#[inline]
189189
pub fn read_raw_bytes(&mut self, s: &mut [u8]) -> Result<(), String> {
190-
let start = self.position;
191-
let end = start + s.len();
192-
193-
s.copy_from_slice(&self.data[start..end]);
194-
195-
self.position = end;
190+
s.copy_from_slice(&self.data[..s.len()]);
191+
self.advance(s.len());
196192

197193
Ok(())
198194
}
199195
}
200196

201197
macro_rules! read_uleb128 {
202198
($dec:expr, $t:ty, $fun:ident) => ({
203-
let (value, bytes_read) = leb128::$fun(&$dec.data[$dec.position ..]);
204-
$dec.position += bytes_read;
199+
let (value, bytes_read) = leb128::$fun(&$dec.data);
200+
$dec.advance(bytes_read);
205201
Ok(value)
206202
})
207203
}
208204

209205
macro_rules! read_sleb128 {
210206
($dec:expr, $t:ty) => ({
211-
let (value, bytes_read) = read_signed_leb128($dec.data, $dec.position);
212-
$dec.position += bytes_read;
207+
let (value, bytes_read) = read_signed_leb128($dec.data);
208+
$dec.advance(bytes_read);
213209
Ok(value as $t)
214210
})
215211
}
@@ -245,8 +241,8 @@ impl<'a> serialize::Decoder for Decoder<'a> {
245241

246242
#[inline]
247243
fn read_u8(&mut self) -> Result<u8, Self::Error> {
248-
let value = self.data[self.position];
249-
self.position += 1;
244+
let value = self.data[0];
245+
self.advance(1);
250246
Ok(value)
251247
}
252248

@@ -277,8 +273,8 @@ impl<'a> serialize::Decoder for Decoder<'a> {
277273

278274
#[inline]
279275
fn read_i8(&mut self) -> Result<i8, Self::Error> {
280-
let as_u8 = self.data[self.position];
281-
self.position += 1;
276+
let as_u8 = self.data[0];
277+
self.advance(1);
282278
unsafe { Ok(::std::mem::transmute(as_u8)) }
283279
}
284280

@@ -314,8 +310,8 @@ impl<'a> serialize::Decoder for Decoder<'a> {
314310
#[inline]
315311
fn read_str(&mut self) -> Result<Cow<'_, str>, Self::Error> {
316312
let len = self.read_usize()?;
317-
let s = ::std::str::from_utf8(&self.data[self.position..self.position + len]).unwrap();
318-
self.position += len;
313+
let s = ::std::str::from_utf8(&self.data[..len]).unwrap();
314+
self.advance(len);
319315
Ok(Cow::Borrowed(s))
320316
}
321317

src/test/run-make-fulldeps/issue-14500/Makefile

-17
This file was deleted.

src/test/run-make-fulldeps/issue-14500/bar.rs

-1
This file was deleted.

src/test/run-make-fulldeps/issue-14500/foo.c

-7
This file was deleted.

src/test/run-make-fulldeps/issue-14500/foo.rs

-5
This file was deleted.

src/test/run-make-fulldeps/lto-smoke-c/Makefile

-11
This file was deleted.

src/test/run-make-fulldeps/lto-smoke-c/bar.c

-7
This file was deleted.

src/test/run-make-fulldeps/lto-smoke-c/foo.rs

-4
This file was deleted.

0 commit comments

Comments
 (0)