Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Rollup of 7 pull requests #94860

Merged
merged 21 commits into from
Mar 12, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
21 commits
Select commit Hold shift + click to select a range
5b5649f
Add missing documentation for std::char types
GuillaumeGomez Jul 30, 2021
3f2cb6e
Rename `IntoFuture::Future` to `IntoFuture::IntoFuture`
yoshuawuyts Mar 10, 2022
63ed8e4
adjust offset_from logic: check that both pointers are in-bounds
RalfJung Mar 10, 2022
09c3e82
Refactor the second half of `parse_tt`.
nnethercote Mar 9, 2022
4d4baf7
Disallow `TokenTree::{MetaVar,MetaVarExpr}` in matchers.
nnethercote Mar 9, 2022
9f0798b
Add a useful assertion.
nnethercote Mar 9, 2022
c13ca42
Move `eof_items` handling entirely within `inner_parse_loop`.
nnethercote Mar 9, 2022
235a87f
Make next_items a `SmallVec`.
nnethercote Mar 9, 2022
95d13fa
Move a `parse_tt` error case into a separate function.
nnethercote Mar 9, 2022
4c17217
make float parsing docs more comprehensive
antonok-edm Mar 11, 2022
bdc3177
suggest using double colon when using single colon in struct field ty…
TaKO8Ki Mar 11, 2022
813f00d
fix a suggestion message
TaKO8Ki Mar 11, 2022
87fba23
Collapse Blanket Implementations and Auto-trait implementations by de…
GuillaumeGomez Mar 8, 2022
aad4227
Update GUI test
GuillaumeGomez Mar 8, 2022
8505610
Rollup merge of #87618 - GuillaumeGomez:std-char-types-doc, r=jyn514,…
Dylan-DPC Mar 11, 2022
0e3ae8d
Rollup merge of #94769 - GuillaumeGomez:collapsed-by-default, r=notri…
Dylan-DPC Mar 11, 2022
86376e3
Rollup merge of #94798 - nnethercote:parse_tt-refactor, r=petrochenkov
Dylan-DPC Mar 11, 2022
fedf70a
Rollup merge of #94818 - yoshuawuyts:into-future-associated-type, r=j…
Dylan-DPC Mar 11, 2022
9e70b1a
Rollup merge of #94827 - RalfJung:offset-from-ub, r=oli-obk
Dylan-DPC Mar 11, 2022
ad51354
Rollup merge of #94838 - antonok-edm:float-parse-docs, r=Dylan-DPC
Dylan-DPC Mar 11, 2022
298c9a0
Rollup merge of #94839 - TaKO8Ki:suggest-using-double-colon-for-struc…
Dylan-DPC Mar 11, 2022
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
80 changes: 42 additions & 38 deletions compiler/rustc_const_eval/src/interpret/intrinsics.rs
Original file line number Diff line number Diff line change
Expand Up @@ -307,53 +307,57 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
self.write_pointer(offset_ptr, dest)?;
}
sym::ptr_offset_from => {
let a = self.read_immediate(&args[0])?.to_scalar()?;
let b = self.read_immediate(&args[1])?.to_scalar()?;
let a = self.read_pointer(&args[0])?;
let b = self.read_pointer(&args[1])?;

// Special case: if both scalars are *equal integers*
// and not null, we pretend there is an allocation of size 0 right there,
// and their offset is 0. (There's never a valid object at null, making it an
// exception from the exception.)
// This is the dual to the special exception for offset-by-0
// in the inbounds pointer offset operation (see the Miri code, `src/operator.rs`).
//
// Control flow is weird because we cannot early-return (to reach the
// `go_to_block` at the end).
let done = if let (Ok(a), Ok(b)) = (a.try_to_int(), b.try_to_int()) {
let a = a.try_to_machine_usize(*self.tcx).unwrap();
let b = b.try_to_machine_usize(*self.tcx).unwrap();
if a == b && a != 0 {
// in the inbounds pointer offset operation (see `ptr_offset_inbounds` below).
match (self.memory.ptr_try_get_alloc(a), self.memory.ptr_try_get_alloc(b)) {
(Err(a), Err(b)) if a == b && a != 0 => {
// Both are the same non-null integer.
self.write_scalar(Scalar::from_machine_isize(0, self), dest)?;
true
} else {
false
}
} else {
false
};

if !done {
// General case: we need two pointers.
let a = self.scalar_to_ptr(a);
let b = self.scalar_to_ptr(b);
let (a_alloc_id, a_offset, _) = self.memory.ptr_get_alloc(a)?;
let (b_alloc_id, b_offset, _) = self.memory.ptr_get_alloc(b)?;
if a_alloc_id != b_alloc_id {
throw_ub_format!(
"ptr_offset_from cannot compute offset of pointers into different \
allocations.",
);
(Err(offset), _) | (_, Err(offset)) => {
throw_ub!(DanglingIntPointer(offset, CheckInAllocMsg::OffsetFromTest));
}
(Ok((a_alloc_id, a_offset, _)), Ok((b_alloc_id, b_offset, _))) => {
// Both are pointers. They must be into the same allocation.
if a_alloc_id != b_alloc_id {
throw_ub_format!(
"ptr_offset_from cannot compute offset of pointers into different \
allocations.",
);
}
// And they must both be valid for zero-sized accesses ("in-bounds or one past the end").
self.memory.check_ptr_access_align(
a,
Size::ZERO,
Align::ONE,
CheckInAllocMsg::OffsetFromTest,
)?;
self.memory.check_ptr_access_align(
b,
Size::ZERO,
Align::ONE,
CheckInAllocMsg::OffsetFromTest,
)?;

// Compute offset.
let usize_layout = self.layout_of(self.tcx.types.usize)?;
let isize_layout = self.layout_of(self.tcx.types.isize)?;
let a_offset = ImmTy::from_uint(a_offset.bytes(), usize_layout);
let b_offset = ImmTy::from_uint(b_offset.bytes(), usize_layout);
let (val, _overflowed, _ty) =
self.overflowing_binary_op(BinOp::Sub, &a_offset, &b_offset)?;
let pointee_layout = self.layout_of(substs.type_at(0))?;
let val = ImmTy::from_scalar(val, isize_layout);
let size = ImmTy::from_int(pointee_layout.size.bytes(), isize_layout);
self.exact_div(&val, &size, dest)?;
}
let usize_layout = self.layout_of(self.tcx.types.usize)?;
let isize_layout = self.layout_of(self.tcx.types.isize)?;
let a_offset = ImmTy::from_uint(a_offset.bytes(), usize_layout);
let b_offset = ImmTy::from_uint(b_offset.bytes(), usize_layout);
let (val, _overflowed, _ty) =
self.overflowing_binary_op(BinOp::Sub, &a_offset, &b_offset)?;
let pointee_layout = self.layout_of(substs.type_at(0))?;
let val = ImmTy::from_scalar(val, isize_layout);
let size = ImmTy::from_int(pointee_layout.size.bytes(), isize_layout);
self.exact_div(&val, &size, dest)?;
}
}

Expand Down
6 changes: 3 additions & 3 deletions compiler/rustc_const_eval/src/interpret/memory.rs
Original file line number Diff line number Diff line change
Expand Up @@ -388,9 +388,9 @@ impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> Memory<'mir, 'tcx, M> {
CheckInAllocMsg::DerefTest | CheckInAllocMsg::MemoryAccessTest => {
AllocCheck::Dereferenceable
}
CheckInAllocMsg::PointerArithmeticTest | CheckInAllocMsg::InboundsTest => {
AllocCheck::Live
}
CheckInAllocMsg::PointerArithmeticTest
| CheckInAllocMsg::OffsetFromTest
| CheckInAllocMsg::InboundsTest => AllocCheck::Live,
};
let (size, align) = self.get_size_and_align(alloc_id, check)?;
Ok((size, align, ()))
Expand Down
Loading