Auto merge of #25013 - pnkfelix:span_to_lines-oflo, r=huonw
Guard against overflow in `codemap::span_to_lines`. (Revised/expanded version of PR #24976) Make `span_to_lines` to return a `Result`. In `diagnostic`, catch `Err` from `span_to_lines` and print `"(unprintable span)"` instead. ---- There a number of recent issues that report the bug here. See e.g. #24761 and #24954. This change *might* fix them. However, that is *not* its main goal. The main goals are: 1. Make it possible for callers to recover from an error here, and 2. Insert a more conservative check, in that we are also checking that the files match up. ---- As a drive-by, fix #24997 , which was causing my attempts to `make check-stage1` on an `--enable-debug` build to fail.
This commit is contained in:
@@ -631,8 +631,14 @@ fn size_from_ptr<T>(_: *const T) -> usize {
|
||||
}
|
||||
|
||||
|
||||
// Use macro to be generic over const/mut
|
||||
macro_rules! slice_offset {
|
||||
// Use macros to be generic over const/mut
|
||||
//
|
||||
// They require non-negative `$by` because otherwise the expression
|
||||
// `(ptr as usize + $by)` would interpret `-1` as `usize::MAX` (and
|
||||
// thus trigger a panic when overflow checks are on).
|
||||
|
||||
// Use this to do `$ptr + $by`, where `$by` is non-negative.
|
||||
macro_rules! slice_add_offset {
|
||||
($ptr:expr, $by:expr) => {{
|
||||
let ptr = $ptr;
|
||||
if size_from_ptr(ptr) == 0 {
|
||||
@@ -643,6 +649,18 @@ macro_rules! slice_offset {
|
||||
}};
|
||||
}
|
||||
|
||||
// Use this to do `$ptr - $by`, where `$by` is non-negative.
|
||||
macro_rules! slice_sub_offset {
|
||||
($ptr:expr, $by:expr) => {{
|
||||
let ptr = $ptr;
|
||||
if size_from_ptr(ptr) == 0 {
|
||||
transmute(ptr as usize - $by)
|
||||
} else {
|
||||
ptr.offset(-$by)
|
||||
}
|
||||
}};
|
||||
}
|
||||
|
||||
macro_rules! slice_ref {
|
||||
($ptr:expr) => {{
|
||||
let ptr = $ptr;
|
||||
@@ -672,7 +690,7 @@ macro_rules! iterator {
|
||||
None
|
||||
} else {
|
||||
let old = self.ptr;
|
||||
self.ptr = slice_offset!(self.ptr, 1);
|
||||
self.ptr = slice_add_offset!(self.ptr, 1);
|
||||
Some(slice_ref!(old))
|
||||
}
|
||||
}
|
||||
@@ -714,7 +732,7 @@ macro_rules! iterator {
|
||||
if self.end == self.ptr {
|
||||
None
|
||||
} else {
|
||||
self.end = slice_offset!(self.end, -1);
|
||||
self.end = slice_sub_offset!(self.end, 1);
|
||||
Some(slice_ref!(self.end))
|
||||
}
|
||||
}
|
||||
@@ -776,7 +794,7 @@ impl<'a, T> Iter<'a, T> {
|
||||
fn iter_nth(&mut self, n: usize) -> Option<&'a T> {
|
||||
match self.as_slice().get(n) {
|
||||
Some(elem_ref) => unsafe {
|
||||
self.ptr = slice_offset!(elem_ref as *const _, 1);
|
||||
self.ptr = slice_add_offset!(elem_ref as *const _, 1);
|
||||
Some(slice_ref!(elem_ref))
|
||||
},
|
||||
None => {
|
||||
@@ -849,7 +867,7 @@ impl<'a, T> IterMut<'a, T> {
|
||||
fn iter_nth(&mut self, n: usize) -> Option<&'a mut T> {
|
||||
match make_mut_slice!(T => &'a mut [T]: self.ptr, self.end).get_mut(n) {
|
||||
Some(elem_ref) => unsafe {
|
||||
self.ptr = slice_offset!(elem_ref as *mut _, 1);
|
||||
self.ptr = slice_add_offset!(elem_ref as *mut _, 1);
|
||||
Some(slice_ref!(elem_ref))
|
||||
},
|
||||
None => {
|
||||
|
||||
Reference in New Issue
Block a user