From 5a501f73ff753109c7e73d4981fe011633bd8e84 Mon Sep 17 00:00:00 2001 From: Andreas Liljeqvist Date: Sun, 22 Aug 2021 21:46:03 +0200 Subject: Use custom wrap-around type instead of Range --- compiler/rustc_target/src/abi/mod.rs | 73 +++++++++++++++++++++--------------- 1 file changed, 43 insertions(+), 30 deletions(-) (limited to 'compiler/rustc_target/src') diff --git a/compiler/rustc_target/src/abi/mod.rs b/compiler/rustc_target/src/abi/mod.rs index 8ef6e142cae..07687a4b104 100644 --- a/compiler/rustc_target/src/abi/mod.rs +++ b/compiler/rustc_target/src/abi/mod.rs @@ -677,32 +677,52 @@ impl Primitive { } } +/// Inclusive wrap-around range of valid values, that is, if +/// start > end, it represents `start..=MAX`, +/// followed by `0..=end`. +/// +/// That is, for an i8 primitive, a range of `254..=2` means following +/// sequence: +/// +/// 254 (-2), 255 (-1), 0, 1, 2 +/// +/// This is intended specifically to mirror LLVM’s `!range` metadata, +/// semantics. +#[derive(Clone, Copy, PartialEq, Eq, Hash, Debug)] +#[derive(HashStable_Generic)] +pub struct AllocationRange { + pub start: u128, + pub end: u128, +} + +impl AllocationRange { + /// Returns `true` if `v` is contained in the range. + #[inline] + pub fn contains(&self, v: u128) -> bool { + if self.start <= self.end { + self.start <= v && v <= self.end + } else { + self.start <= v || v <= self.end + } + } +} + /// Information about one scalar component of a Rust type. #[derive(Clone, PartialEq, Eq, Hash, Debug)] #[derive(HashStable_Generic)] pub struct Scalar { pub value: Primitive, - /// Inclusive wrap-around range of valid values, that is, if - /// start > end, it represents `start..=MAX`, - /// followed by `0..=end`. - /// - /// That is, for an i8 primitive, a range of `254..=2` means following - /// sequence: - /// - /// 254 (-2), 255 (-1), 0, 1, 2 - /// - /// This is intended specifically to mirror LLVM’s `!range` metadata, - /// semantics. // FIXME(eddyb) always use the shortest range, e.g., by finding // the largest space between two consecutive valid values and // taking everything else as the (shortest) valid range. - pub valid_range: RangeInclusive, + pub valid_range: AllocationRange, } impl Scalar { pub fn is_bool(&self) -> bool { - matches!(self.value, Int(I8, false)) && self.valid_range == (0..=1) + matches!(self.value, Int(I8, false)) + && matches!(self.valid_range, AllocationRange { start: 0, end: 1 }) } /// Returns the valid range as a `x..y` range. @@ -715,8 +735,8 @@ impl Scalar { let bits = self.value.size(cx).bits(); assert!(bits <= 128); let mask = !0u128 >> (128 - bits); - let start = *self.valid_range.start(); - let end = *self.valid_range.end(); + let start = self.valid_range.start; + let end = self.valid_range.end; assert_eq!(start, start & mask); assert_eq!(end, end & mask); start..(end.wrapping_add(1) & mask) @@ -965,20 +985,20 @@ impl Niche { } pub fn available(&self, cx: &C) -> u128 { - let Scalar { value, valid_range: ref v } = self.scalar; + let Scalar { value, valid_range: v } = self.scalar; let bits = value.size(cx).bits(); assert!(bits <= 128); let max_value = !0u128 >> (128 - bits); // Find out how many values are outside the valid range. - let niche = v.end().wrapping_add(1)..*v.start(); + let niche = v.end.wrapping_add(1)..v.start; niche.end.wrapping_sub(niche.start) & max_value } pub fn reserve(&self, cx: &C, count: u128) -> Option<(u128, Scalar)> { assert!(count > 0); - let Scalar { value, valid_range: ref v } = self.scalar; + let Scalar { value, valid_range: v } = self.scalar; let bits = value.size(cx).bits(); assert!(bits <= 128); let max_value = !0u128 >> (128 - bits); @@ -988,24 +1008,17 @@ impl Niche { } // Compute the range of invalid values being reserved. - let start = v.end().wrapping_add(1) & max_value; - let end = v.end().wrapping_add(count) & max_value; + let start = v.end.wrapping_add(1) & max_value; + let end = v.end.wrapping_add(count) & max_value; // If the `end` of our range is inside the valid range, // then we ran out of invalid values. // FIXME(eddyb) abstract this with a wraparound range type. - let valid_range_contains = |x| { - if v.start() <= v.end() { - *v.start() <= x && x <= *v.end() - } else { - *v.start() <= x || x <= *v.end() - } - }; - if valid_range_contains(end) { + if v.contains(end) { return None; } - Some((start, Scalar { value, valid_range: *v.start()..=end })) + Some((start, Scalar { value, valid_range: AllocationRange { start: v.start, end } })) } } @@ -1214,7 +1227,7 @@ impl<'a, Ty> TyAndLayout<'a, Ty> { if zero { let range = &s.valid_range; // The range must contain 0. - range.contains(&0) || (*range.start() > *range.end()) // wrap-around allows 0 + range.contains(0) || (range.start > range.end) // wrap-around allows 0 } else { // The range must include all values. `valid_range_exclusive` handles // the wrap-around using target arithmetic; with wrap-around then the full -- cgit 1.4.1-3-g733a5 From 225a4bf9222dbef88dc6fbefe437602e55decf1b Mon Sep 17 00:00:00 2001 From: Andreas Liljeqvist Date: Mon, 23 Aug 2021 13:56:28 +0200 Subject: Removed fixed fixme --- compiler/rustc_target/src/abi/mod.rs | 3 --- 1 file changed, 3 deletions(-) (limited to 'compiler/rustc_target/src') diff --git a/compiler/rustc_target/src/abi/mod.rs b/compiler/rustc_target/src/abi/mod.rs index 07687a4b104..b30111c6788 100644 --- a/compiler/rustc_target/src/abi/mod.rs +++ b/compiler/rustc_target/src/abi/mod.rs @@ -1011,9 +1011,6 @@ impl Niche { let start = v.end.wrapping_add(1) & max_value; let end = v.end.wrapping_add(count) & max_value; - // If the `end` of our range is inside the valid range, - // then we ran out of invalid values. - // FIXME(eddyb) abstract this with a wraparound range type. if v.contains(end) { return None; } -- cgit 1.4.1-3-g733a5 From d50abd024901176f8b21081713bf4a2779d9aadb Mon Sep 17 00:00:00 2001 From: Andreas Liljeqvist Date: Mon, 23 Aug 2021 14:18:48 +0200 Subject: Use ref --- compiler/rustc_mir/src/interpret/validity.rs | 2 +- compiler/rustc_target/src/abi/mod.rs | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) (limited to 'compiler/rustc_target/src') diff --git a/compiler/rustc_mir/src/interpret/validity.rs b/compiler/rustc_mir/src/interpret/validity.rs index 71e616ff560..bf34430cece 100644 --- a/compiler/rustc_mir/src/interpret/validity.rs +++ b/compiler/rustc_mir/src/interpret/validity.rs @@ -623,7 +623,7 @@ impl<'rt, 'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> ValidityVisitor<'rt, 'mir, ' scalar_layout: &ScalarAbi, ) -> InterpResult<'tcx> { let value = self.read_scalar(op)?; - let valid_range = scalar_layout.valid_range; + let valid_range = scalar_layout.valid_range.clone(); let AllocationRange { start: lo, end: hi } = valid_range; // Determine the allowed range // `max_hi` is as big as the size fits diff --git a/compiler/rustc_target/src/abi/mod.rs b/compiler/rustc_target/src/abi/mod.rs index b30111c6788..c3ec9bb8233 100644 --- a/compiler/rustc_target/src/abi/mod.rs +++ b/compiler/rustc_target/src/abi/mod.rs @@ -985,7 +985,7 @@ impl Niche { } pub fn available(&self, cx: &C) -> u128 { - let Scalar { value, valid_range: v } = self.scalar; + let Scalar { value, valid_range: ref v } = self.scalar; let bits = value.size(cx).bits(); assert!(bits <= 128); let max_value = !0u128 >> (128 - bits); @@ -998,7 +998,7 @@ impl Niche { pub fn reserve(&self, cx: &C, count: u128) -> Option<(u128, Scalar)> { assert!(count > 0); - let Scalar { value, valid_range: v } = self.scalar; + let Scalar { value, valid_range: ref v } = self.scalar; let bits = value.size(cx).bits(); assert!(bits <= 128); let max_value = !0u128 >> (128 - bits); -- cgit 1.4.1-3-g733a5 From 70433955f4531f2742ddeb986e6ac19a8fd4792f Mon Sep 17 00:00:00 2001 From: Andreas Liljeqvist Date: Mon, 23 Aug 2021 14:20:38 +0200 Subject: implement contains_zero method --- compiler/rustc_codegen_llvm/src/builder.rs | 3 +-- compiler/rustc_middle/src/ty/layout.rs | 6 ++---- compiler/rustc_target/src/abi/mod.rs | 12 +++++++++--- 3 files changed, 12 insertions(+), 9 deletions(-) (limited to 'compiler/rustc_target/src') diff --git a/compiler/rustc_codegen_llvm/src/builder.rs b/compiler/rustc_codegen_llvm/src/builder.rs index 2b72b167426..7986d1d9cb2 100644 --- a/compiler/rustc_codegen_llvm/src/builder.rs +++ b/compiler/rustc_codegen_llvm/src/builder.rs @@ -462,7 +462,6 @@ impl BuilderMethods<'a, 'tcx> for Builder<'a, 'll, 'tcx> { load: &'ll Value, scalar: &abi::Scalar, ) { - let vr = scalar.valid_range; match scalar.value { abi::Int(..) => { let range = scalar.valid_range_exclusive(bx); @@ -470,7 +469,7 @@ impl BuilderMethods<'a, 'tcx> for Builder<'a, 'll, 'tcx> { bx.range_metadata(load, range); } } - abi::Pointer if vr.start < vr.end && !vr.contains(0) => { + abi::Pointer if !scalar.valid_range.contains_zero() => { bx.nonnull_metadata(load); } _ => {} diff --git a/compiler/rustc_middle/src/ty/layout.rs b/compiler/rustc_middle/src/ty/layout.rs index 671f956bf31..c6caab3e798 100644 --- a/compiler/rustc_middle/src/ty/layout.rs +++ b/compiler/rustc_middle/src/ty/layout.rs @@ -2857,10 +2857,8 @@ where return; } - if scalar.valid_range.start < scalar.valid_range.end { - if scalar.valid_range.start > 0 { - attrs.set(ArgAttribute::NonNull); - } + if !scalar.valid_range.contains_zero() { + attrs.set(ArgAttribute::NonNull); } if let Some(pointee) = layout.pointee_info_at(cx, offset) { diff --git a/compiler/rustc_target/src/abi/mod.rs b/compiler/rustc_target/src/abi/mod.rs index c3ec9bb8233..5ce8906e6ac 100644 --- a/compiler/rustc_target/src/abi/mod.rs +++ b/compiler/rustc_target/src/abi/mod.rs @@ -688,7 +688,7 @@ impl Primitive { /// /// This is intended specifically to mirror LLVM’s `!range` metadata, /// semantics. -#[derive(Clone, Copy, PartialEq, Eq, Hash, Debug)] +#[derive(Clone, PartialEq, Eq, Hash, Debug)] #[derive(HashStable_Generic)] pub struct AllocationRange { pub start: u128, @@ -705,6 +705,13 @@ impl AllocationRange { self.start <= v || v <= self.end } } + + /// Returns `true` if zero is contained in the range. + /// Equal to `range.contains(0)` but should be faster. + #[inline] + pub fn contains_zero(&self) -> bool { + !(self.start <= self.end && self.start != 0) + } } /// Information about one scalar component of a Rust type. @@ -1222,9 +1229,8 @@ impl<'a, Ty> TyAndLayout<'a, Ty> { { let scalar_allows_raw_init = move |s: &Scalar| -> bool { if zero { - let range = &s.valid_range; // The range must contain 0. - range.contains(0) || (range.start > range.end) // wrap-around allows 0 + s.valid_range.contains_zero() } else { // The range must include all values. `valid_range_exclusive` handles // the wrap-around using target arithmetic; with wrap-around then the full -- cgit 1.4.1-3-g733a5 From e8e6d9bd86c9cf685666718ca99e016275e1751b Mon Sep 17 00:00:00 2001 From: Andreas Liljeqvist Date: Mon, 23 Aug 2021 14:24:34 +0200 Subject: Rename to WrappingRange --- compiler/rustc_codegen_llvm/src/consts.rs | 7 ++----- compiler/rustc_middle/src/ty/layout.rs | 16 ++++++++-------- compiler/rustc_mir/src/interpret/validity.rs | 8 ++++---- compiler/rustc_target/src/abi/mod.rs | 10 +++++----- 4 files changed, 19 insertions(+), 22 deletions(-) (limited to 'compiler/rustc_target/src') diff --git a/compiler/rustc_codegen_llvm/src/consts.rs b/compiler/rustc_codegen_llvm/src/consts.rs index 01a93dd8857..ec92bd686d2 100644 --- a/compiler/rustc_codegen_llvm/src/consts.rs +++ b/compiler/rustc_codegen_llvm/src/consts.rs @@ -17,7 +17,7 @@ use rustc_middle::mir::mono::MonoItem; use rustc_middle::ty::{self, Instance, Ty}; use rustc_middle::{bug, span_bug}; use rustc_target::abi::{ - AddressSpace, Align, AllocationRange, HasDataLayout, LayoutOf, Primitive, Scalar, Size, + AddressSpace, Align, HasDataLayout, LayoutOf, Primitive, Scalar, Size, WrappingRange, }; use tracing::debug; @@ -61,10 +61,7 @@ pub fn const_alloc_to_llvm(cx: &CodegenCx<'ll, '_>, alloc: &Allocation) -> &'ll Pointer::new(alloc_id, Size::from_bytes(ptr_offset)), &cx.tcx, ), - &Scalar { - value: Primitive::Pointer, - valid_range: AllocationRange { start: 0, end: !0 }, - }, + &Scalar { value: Primitive::Pointer, valid_range: WrappingRange { start: 0, end: !0 } }, cx.type_i8p_ext(address_space), )); next_offset = offset + pointer_size; diff --git a/compiler/rustc_middle/src/ty/layout.rs b/compiler/rustc_middle/src/ty/layout.rs index c6caab3e798..6b628cb041b 100644 --- a/compiler/rustc_middle/src/ty/layout.rs +++ b/compiler/rustc_middle/src/ty/layout.rs @@ -499,7 +499,7 @@ impl<'tcx> LayoutCx<'tcx, TyCtxt<'tcx>> { let scalar_unit = |value: Primitive| { let bits = value.size(dl).bits(); assert!(bits <= 128); - Scalar { value, valid_range: AllocationRange { start: 0, end: (!0 >> (128 - bits)) } } + Scalar { value, valid_range: WrappingRange { start: 0, end: (!0 >> (128 - bits)) } } }; let scalar = |value: Primitive| tcx.intern_layout(Layout::scalar(self, scalar_unit(value))); @@ -512,13 +512,13 @@ impl<'tcx> LayoutCx<'tcx, TyCtxt<'tcx>> { // Basic scalars. ty::Bool => tcx.intern_layout(Layout::scalar( self, - Scalar { value: Int(I8, false), valid_range: AllocationRange { start: 0, end: 1 } }, + Scalar { value: Int(I8, false), valid_range: WrappingRange { start: 0, end: 1 } }, )), ty::Char => tcx.intern_layout(Layout::scalar( self, Scalar { value: Int(I32, false), - valid_range: AllocationRange { start: 0, end: 0x10FFFF }, + valid_range: WrappingRange { start: 0, end: 0x10FFFF }, }, )), ty::Int(ity) => scalar(Int(Integer::from_int_ty(dl, ity), true)), @@ -529,7 +529,7 @@ impl<'tcx> LayoutCx<'tcx, TyCtxt<'tcx>> { }), ty::FnPtr(_) => { let mut ptr = scalar_unit(Pointer); - ptr.valid_range = AllocationRange { start: 1, end: ptr.valid_range.end }; + ptr.valid_range = WrappingRange { start: 1, end: ptr.valid_range.end }; tcx.intern_layout(Layout::scalar(self, ptr)) } @@ -548,7 +548,7 @@ impl<'tcx> LayoutCx<'tcx, TyCtxt<'tcx>> { let mut data_ptr = scalar_unit(Pointer); if !ty.is_unsafe_ptr() { data_ptr.valid_range = - AllocationRange { start: 1, end: data_ptr.valid_range.end }; + WrappingRange { start: 1, end: data_ptr.valid_range.end }; } let pointee = tcx.normalize_erasing_regions(param_env, pointee); @@ -565,7 +565,7 @@ impl<'tcx> LayoutCx<'tcx, TyCtxt<'tcx>> { ty::Dynamic(..) => { let mut vtable = scalar_unit(Pointer); vtable.valid_range = - AllocationRange { start: 1, end: vtable.valid_range.end }; + WrappingRange { start: 1, end: vtable.valid_range.end }; vtable } _ => return Err(LayoutError::Unknown(unsized_part)), @@ -1261,7 +1261,7 @@ impl<'tcx> LayoutCx<'tcx, TyCtxt<'tcx>> { let tag_mask = !0u128 >> (128 - ity.size().bits()); let tag = Scalar { value: Int(ity, signed), - valid_range: AllocationRange { + valid_range: WrappingRange { start: (min as u128 & tag_mask), end: (max as u128 & tag_mask), }, @@ -1545,7 +1545,7 @@ impl<'tcx> LayoutCx<'tcx, TyCtxt<'tcx>> { let discr_int_ty = discr_int.to_ty(tcx, false); let tag = Scalar { value: Primitive::Int(discr_int, false), - valid_range: AllocationRange { start: 0, end: max_discr }, + valid_range: WrappingRange { start: 0, end: max_discr }, }; let tag_layout = self.tcx.intern_layout(Layout::scalar(self, tag.clone())); let tag_layout = TyAndLayout { ty: discr_int_ty, layout: tag_layout }; diff --git a/compiler/rustc_mir/src/interpret/validity.rs b/compiler/rustc_mir/src/interpret/validity.rs index bf34430cece..3ff149d6a7a 100644 --- a/compiler/rustc_mir/src/interpret/validity.rs +++ b/compiler/rustc_mir/src/interpret/validity.rs @@ -15,7 +15,7 @@ use rustc_middle::ty; use rustc_middle::ty::layout::TyAndLayout; use rustc_span::symbol::{sym, Symbol}; use rustc_target::abi::{ - Abi, AllocationRange, LayoutOf, Scalar as ScalarAbi, Size, VariantIdx, Variants, + Abi, LayoutOf, Scalar as ScalarAbi, Size, VariantIdx, Variants, WrappingRange, }; use std::hash::Hash; @@ -184,8 +184,8 @@ fn write_path(out: &mut String, path: &[PathElem]) { // Formats such that a sentence like "expected something {}" to mean // "expected something " makes sense. -fn wrapping_range_format(r: AllocationRange, max_hi: u128) -> String { - let AllocationRange { start: lo, end: hi } = r; +fn wrapping_range_format(r: WrappingRange, max_hi: u128) -> String { + let WrappingRange { start: lo, end: hi } = r; assert!(hi <= max_hi); if lo > hi { format!("less or equal to {}, or greater or equal to {}", hi, lo) @@ -624,7 +624,7 @@ impl<'rt, 'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> ValidityVisitor<'rt, 'mir, ' ) -> InterpResult<'tcx> { let value = self.read_scalar(op)?; let valid_range = scalar_layout.valid_range.clone(); - let AllocationRange { start: lo, end: hi } = valid_range; + let WrappingRange { start: lo, end: hi } = valid_range; // Determine the allowed range // `max_hi` is as big as the size fits let max_hi = u128::MAX >> (128 - op.layout.size.bits()); diff --git a/compiler/rustc_target/src/abi/mod.rs b/compiler/rustc_target/src/abi/mod.rs index 5ce8906e6ac..d29b731e4f1 100644 --- a/compiler/rustc_target/src/abi/mod.rs +++ b/compiler/rustc_target/src/abi/mod.rs @@ -690,12 +690,12 @@ impl Primitive { /// semantics. #[derive(Clone, PartialEq, Eq, Hash, Debug)] #[derive(HashStable_Generic)] -pub struct AllocationRange { +pub struct WrappingRange { pub start: u128, pub end: u128, } -impl AllocationRange { +impl WrappingRange { /// Returns `true` if `v` is contained in the range. #[inline] pub fn contains(&self, v: u128) -> bool { @@ -723,13 +723,13 @@ pub struct Scalar { // FIXME(eddyb) always use the shortest range, e.g., by finding // the largest space between two consecutive valid values and // taking everything else as the (shortest) valid range. - pub valid_range: AllocationRange, + pub valid_range: WrappingRange, } impl Scalar { pub fn is_bool(&self) -> bool { matches!(self.value, Int(I8, false)) - && matches!(self.valid_range, AllocationRange { start: 0, end: 1 }) + && matches!(self.valid_range, WrappingRange { start: 0, end: 1 }) } /// Returns the valid range as a `x..y` range. @@ -1022,7 +1022,7 @@ impl Niche { return None; } - Some((start, Scalar { value, valid_range: AllocationRange { start: v.start, end } })) + Some((start, Scalar { value, valid_range: WrappingRange { start: v.start, end } })) } } -- cgit 1.4.1-3-g733a5 From d230b92ba7a2a32000be5e207860aa27d1a11113 Mon Sep 17 00:00:00 2001 From: Andreas Liljeqvist Date: Mon, 23 Aug 2021 15:05:40 +0200 Subject: implement debug in similar way to RangeInclusive --- compiler/rustc_target/src/abi/mod.rs | 9 ++- .../ui/consts/const-eval/ub-nonnull.32bit.stderr | 2 +- .../ui/consts/const-eval/ub-nonnull.64bit.stderr | 2 +- src/test/ui/layout/debug.stderr | 45 +++---------- src/test/ui/layout/hexagon-enum.stderr | 75 +++++----------------- src/test/ui/layout/thumb-enum.stderr | 75 +++++----------------- 6 files changed, 49 insertions(+), 159 deletions(-) (limited to 'compiler/rustc_target/src') diff --git a/compiler/rustc_target/src/abi/mod.rs b/compiler/rustc_target/src/abi/mod.rs index d29b731e4f1..c9d0b12e739 100644 --- a/compiler/rustc_target/src/abi/mod.rs +++ b/compiler/rustc_target/src/abi/mod.rs @@ -688,7 +688,7 @@ impl Primitive { /// /// This is intended specifically to mirror LLVM’s `!range` metadata, /// semantics. -#[derive(Clone, PartialEq, Eq, Hash, Debug)] +#[derive(Clone, PartialEq, Eq, Hash)] #[derive(HashStable_Generic)] pub struct WrappingRange { pub start: u128, @@ -714,6 +714,13 @@ impl WrappingRange { } } +impl fmt::Debug for WrappingRange { + fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result { + write!(fmt, "{}..={}", self.start, self.end)?; + Ok(()) + } +} + /// Information about one scalar component of a Rust type. #[derive(Clone, PartialEq, Eq, Hash, Debug)] #[derive(HashStable_Generic)] diff --git a/src/test/ui/consts/const-eval/ub-nonnull.32bit.stderr b/src/test/ui/consts/const-eval/ub-nonnull.32bit.stderr index 01403a61e5e..e44f3249454 100644 --- a/src/test/ui/consts/const-eval/ub-nonnull.32bit.stderr +++ b/src/test/ui/consts/const-eval/ub-nonnull.32bit.stderr @@ -52,7 +52,7 @@ error[E0080]: it is undefined behavior to use this value --> $DIR/ub-nonnull.rs:41:1 | LL | const BAD_RANGE1: RestrictedRange1 = unsafe { RestrictedRange1(42) }; - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ type validation failed: encountered 42, but expected something in the range AllocationRange { start: 10, end: 30 } + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ type validation failed: encountered 42, but expected something in the range 10..=30 | = note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rustc repository if you believe it should not be considered undefined behavior. = note: the raw bytes of the constant (size: 4, align: 4) { diff --git a/src/test/ui/consts/const-eval/ub-nonnull.64bit.stderr b/src/test/ui/consts/const-eval/ub-nonnull.64bit.stderr index 41de900f164..1ce87bc7c1c 100644 --- a/src/test/ui/consts/const-eval/ub-nonnull.64bit.stderr +++ b/src/test/ui/consts/const-eval/ub-nonnull.64bit.stderr @@ -52,7 +52,7 @@ error[E0080]: it is undefined behavior to use this value --> $DIR/ub-nonnull.rs:41:1 | LL | const BAD_RANGE1: RestrictedRange1 = unsafe { RestrictedRange1(42) }; - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ type validation failed: encountered 42, but expected something in the range AllocationRange { start: 10, end: 30 } + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ type validation failed: encountered 42, but expected something in the range 10..=30 | = note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rustc repository if you believe it should not be considered undefined behavior. = note: the raw bytes of the constant (size: 4, align: 4) { diff --git a/src/test/ui/layout/debug.stderr b/src/test/ui/layout/debug.stderr index cbe9b6400c3..1a371c6b170 100644 --- a/src/test/ui/layout/debug.stderr +++ b/src/test/ui/layout/debug.stderr @@ -15,10 +15,7 @@ error: layout_of(E) = Layout { I32, false, ), - valid_range: AllocationRange { - start: 0, - end: 0, - }, + valid_range: 0..=0, }, tag_encoding: Direct, tag_field: 0, @@ -94,10 +91,7 @@ error: layout_of(E) = Layout { I32, false, ), - valid_range: AllocationRange { - start: 0, - end: 0, - }, + valid_range: 0..=0, }, }, ), @@ -144,20 +138,14 @@ error: layout_of(S) = Layout { I32, true, ), - valid_range: AllocationRange { - start: 0, - end: 4294967295, - }, + valid_range: 0..=4294967295, }, Scalar { value: Int( I32, true, ), - valid_range: AllocationRange { - start: 0, - end: 4294967295, - }, + valid_range: 0..=4294967295, }, ), largest_niche: None, @@ -219,10 +207,7 @@ error: layout_of(std::result::Result) = Layout { I32, false, ), - valid_range: AllocationRange { - start: 0, - end: 1, - }, + valid_range: 0..=1, }, tag_encoding: Direct, tag_field: 0, @@ -291,20 +276,14 @@ error: layout_of(std::result::Result) = Layout { I32, false, ), - valid_range: AllocationRange { - start: 0, - end: 1, - }, + valid_range: 0..=1, }, Scalar { value: Int( I32, true, ), - valid_range: AllocationRange { - start: 0, - end: 4294967295, - }, + valid_range: 0..=4294967295, }, ), largest_niche: Some( @@ -317,10 +296,7 @@ error: layout_of(std::result::Result) = Layout { I32, false, ), - valid_range: AllocationRange { - start: 0, - end: 1, - }, + valid_range: 0..=1, }, }, ), @@ -350,10 +326,7 @@ error: layout_of(i32) = Layout { I32, true, ), - valid_range: AllocationRange { - start: 0, - end: 4294967295, - }, + valid_range: 0..=4294967295, }, ), largest_niche: None, diff --git a/src/test/ui/layout/hexagon-enum.stderr b/src/test/ui/layout/hexagon-enum.stderr index 520ba12c39f..d4676a5afb2 100644 --- a/src/test/ui/layout/hexagon-enum.stderr +++ b/src/test/ui/layout/hexagon-enum.stderr @@ -15,10 +15,7 @@ error: layout_of(A) = Layout { I8, false, ), - valid_range: AllocationRange { - start: 0, - end: 0, - }, + valid_range: 0..=0, }, tag_encoding: Direct, tag_field: 0, @@ -55,10 +52,7 @@ error: layout_of(A) = Layout { I8, false, ), - valid_range: AllocationRange { - start: 0, - end: 0, - }, + valid_range: 0..=0, }, ), largest_niche: Some( @@ -71,10 +65,7 @@ error: layout_of(A) = Layout { I8, false, ), - valid_range: AllocationRange { - start: 0, - end: 0, - }, + valid_range: 0..=0, }, }, ), @@ -112,10 +103,7 @@ error: layout_of(B) = Layout { I8, false, ), - valid_range: AllocationRange { - start: 255, - end: 255, - }, + valid_range: 255..=255, }, tag_encoding: Direct, tag_field: 0, @@ -152,10 +140,7 @@ error: layout_of(B) = Layout { I8, false, ), - valid_range: AllocationRange { - start: 255, - end: 255, - }, + valid_range: 255..=255, }, ), largest_niche: Some( @@ -168,10 +153,7 @@ error: layout_of(B) = Layout { I8, false, ), - valid_range: AllocationRange { - start: 255, - end: 255, - }, + valid_range: 255..=255, }, }, ), @@ -209,10 +191,7 @@ error: layout_of(C) = Layout { I16, false, ), - valid_range: AllocationRange { - start: 256, - end: 256, - }, + valid_range: 256..=256, }, tag_encoding: Direct, tag_field: 0, @@ -249,10 +228,7 @@ error: layout_of(C) = Layout { I16, false, ), - valid_range: AllocationRange { - start: 256, - end: 256, - }, + valid_range: 256..=256, }, ), largest_niche: Some( @@ -265,10 +241,7 @@ error: layout_of(C) = Layout { I16, false, ), - valid_range: AllocationRange { - start: 256, - end: 256, - }, + valid_range: 256..=256, }, }, ), @@ -306,10 +279,7 @@ error: layout_of(P) = Layout { I32, false, ), - valid_range: AllocationRange { - start: 268435456, - end: 268435456, - }, + valid_range: 268435456..=268435456, }, tag_encoding: Direct, tag_field: 0, @@ -346,10 +316,7 @@ error: layout_of(P) = Layout { I32, false, ), - valid_range: AllocationRange { - start: 268435456, - end: 268435456, - }, + valid_range: 268435456..=268435456, }, ), largest_niche: Some( @@ -362,10 +329,7 @@ error: layout_of(P) = Layout { I32, false, ), - valid_range: AllocationRange { - start: 268435456, - end: 268435456, - }, + valid_range: 268435456..=268435456, }, }, ), @@ -403,10 +367,7 @@ error: layout_of(T) = Layout { I32, true, ), - valid_range: AllocationRange { - start: 2164260864, - end: 2164260864, - }, + valid_range: 2164260864..=2164260864, }, tag_encoding: Direct, tag_field: 0, @@ -443,10 +404,7 @@ error: layout_of(T) = Layout { I32, true, ), - valid_range: AllocationRange { - start: 2164260864, - end: 2164260864, - }, + valid_range: 2164260864..=2164260864, }, ), largest_niche: Some( @@ -459,10 +417,7 @@ error: layout_of(T) = Layout { I32, true, ), - valid_range: AllocationRange { - start: 2164260864, - end: 2164260864, - }, + valid_range: 2164260864..=2164260864, }, }, ), diff --git a/src/test/ui/layout/thumb-enum.stderr b/src/test/ui/layout/thumb-enum.stderr index 50e37c54116..898a61b904d 100644 --- a/src/test/ui/layout/thumb-enum.stderr +++ b/src/test/ui/layout/thumb-enum.stderr @@ -15,10 +15,7 @@ error: layout_of(A) = Layout { I8, false, ), - valid_range: AllocationRange { - start: 0, - end: 0, - }, + valid_range: 0..=0, }, tag_encoding: Direct, tag_field: 0, @@ -55,10 +52,7 @@ error: layout_of(A) = Layout { I8, false, ), - valid_range: AllocationRange { - start: 0, - end: 0, - }, + valid_range: 0..=0, }, ), largest_niche: Some( @@ -71,10 +65,7 @@ error: layout_of(A) = Layout { I8, false, ), - valid_range: AllocationRange { - start: 0, - end: 0, - }, + valid_range: 0..=0, }, }, ), @@ -112,10 +103,7 @@ error: layout_of(B) = Layout { I8, false, ), - valid_range: AllocationRange { - start: 255, - end: 255, - }, + valid_range: 255..=255, }, tag_encoding: Direct, tag_field: 0, @@ -152,10 +140,7 @@ error: layout_of(B) = Layout { I8, false, ), - valid_range: AllocationRange { - start: 255, - end: 255, - }, + valid_range: 255..=255, }, ), largest_niche: Some( @@ -168,10 +153,7 @@ error: layout_of(B) = Layout { I8, false, ), - valid_range: AllocationRange { - start: 255, - end: 255, - }, + valid_range: 255..=255, }, }, ), @@ -209,10 +191,7 @@ error: layout_of(C) = Layout { I16, false, ), - valid_range: AllocationRange { - start: 256, - end: 256, - }, + valid_range: 256..=256, }, tag_encoding: Direct, tag_field: 0, @@ -249,10 +228,7 @@ error: layout_of(C) = Layout { I16, false, ), - valid_range: AllocationRange { - start: 256, - end: 256, - }, + valid_range: 256..=256, }, ), largest_niche: Some( @@ -265,10 +241,7 @@ error: layout_of(C) = Layout { I16, false, ), - valid_range: AllocationRange { - start: 256, - end: 256, - }, + valid_range: 256..=256, }, }, ), @@ -306,10 +279,7 @@ error: layout_of(P) = Layout { I32, false, ), - valid_range: AllocationRange { - start: 268435456, - end: 268435456, - }, + valid_range: 268435456..=268435456, }, tag_encoding: Direct, tag_field: 0, @@ -346,10 +316,7 @@ error: layout_of(P) = Layout { I32, false, ), - valid_range: AllocationRange { - start: 268435456, - end: 268435456, - }, + valid_range: 268435456..=268435456, }, ), largest_niche: Some( @@ -362,10 +329,7 @@ error: layout_of(P) = Layout { I32, false, ), - valid_range: AllocationRange { - start: 268435456, - end: 268435456, - }, + valid_range: 268435456..=268435456, }, }, ), @@ -403,10 +367,7 @@ error: layout_of(T) = Layout { I32, true, ), - valid_range: AllocationRange { - start: 2164260864, - end: 2164260864, - }, + valid_range: 2164260864..=2164260864, }, tag_encoding: Direct, tag_field: 0, @@ -443,10 +404,7 @@ error: layout_of(T) = Layout { I32, true, ), - valid_range: AllocationRange { - start: 2164260864, - end: 2164260864, - }, + valid_range: 2164260864..=2164260864, }, ), largest_niche: Some( @@ -459,10 +417,7 @@ error: layout_of(T) = Layout { I32, true, ), - valid_range: AllocationRange { - start: 2164260864, - end: 2164260864, - }, + valid_range: 2164260864..=2164260864, }, }, ), -- cgit 1.4.1-3-g733a5 From 32d7e5b723f97092e392abc33074d8e750a9cb23 Mon Sep 17 00:00:00 2001 From: Andreas Liljeqvist Date: Mon, 23 Aug 2021 15:44:56 +0200 Subject: add `with_start` and `with_end` --- compiler/rustc_middle/src/ty/layout.rs | 8 +++----- compiler/rustc_target/src/abi/mod.rs | 12 +++++++++++- 2 files changed, 14 insertions(+), 6 deletions(-) (limited to 'compiler/rustc_target/src') diff --git a/compiler/rustc_middle/src/ty/layout.rs b/compiler/rustc_middle/src/ty/layout.rs index 6b628cb041b..dcb56d5b2ba 100644 --- a/compiler/rustc_middle/src/ty/layout.rs +++ b/compiler/rustc_middle/src/ty/layout.rs @@ -529,7 +529,7 @@ impl<'tcx> LayoutCx<'tcx, TyCtxt<'tcx>> { }), ty::FnPtr(_) => { let mut ptr = scalar_unit(Pointer); - ptr.valid_range = WrappingRange { start: 1, end: ptr.valid_range.end }; + ptr.valid_range = ptr.valid_range.with_start(1); tcx.intern_layout(Layout::scalar(self, ptr)) } @@ -547,8 +547,7 @@ impl<'tcx> LayoutCx<'tcx, TyCtxt<'tcx>> { ty::Ref(_, pointee, _) | ty::RawPtr(ty::TypeAndMut { ty: pointee, .. }) => { let mut data_ptr = scalar_unit(Pointer); if !ty.is_unsafe_ptr() { - data_ptr.valid_range = - WrappingRange { start: 1, end: data_ptr.valid_range.end }; + data_ptr.valid_range = data_ptr.valid_range.with_start(1); } let pointee = tcx.normalize_erasing_regions(param_env, pointee); @@ -564,8 +563,7 @@ impl<'tcx> LayoutCx<'tcx, TyCtxt<'tcx>> { ty::Slice(_) | ty::Str => scalar_unit(Int(dl.ptr_sized_integer(), false)), ty::Dynamic(..) => { let mut vtable = scalar_unit(Pointer); - vtable.valid_range = - WrappingRange { start: 1, end: vtable.valid_range.end }; + vtable.valid_range = vtable.valid_range.with_start(1); vtable } _ => return Err(LayoutError::Unknown(unsized_part)), diff --git a/compiler/rustc_target/src/abi/mod.rs b/compiler/rustc_target/src/abi/mod.rs index c9d0b12e739..6e2f8962eef 100644 --- a/compiler/rustc_target/src/abi/mod.rs +++ b/compiler/rustc_target/src/abi/mod.rs @@ -712,6 +712,16 @@ impl WrappingRange { pub fn contains_zero(&self) -> bool { !(self.start <= self.end && self.start != 0) } + + /// Returns new `WrappingRange` with replaced `start` + pub fn with_start(&self, start: u128) -> Self { + Self { start, end: self.end } + } + + /// Returns new `WrappingRange` with replaced `end` + pub fn with_end(&self, end: u128) -> Self { + Self { start: self.start, end } + } } impl fmt::Debug for WrappingRange { @@ -1029,7 +1039,7 @@ impl Niche { return None; } - Some((start, Scalar { value, valid_range: WrappingRange { start: v.start, end } })) + Some((start, Scalar { value, valid_range: v.with_end(end) })) } } -- cgit 1.4.1-3-g733a5 From d92810646ed517376b16ac3b1fed329d8df2a8a9 Mon Sep 17 00:00:00 2001 From: Andreas Liljeqvist Date: Mon, 23 Aug 2021 15:52:47 +0200 Subject: Simplify zero check --- compiler/rustc_target/src/abi/mod.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'compiler/rustc_target/src') diff --git a/compiler/rustc_target/src/abi/mod.rs b/compiler/rustc_target/src/abi/mod.rs index 6e2f8962eef..b352243c0c4 100644 --- a/compiler/rustc_target/src/abi/mod.rs +++ b/compiler/rustc_target/src/abi/mod.rs @@ -710,7 +710,7 @@ impl WrappingRange { /// Equal to `range.contains(0)` but should be faster. #[inline] pub fn contains_zero(&self) -> bool { - !(self.start <= self.end && self.start != 0) + self.start > self.end || self.start == 0 } /// Returns new `WrappingRange` with replaced `start` -- cgit 1.4.1-3-g733a5 From e3f07b2e30eb29a737b13ab127db927d3825c22b Mon Sep 17 00:00:00 2001 From: Andreas Liljeqvist Date: Tue, 24 Aug 2021 10:18:07 +0200 Subject: Force inline: small functions and single call-site --- compiler/rustc_target/src/abi/mod.rs | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) (limited to 'compiler/rustc_target/src') diff --git a/compiler/rustc_target/src/abi/mod.rs b/compiler/rustc_target/src/abi/mod.rs index b352243c0c4..49c06fca85a 100644 --- a/compiler/rustc_target/src/abi/mod.rs +++ b/compiler/rustc_target/src/abi/mod.rs @@ -697,7 +697,7 @@ pub struct WrappingRange { impl WrappingRange { /// Returns `true` if `v` is contained in the range. - #[inline] + #[inline(always)] pub fn contains(&self, v: u128) -> bool { if self.start <= self.end { self.start <= v && v <= self.end @@ -708,17 +708,19 @@ impl WrappingRange { /// Returns `true` if zero is contained in the range. /// Equal to `range.contains(0)` but should be faster. - #[inline] + #[inline(always)] pub fn contains_zero(&self) -> bool { self.start > self.end || self.start == 0 } /// Returns new `WrappingRange` with replaced `start` + #[inline(always)] pub fn with_start(&self, start: u128) -> Self { Self { start, end: self.end } } /// Returns new `WrappingRange` with replaced `end` + #[inline(always)] pub fn with_end(&self, end: u128) -> Self { Self { start: self.start, end } } -- cgit 1.4.1-3-g733a5 From f17e384a43dd8ca0aefb36bfcd8a69d9ad7f12cf Mon Sep 17 00:00:00 2001 From: Andreas Liljeqvist Date: Tue, 24 Aug 2021 19:41:58 +0200 Subject: use convention for with_* methods --- compiler/rustc_target/src/abi/mod.rs | 16 +++++++++------- 1 file changed, 9 insertions(+), 7 deletions(-) (limited to 'compiler/rustc_target/src') diff --git a/compiler/rustc_target/src/abi/mod.rs b/compiler/rustc_target/src/abi/mod.rs index 49c06fca85a..d206df46120 100644 --- a/compiler/rustc_target/src/abi/mod.rs +++ b/compiler/rustc_target/src/abi/mod.rs @@ -713,16 +713,18 @@ impl WrappingRange { self.start > self.end || self.start == 0 } - /// Returns new `WrappingRange` with replaced `start` + /// Returns `self` with replaced `start` #[inline(always)] - pub fn with_start(&self, start: u128) -> Self { - Self { start, end: self.end } + pub fn with_start(mut self, start: u128) -> Self { + self.start = start; + self } - /// Returns new `WrappingRange` with replaced `end` + /// Returns `self` with replaced `end` #[inline(always)] - pub fn with_end(&self, end: u128) -> Self { - Self { start: self.start, end } + pub fn with_end(mut self, end: u128) -> Self { + self.end = end; + self } } @@ -1024,7 +1026,7 @@ impl Niche { pub fn reserve(&self, cx: &C, count: u128) -> Option<(u128, Scalar)> { assert!(count > 0); - let Scalar { value, valid_range: ref v } = self.scalar; + let Scalar { value, valid_range: v } = self.scalar.clone(); let bits = value.size(cx).bits(); assert!(bits <= 128); let max_value = !0u128 >> (128 - bits); -- cgit 1.4.1-3-g733a5