]> git.lizzy.rs Git - rust.git/commitdiff
generalize InvalidNullPointerUsage to InvalidIntPointerUsage
authorRalf Jung <post@ralfj.de>
Sun, 8 Mar 2020 22:28:00 +0000 (23:28 +0100)
committerRalf Jung <post@ralfj.de>
Wed, 11 Mar 2020 18:44:23 +0000 (19:44 +0100)
src/librustc/mir/interpret/allocation.rs
src/librustc/mir/interpret/error.rs
src/librustc_mir/interpret/machine.rs
src/librustc_mir/interpret/memory.rs
src/librustc_mir/interpret/terminator.rs
src/librustc_mir/interpret/validity.rs
src/test/ui/consts/const-eval/ub-wide-ptr.stderr
src/test/ui/error-codes/E0396-fixed.stderr

index 48b26cfd83cd4cd06d6b78437746934e604f2b05..9474f05b55df7e9bbf1d02c86f9ee7acf5aa1fc4 100644 (file)
@@ -41,6 +41,7 @@ pub struct Allocation<Tag = (), Extra = ()> {
     /// The size of the allocation. Currently, must always equal `bytes.len()`.
     pub size: Size,
     /// The alignment of the allocation to detect unaligned reads.
+    /// (`Align` guarantees that this is a power of two.)
     pub align: Align,
     /// `true` if the allocation is mutable.
     /// Also used by codegen to determine if a static should be put into mutable memory,
index f4fe0bc3d3f0f6f88fcde59ce0942f1c2ff8fc06..55112c23ef42870b0c69ee7ecdfafaf0b2fbd765 100644 (file)
@@ -342,8 +342,6 @@ pub enum UndefinedBehaviorInfo {
     UnterminatedCString(Pointer),
     /// Dereferencing a dangling pointer after it got freed.
     PointerUseAfterFree(AllocId),
-    /// Using a NULL pointer in the wrong way.
-    InvalidNullPointerUsage,
     /// Used a pointer outside the bounds it is valid for.
     PointerOutOfBounds {
         ptr: Pointer,
@@ -355,6 +353,8 @@ pub enum UndefinedBehaviorInfo {
         required: Align,
         has: Align,
     },
+    /// Using an integer as a pointer in the wrong way.
+    InvalidIntPointerUsage(u64),
     /// Writing to read-only memory.
     WriteToReadOnly(AllocId),
     /// Using a pointer-not-to-a-function as function pointer.
@@ -401,7 +401,6 @@ fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
             PointerUseAfterFree(a) => {
                 write!(f, "pointer to {:?} was dereferenced after this allocation got freed", a)
             }
-            InvalidNullPointerUsage => write!(f, "invalid use of NULL pointer"),
             PointerOutOfBounds { ptr, msg, allocation_size } => write!(
                 f,
                 "{} failed: pointer must be in-bounds at offset {}, \
@@ -411,6 +410,8 @@ fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
                 ptr.alloc_id,
                 allocation_size.bytes()
             ),
+            InvalidIntPointerUsage(0) => write!(f, "invalid use of NULL pointer"),
+            InvalidIntPointerUsage(i) => write!(f, "invalid use of {} as a pointer", i),
             AlignmentCheckFailed { required, has } => write!(
                 f,
                 "accessing memory with alignment {}, but alignment {} is required",
@@ -450,24 +451,18 @@ fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
 pub enum UnsupportedOpInfo {
     /// Free-form case. Only for errors that are never caught!
     Unsupported(String),
-
     /// When const-prop encounters a situation it does not support, it raises this error.
     /// This must not allocate for performance reasons (hence `str`, not `String`).
     ConstPropUnsupported(&'static str),
-
     /// Accessing an unsupported foreign static.
     ReadForeignStatic(DefId),
-
     /// Could not find MIR for a function.
     NoMirFor(DefId),
-
     /// Modified a static during const-eval.
     /// FIXME: move this to `ConstEvalErrKind` through a machine hook.
     ModifiedStatic,
-
     /// Encountered a pointer where we needed raw bytes.
     ReadPointerAsBytes,
-
     /// Encountered raw bytes where we needed a pointer.
     ReadBytesAsPointer,
 }
index d86ea026ad0dafe5901c4b45903e998227331a4d..b1210a47fd93d07686de1c303b7abebfef9e948b 100644 (file)
@@ -281,8 +281,10 @@ fn int_to_ptr(
         int: u64,
     ) -> InterpResult<'tcx, Pointer<Self::PointerTag>> {
         Err((if int == 0 {
-            err_ub!(InvalidNullPointerUsage)
+            // This is UB, seriously.
+            err_ub!(InvalidIntPointerUsage(0))
         } else {
+            // This is just something we cannot support during const-eval.
             err_unsup!(ReadBytesAsPointer)
         })
         .into())
index 0244a75e8d956dff8d169d81c1efe3ea1ac50777..7099c42ce7ac5cd26c00132f2e63a5f0a89a0eed 100644 (file)
@@ -369,7 +369,7 @@ fn check_offset_align(offset: u64, align: Align) -> InterpResult<'static> {
                 assert!(size.bytes() == 0);
                 // Must be non-NULL.
                 if bits == 0 {
-                    throw_ub!(InvalidNullPointerUsage)
+                    throw_ub!(InvalidIntPointerUsage(0))
                 }
                 // Must be aligned.
                 if let Some(align) = align {
index 51a557851fce280c3382057869f3344570b2cd0e..6fc7355fab38e40521d133c16665faf26f773b0e 100644 (file)
@@ -171,7 +171,7 @@ fn pass_argument(
             return Ok(());
         }
         let caller_arg = caller_arg.next().ok_or_else(|| {
-            err_ub_format!("calling a function passing fewer arguments than it requires")
+            err_ub_format!("calling a function with fewer arguments than it requires")
         })?;
         if rust_abi {
             assert!(!caller_arg.layout.is_zst(), "ZSTs must have been already filtered out");
@@ -341,7 +341,7 @@ fn eval_fn_call(
                     // Now we should have no more caller args
                     if caller_iter.next().is_some() {
                         throw_ub_format!(
-                            "calling a function passing more arguments than it expected"
+                            "calling a function with more arguments than it expected"
                         )
                     }
                     // Don't forget to check the return type!
index 96f44256ff96d871249cdfd13a59b5be8f49ef36..620e4391ad6e4ed0223de48bdbc9ffb58c885c7e 100644 (file)
@@ -353,13 +353,16 @@ fn check_safe_pointer(
                     place.ptr, size, align
                 );
                 match err.kind {
-                    err_ub!(InvalidNullPointerUsage) => {
+                    err_ub!(InvalidIntPointerUsage(0)) => {
                         throw_validation_failure!(format_args!("a NULL {}", kind), self.path)
                     }
+                    err_ub!(InvalidIntPointerUsage(i)) => throw_validation_failure!(
+                        format_args!("a {} to unallocated address {}", kind, i),
+                        self.path
+                    ),
                     err_ub!(AlignmentCheckFailed { required, has }) => throw_validation_failure!(
                         format_args!(
-                            "an unaligned {} \
-                                    (required {} byte alignment but found {})",
+                            "an unaligned {} (required {} byte alignment but found {})",
                             kind,
                             required.bytes(),
                             has.bytes()
@@ -370,12 +373,17 @@ fn check_safe_pointer(
                         format_args!("a dangling {} (created from integer)", kind),
                         self.path
                     ),
-                    err_ub!(PointerOutOfBounds { .. }) | err_ub!(PointerUseAfterFree(_)) => {
-                        throw_validation_failure!(
-                            format_args!("a dangling {} (not entirely in bounds)", kind),
-                            self.path
-                        )
-                    }
+                    err_ub!(PointerOutOfBounds { .. }) => throw_validation_failure!(
+                        format_args!(
+                            "a dangling {} (going beyond the bounds of its allocation)",
+                            kind
+                        ),
+                        self.path
+                    ),
+                    err_ub!(PointerUseAfterFree(_)) => throw_validation_failure!(
+                        format_args!("a dangling {} (use-after-free)", kind),
+                        self.path
+                    ),
                     _ => bug!("Unexpected error during ptr inbounds test: {}", err),
                 }
             }
index cf51b8765fc6945d8fdcee7230a806178f0035ab..80e60dbb58a5d6adf5f74cc191158f2a3b218c36 100644 (file)
@@ -2,7 +2,7 @@ error[E0080]: it is undefined behavior to use this value
   --> $DIR/ub-wide-ptr.rs:32:1
    |
 LL | const STR_TOO_LONG: &str = unsafe { mem::transmute((&42u8, 999usize)) };
-   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ type validation failed: encountered a dangling reference (not entirely in bounds)
+   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ type validation failed: encountered a dangling reference (going beyond the bounds of its allocation)
    |
    = 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.
 
@@ -70,7 +70,7 @@ error[E0080]: it is undefined behavior to use this value
   --> $DIR/ub-wide-ptr.rs:62:1
    |
 LL | const SLICE_TOO_LONG: &[u8] = unsafe { mem::transmute((&42u8, 999usize)) };
-   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ type validation failed: encountered a dangling reference (not entirely in bounds)
+   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ type validation failed: encountered a dangling reference (going beyond the bounds of its allocation)
    |
    = 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.
 
@@ -86,7 +86,7 @@ error[E0080]: it is undefined behavior to use this value
   --> $DIR/ub-wide-ptr.rs:68:1
    |
 LL | const SLICE_TOO_LONG_BOX: Box<[u8]> = unsafe { mem::transmute((&42u8, 999usize)) };
-   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ type validation failed: encountered a dangling box (not entirely in bounds)
+   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ type validation failed: encountered a dangling box (going beyond the bounds of its allocation)
    |
    = 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.
 
index 7222f87da248f32732f3b206a2c103b43b545751..90c8e95e8ebd61476ff474a9be8f4944864ca28c 100644 (file)
@@ -4,7 +4,7 @@ error: any use of this value will cause an error
 LL | const VALUE: u8 = unsafe { *REG_ADDR };
    | ---------------------------^^^^^^^^^---
    |                            |
-   |                            a memory access tried to interpret some bytes as a pointer
+   |                            unable to turn these bytes into a pointer
    |
    = note: `#[deny(const_err)]` on by default