diff options
| author | Andreas Liljeqvist <bonega@gmail.com> | 2021-08-25 15:21:45 +0200 |
|---|---|---|
| committer | Andreas Liljeqvist <bonega@gmail.com> | 2021-09-09 10:41:17 +0200 |
| commit | 05cd48b008630cda27e2f1a082f9bab33d13a340 (patch) | |
| tree | 7c107af072d83ccc589979ac050394b34bcd80ff /compiler/rustc_const_eval/src | |
| parent | c5cbf7852a7692c7c51df64c09a59e7838b55202 (diff) | |
| download | rust-05cd48b008630cda27e2f1a082f9bab33d13a340.tar.gz rust-05cd48b008630cda27e2f1a082f9bab33d13a340.zip | |
Add methods for checking for full ranges to `Scalar` and `WrappingRange`
Move *_max methods back to util change to inline instead of inline(always) Remove valid_range_exclusive from scalar Use WrappingRange instead implement always_valid_for in a safer way Fix accidental edit
Diffstat (limited to 'compiler/rustc_const_eval/src')
| -rw-r--r-- | compiler/rustc_const_eval/src/interpret/validity.rs | 28 |
1 files changed, 13 insertions, 15 deletions
diff --git a/compiler/rustc_const_eval/src/interpret/validity.rs b/compiler/rustc_const_eval/src/interpret/validity.rs index 03e0a8e7901..7ae3f98d834 100644 --- a/compiler/rustc_const_eval/src/interpret/validity.rs +++ b/compiler/rustc_const_eval/src/interpret/validity.rs @@ -620,38 +620,36 @@ impl<'rt, 'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> ValidityVisitor<'rt, 'mir, ' op: &OpTy<'tcx, M::PointerTag>, scalar_layout: &ScalarAbi, ) -> InterpResult<'tcx> { - let value = self.read_scalar(op)?; - let valid_range = scalar_layout.valid_range.clone(); - 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()); - assert!(hi <= max_hi); - // We could also write `(hi + 1) % (max_hi + 1) == lo` but `max_hi + 1` overflows for `u128` - if (lo == 0 && hi == max_hi) || (hi + 1 == lo) { + if scalar_layout.valid_range.is_full_for(op.layout.size) { // Nothing to check return Ok(()); } - // At least one value is excluded. Get the bits. + // At least one value is excluded. + let valid_range = scalar_layout.valid_range.clone(); + let WrappingRange { start, end } = valid_range; + let max_value = u128::MAX >> (128 - op.layout.size.bits()); + assert!(end <= max_value); + // Determine the allowed range + let value = self.read_scalar(op)?; let value = try_validation!( value.check_init(), self.path, err_ub!(InvalidUninitBytes(None)) => { "{}", value } - expected { "something {}", wrapping_range_format(valid_range, max_hi) }, + expected { "something {}", wrapping_range_format(valid_range, max_value) }, ); let bits = match value.try_to_int() { Err(_) => { // So this is a pointer then, and casting to an int failed. // Can only happen during CTFE. let ptr = self.ecx.scalar_to_ptr(value); - if lo == 1 && hi == max_hi { + if start == 1 && end == max_value { // Only null is the niche. So make sure the ptr is NOT null. if self.ecx.memory.ptr_may_be_null(ptr) { throw_validation_failure!(self.path, { "a potentially null pointer" } expected { "something that cannot possibly fail to be {}", - wrapping_range_format(valid_range, max_hi) + wrapping_range_format(valid_range, max_value) } ) } @@ -663,7 +661,7 @@ impl<'rt, 'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> ValidityVisitor<'rt, 'mir, ' { "a pointer" } expected { "something that cannot possibly fail to be {}", - wrapping_range_format(valid_range, max_hi) + wrapping_range_format(valid_range, max_value) } ) } @@ -676,7 +674,7 @@ impl<'rt, 'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> ValidityVisitor<'rt, 'mir, ' } else { throw_validation_failure!(self.path, { "{}", bits } - expected { "something {}", wrapping_range_format(valid_range, max_hi) } + expected { "something {}", wrapping_range_format(valid_range, max_value) } ) } } |
