]> git.lizzy.rs Git - rust.git/commitdiff
make eval_libc functions ICE on any problem
authorRalf Jung <post@ralfj.de>
Mon, 12 Dec 2022 07:14:22 +0000 (08:14 +0100)
committerRalf Jung <post@ralfj.de>
Mon, 12 Dec 2022 07:38:07 +0000 (08:38 +0100)
13 files changed:
src/tools/miri/src/helpers.rs
src/tools/miri/src/shims/env.rs
src/tools/miri/src/shims/time.rs
src/tools/miri/src/shims/tls.rs
src/tools/miri/src/shims/unix/foreign_items.rs
src/tools/miri/src/shims/unix/fs.rs
src/tools/miri/src/shims/unix/linux/foreign_items.rs
src/tools/miri/src/shims/unix/linux/sync.rs
src/tools/miri/src/shims/unix/macos/foreign_items.rs
src/tools/miri/src/shims/unix/sync.rs
src/tools/miri/src/shims/unix/thread.rs
src/tools/miri/src/shims/windows/sync.rs
src/tools/miri/src/shims/windows/thread.rs

index 7fb2539ca5a678824649211f3b9bb4b3309467ee..c11c6104c2843474c4a253216daedc471d66ebb0 100644 (file)
@@ -138,55 +138,77 @@ fn resolve_path(&self, path: &[&str], namespace: Namespace) -> ty::Instance<'tcx
             .unwrap_or_else(|| panic!("failed to find required Rust item: {path:?}"))
     }
 
-    /// Evaluates the scalar at the specified path. Returns Some(val)
-    /// if the path could be resolved, and None otherwise
-    fn eval_path_scalar(&self, path: &[&str]) -> InterpResult<'tcx, Scalar<Provenance>> {
+    /// Evaluates the scalar at the specified path.
+    fn eval_path_scalar(&self, path: &[&str]) -> Scalar<Provenance> {
         let this = self.eval_context_ref();
         let instance = this.resolve_path(path, Namespace::ValueNS);
         let cid = GlobalId { instance, promoted: None };
         // We don't give a span -- this isn't actually used directly by the program anyway.
-        let const_val = this.eval_global(cid, None)?;
+        let const_val = this
+            .eval_global(cid, None)
+            .unwrap_or_else(|err| panic!("failed to evaluate required Rust item: {path:?}\n{err}"));
         this.read_scalar(&const_val.into())
+            .unwrap_or_else(|err| panic!("failed to read required Rust item: {path:?}\n{err}"))
     }
 
     /// Helper function to get a `libc` constant as a `Scalar`.
-    fn eval_libc(&self, name: &str) -> InterpResult<'tcx, Scalar<Provenance>> {
+    fn eval_libc(&self, name: &str) -> Scalar<Provenance> {
         self.eval_path_scalar(&["libc", name])
     }
 
     /// Helper function to get a `libc` constant as an `i32`.
-    fn eval_libc_i32(&self, name: &str) -> InterpResult<'tcx, i32> {
+    fn eval_libc_i32(&self, name: &str) -> i32 {
         // TODO: Cache the result.
-        self.eval_libc(name)?.to_i32()
+        self.eval_libc(name).to_i32().unwrap_or_else(|_err| {
+            panic!("required libc item has unexpected type (not `i32`): {name}")
+        })
+    }
+
+    /// Helper function to get a `libc` constant as an `u32`.
+    fn eval_libc_u32(&self, name: &str) -> u32 {
+        // TODO: Cache the result.
+        self.eval_libc(name).to_u32().unwrap_or_else(|_err| {
+            panic!("required libc item has unexpected type (not `u32`): {name}")
+        })
     }
 
     /// Helper function to get a `windows` constant as a `Scalar`.
-    fn eval_windows(&self, module: &str, name: &str) -> InterpResult<'tcx, Scalar<Provenance>> {
+    fn eval_windows(&self, module: &str, name: &str) -> Scalar<Provenance> {
         self.eval_context_ref().eval_path_scalar(&["std", "sys", "windows", module, name])
     }
 
+    /// Helper function to get a `windows` constant as a `u32`.
+    fn eval_windows_u32(&self, module: &str, name: &str) -> u32 {
+        // TODO: Cache the result.
+        self.eval_windows(module, name).to_u32().unwrap_or_else(|_err| {
+            panic!("required Windows item has unexpected type (not `u32`): {module}::{name}")
+        })
+    }
+
     /// Helper function to get a `windows` constant as a `u64`.
-    fn eval_windows_u64(&self, module: &str, name: &str) -> InterpResult<'tcx, u64> {
+    fn eval_windows_u64(&self, module: &str, name: &str) -> u64 {
         // TODO: Cache the result.
-        self.eval_windows(module, name)?.to_u64()
+        self.eval_windows(module, name).to_u64().unwrap_or_else(|_err| {
+            panic!("required Windows item has unexpected type (not `u64`): {module}::{name}")
+        })
     }
 
     /// Helper function to get the `TyAndLayout` of a `libc` type
-    fn libc_ty_layout(&self, name: &str) -> InterpResult<'tcx, TyAndLayout<'tcx>> {
+    fn libc_ty_layout(&self, name: &str) -> TyAndLayout<'tcx> {
         let this = self.eval_context_ref();
         let ty = this
             .resolve_path(&["libc", name], Namespace::TypeNS)
             .ty(*this.tcx, ty::ParamEnv::reveal_all());
-        this.layout_of(ty)
+        this.layout_of(ty).unwrap()
     }
 
     /// Helper function to get the `TyAndLayout` of a `windows` type
-    fn windows_ty_layout(&self, name: &str) -> InterpResult<'tcx, TyAndLayout<'tcx>> {
+    fn windows_ty_layout(&self, name: &str) -> TyAndLayout<'tcx> {
         let this = self.eval_context_ref();
         let ty = this
             .resolve_path(&["std", "sys", "windows", "c", name], Namespace::TypeNS)
             .ty(*this.tcx, ty::ParamEnv::reveal_all());
-        this.layout_of(ty)
+        this.layout_of(ty).unwrap()
     }
 
     /// Project to the given *named* field of the mplace (which must be a struct or union type).
@@ -609,14 +631,14 @@ fn io_error_to_errnum(
         if target.families.iter().any(|f| f == "unix") {
             for &(name, kind) in UNIX_IO_ERROR_TABLE {
                 if err_kind == kind {
-                    return this.eval_libc(name);
+                    return Ok(this.eval_libc(name));
                 }
             }
             throw_unsup_format!("io error {:?} cannot be translated into a raw os error", err_kind)
         } else if target.families.iter().any(|f| f == "windows") {
             // FIXME: we have to finish implementing the Windows equivalent of this.
             use std::io::ErrorKind::*;
-            this.eval_windows(
+            Ok(this.eval_windows(
                 "c",
                 match err_kind {
                     NotFound => "ERROR_FILE_NOT_FOUND",
@@ -627,7 +649,7 @@ fn io_error_to_errnum(
                             err_kind
                         ),
                 },
-            )
+            ))
         } else {
             throw_unsup_format!(
                 "converting io::Error into errnum is unsupported for OS {}",
@@ -647,7 +669,7 @@ fn try_errnum_to_io_error(
         if target.families.iter().any(|f| f == "unix") {
             let errnum = errnum.to_i32()?;
             for &(name, kind) in UNIX_IO_ERROR_TABLE {
-                if errnum == this.eval_libc_i32(name)? {
+                if errnum == this.eval_libc_i32(name) {
                     return Ok(Some(kind));
                 }
             }
index 80fb4ff2fe9802e051d61389f3f90c67978bddce..054162a4ea9f5a06195850b2c685b829b42a19ac 100644 (file)
@@ -170,7 +170,7 @@ fn GetEnvironmentVariableW(
                 ))
             }
             None => {
-                let envvar_not_found = this.eval_windows("c", "ERROR_ENVVAR_NOT_FOUND")?;
+                let envvar_not_found = this.eval_windows("c", "ERROR_ENVVAR_NOT_FOUND");
                 this.set_last_error(envvar_not_found)?;
                 Scalar::from_u32(0) // return zero upon failure
             }
@@ -240,7 +240,7 @@ fn setenv(
             Ok(0) // return zero on success
         } else {
             // name argument is a null pointer, points to an empty string, or points to a string containing an '=' character.
-            let einval = this.eval_libc("EINVAL")?;
+            let einval = this.eval_libc("EINVAL");
             this.set_last_error(einval)?;
             Ok(-1)
         }
@@ -274,7 +274,7 @@ fn SetEnvironmentVariableW(
                 this.deallocate_ptr(var, None, MiriMemoryKind::Runtime.into())?;
                 this.update_environ()?;
             }
-            Ok(this.eval_windows("c", "TRUE")?)
+            Ok(this.eval_windows("c", "TRUE"))
         } else {
             let value = this.read_os_str_from_wide_str(value_ptr)?;
             let var_ptr = alloc_env_var_as_wide_str(&name, &value, this)?;
@@ -282,7 +282,7 @@ fn SetEnvironmentVariableW(
                 this.deallocate_ptr(var, None, MiriMemoryKind::Runtime.into())?;
             }
             this.update_environ()?;
-            Ok(this.eval_windows("c", "TRUE")?)
+            Ok(this.eval_windows("c", "TRUE"))
         }
     }
 
@@ -306,7 +306,7 @@ fn unsetenv(&mut self, name_op: &OpTy<'tcx, Provenance>) -> InterpResult<'tcx, i
             Ok(0)
         } else {
             // name argument is a null pointer, points to an empty string, or points to a string containing an '=' character.
-            let einval = this.eval_libc("EINVAL")?;
+            let einval = this.eval_libc("EINVAL");
             this.set_last_error(einval)?;
             Ok(-1)
         }
@@ -335,7 +335,7 @@ fn getcwd(
                 if this.write_path_to_c_str(&cwd, buf, size)?.0 {
                     return Ok(buf);
                 }
-                let erange = this.eval_libc("ERANGE")?;
+                let erange = this.eval_libc("ERANGE");
                 this.set_last_error(erange)?;
             }
             Err(e) => this.set_last_error_from_io_error(e.kind())?,
@@ -411,14 +411,14 @@ fn SetCurrentDirectoryW(
             this.reject_in_isolation("`SetCurrentDirectoryW`", reject_with)?;
             this.set_last_error_from_io_error(ErrorKind::PermissionDenied)?;
 
-            return this.eval_windows("c", "FALSE");
+            return Ok(this.eval_windows("c", "FALSE"));
         }
 
         match env::set_current_dir(path) {
-            Ok(()) => this.eval_windows("c", "TRUE"),
+            Ok(()) => Ok(this.eval_windows("c", "TRUE")),
             Err(e) => {
                 this.set_last_error_from_io_error(e.kind())?;
-                this.eval_windows("c", "FALSE")
+                Ok(this.eval_windows("c", "FALSE"))
             }
         }
     }
index d263aab351b12e07591210cc85ede4bc60c461c0..ef411eb8aa7248bfe0c2028dcdac42b66e44b63b 100644 (file)
@@ -36,26 +36,26 @@ fn clock_gettime(
                 // Linux further distinguishes regular and "coarse" clocks, but the "coarse" version
                 // is just specified to be "faster and less precise", so we implement both the same way.
                 absolute_clocks = vec![
-                    this.eval_libc_i32("CLOCK_REALTIME")?,
-                    this.eval_libc_i32("CLOCK_REALTIME_COARSE")?,
+                    this.eval_libc_i32("CLOCK_REALTIME"),
+                    this.eval_libc_i32("CLOCK_REALTIME_COARSE"),
                 ];
                 // The second kind is MONOTONIC clocks for which 0 is an arbitrary time point, but they are
                 // never allowed to go backwards. We don't need to do any additonal monotonicity
                 // enforcement because std::time::Instant already guarantees that it is monotonic.
                 relative_clocks = vec![
-                    this.eval_libc_i32("CLOCK_MONOTONIC")?,
-                    this.eval_libc_i32("CLOCK_MONOTONIC_COARSE")?,
+                    this.eval_libc_i32("CLOCK_MONOTONIC"),
+                    this.eval_libc_i32("CLOCK_MONOTONIC_COARSE"),
                 ];
             }
             "macos" => {
-                absolute_clocks = vec![this.eval_libc_i32("CLOCK_REALTIME")?];
-                relative_clocks = vec![this.eval_libc_i32("CLOCK_MONOTONIC")?];
+                absolute_clocks = vec![this.eval_libc_i32("CLOCK_REALTIME")];
+                relative_clocks = vec![this.eval_libc_i32("CLOCK_MONOTONIC")];
                 // Some clocks only seem to exist in the aarch64 version of the target.
                 if this.tcx.sess.target.arch == "aarch64" {
                     // `CLOCK_UPTIME_RAW` supposed to not increment while the system is asleep... but
                     // that's not really something a program running inside Miri can tell, anyway.
                     // We need to support it because std uses it.
-                    relative_clocks.push(this.eval_libc_i32("CLOCK_UPTIME_RAW")?);
+                    relative_clocks.push(this.eval_libc_i32("CLOCK_UPTIME_RAW"));
                 }
             }
             target => throw_unsup_format!("`clock_gettime` is not supported on target OS {target}"),
@@ -68,7 +68,7 @@ fn clock_gettime(
             this.machine.clock.now().duration_since(this.machine.clock.anchor())
         } else {
             // Unsupported clock.
-            let einval = this.eval_libc("EINVAL")?;
+            let einval = this.eval_libc("EINVAL");
             this.set_last_error(einval)?;
             return Ok(Scalar::from_i32(-1));
         };
@@ -94,7 +94,7 @@ fn gettimeofday(
         // Using tz is obsolete and should always be null
         let tz = this.read_pointer(tz_op)?;
         if !this.ptr_is_null(tz)? {
-            let einval = this.eval_libc("EINVAL")?;
+            let einval = this.eval_libc("EINVAL");
             this.set_last_error(einval)?;
             return Ok(-1);
         }
@@ -118,9 +118,9 @@ fn GetSystemTimeAsFileTime(
         this.assert_target_os("windows", "GetSystemTimeAsFileTime");
         this.check_no_isolation("`GetSystemTimeAsFileTime`")?;
 
-        let NANOS_PER_SEC = this.eval_windows_u64("time", "NANOS_PER_SEC")?;
-        let INTERVALS_PER_SEC = this.eval_windows_u64("time", "INTERVALS_PER_SEC")?;
-        let INTERVALS_TO_UNIX_EPOCH = this.eval_windows_u64("time", "INTERVALS_TO_UNIX_EPOCH")?;
+        let NANOS_PER_SEC = this.eval_windows_u64("time", "NANOS_PER_SEC");
+        let INTERVALS_PER_SEC = this.eval_windows_u64("time", "INTERVALS_PER_SEC");
+        let INTERVALS_TO_UNIX_EPOCH = this.eval_windows_u64("time", "INTERVALS_TO_UNIX_EPOCH");
         let NANOS_PER_INTERVAL = NANOS_PER_SEC / INTERVALS_PER_SEC;
         let SECONDS_TO_UNIX_EPOCH = INTERVALS_TO_UNIX_EPOCH / INTERVALS_PER_SEC;
 
@@ -226,7 +226,7 @@ fn nanosleep(
         let duration = match this.read_timespec(&this.deref_operand(req_op)?)? {
             Some(duration) => duration,
             None => {
-                let einval = this.eval_libc("EINVAL")?;
+                let einval = this.eval_libc("EINVAL");
                 this.set_last_error(einval)?;
                 return Ok(-1);
             }
index 54fdf2872ab4d3967c594fba3d30def27840b96f..7768772338a777b73d709b1dbd68985435ee1643 100644 (file)
@@ -303,12 +303,12 @@ fn schedule_windows_tls_dtors(&mut self) -> InterpResult<'tcx> {
             return Ok(());
         }
         let thread_callback =
-            this.eval_windows("thread_local_key", "p_thread_callback")?.to_pointer(this)?;
+            this.eval_windows("thread_local_key", "p_thread_callback").to_pointer(this)?;
         let thread_callback = this.get_ptr_fn(thread_callback)?.as_instance()?;
 
         // FIXME: Technically, the reason should be `DLL_PROCESS_DETACH` when the main thread exits
         // but std treats both the same.
-        let reason = this.eval_windows("c", "DLL_THREAD_DETACH")?;
+        let reason = this.eval_windows("c", "DLL_THREAD_DETACH");
 
         // The signature of this function is `unsafe extern "system" fn(h: c::LPVOID, dwReason: c::DWORD, pv: c::LPVOID)`.
         // FIXME: `h` should be a handle to the current module and what `pv` should be is unknown
index e851d6d5139ce5a666e23ae54003d95f51c18aa1..f155e11241b7015673fdf1842dea9436e8926dfb 100644 (file)
@@ -196,7 +196,7 @@ fn emulate_foreign_item_by_name(
                 // Align must be power of 2, and also at least ptr-sized (POSIX rules).
                 // But failure to adhere to this is not UB, it's an error condition.
                 if !align.is_power_of_two() || align < this.pointer_size().bytes() {
-                    let einval = this.eval_libc_i32("EINVAL")?;
+                    let einval = this.eval_libc_i32("EINVAL");
                     this.write_int(einval, dest)?;
                 } else {
                     if size == 0 {
@@ -243,7 +243,7 @@ fn emulate_foreign_item_by_name(
                 ];
                 let mut result = None;
                 for &(sysconf_name, value) in sysconfs {
-                    let sysconf_name = this.eval_libc_i32(sysconf_name)?;
+                    let sysconf_name = this.eval_libc_i32(sysconf_name);
                     if sysconf_name == name {
                         result = Some(value(this));
                         break;
@@ -480,7 +480,7 @@ fn emulate_foreign_item_by_name(
                     None => format!("<unknown errnum in strerror_r: {errnum}>"),
                 };
                 let (complete, _) = this.write_os_str_to_c_str(OsStr::new(&formatted), buf, buflen)?;
-                let ret = if complete { 0 } else { this.eval_libc_i32("ERANGE")? };
+                let ret = if complete { 0 } else { this.eval_libc_i32("ERANGE") };
                 this.write_int(ret, dest)?;
             }
             "getpid" => {
@@ -495,7 +495,7 @@ fn emulate_foreign_item_by_name(
             if this.frame_in_std() => {
                 let [_attr, guard_size] = this.check_shim(abi, Abi::C { unwind: false }, link_name, args)?;
                 let guard_size = this.deref_operand(guard_size)?;
-                let guard_size_layout = this.libc_ty_layout("size_t")?;
+                let guard_size_layout = this.libc_ty_layout("size_t");
                 this.write_scalar(Scalar::from_uint(this.machine.page_size, guard_size_layout.size), &guard_size.into())?;
 
                 // Return success (`0`).
@@ -589,7 +589,7 @@ fn emulate_foreign_item_by_name(
                     this.write_null(dest)?;
                 } else {
                     this.write_null(&result.into())?;
-                    this.write_scalar(this.eval_libc("ERANGE")?, dest)?;
+                    this.write_scalar(this.eval_libc("ERANGE"), dest)?;
                 }
             }
 
index 0a26657f57c85cc921db96efbedecdf1fe03842f..22fbd940e71266a87db977b361adc1cc4624daa1 100644 (file)
@@ -382,7 +382,7 @@ fn macos_stat_write_buf(
     /// types (like `read`, that returns an `i64`).
     fn handle_not_found<T: From<i32>>(&mut self) -> InterpResult<'tcx, T> {
         let this = self.eval_context_mut();
-        let ebadf = this.eval_libc("EBADF")?;
+        let ebadf = this.eval_libc("EBADF");
         this.set_last_error(ebadf)?;
         Ok((-1).into())
     }
@@ -395,11 +395,11 @@ fn file_type_to_d_type(
         match file_type {
             Ok(file_type) => {
                 if file_type.is_dir() {
-                    Ok(this.eval_libc("DT_DIR")?.to_u8()?.into())
+                    Ok(this.eval_libc("DT_DIR").to_u8()?.into())
                 } else if file_type.is_file() {
-                    Ok(this.eval_libc("DT_REG")?.to_u8()?.into())
+                    Ok(this.eval_libc("DT_REG").to_u8()?.into())
                 } else if file_type.is_symlink() {
-                    Ok(this.eval_libc("DT_LNK")?.to_u8()?.into())
+                    Ok(this.eval_libc("DT_LNK").to_u8()?.into())
                 } else {
                     // Certain file types are only supported when the host is a Unix system.
                     // (i.e. devices and sockets) If it is, check those cases, if not, fall back to
@@ -409,19 +409,19 @@ fn file_type_to_d_type(
                     {
                         use std::os::unix::fs::FileTypeExt;
                         if file_type.is_block_device() {
-                            Ok(this.eval_libc("DT_BLK")?.to_u8()?.into())
+                            Ok(this.eval_libc("DT_BLK").to_u8()?.into())
                         } else if file_type.is_char_device() {
-                            Ok(this.eval_libc("DT_CHR")?.to_u8()?.into())
+                            Ok(this.eval_libc("DT_CHR").to_u8()?.into())
                         } else if file_type.is_fifo() {
-                            Ok(this.eval_libc("DT_FIFO")?.to_u8()?.into())
+                            Ok(this.eval_libc("DT_FIFO").to_u8()?.into())
                         } else if file_type.is_socket() {
-                            Ok(this.eval_libc("DT_SOCK")?.to_u8()?.into())
+                            Ok(this.eval_libc("DT_SOCK").to_u8()?.into())
                         } else {
-                            Ok(this.eval_libc("DT_UNKNOWN")?.to_u8()?.into())
+                            Ok(this.eval_libc("DT_UNKNOWN").to_u8()?.into())
                         }
                     }
                     #[cfg(not(unix))]
-                    Ok(this.eval_libc("DT_UNKNOWN")?.to_u8()?.into())
+                    Ok(this.eval_libc("DT_UNKNOWN").to_u8()?.into())
                 }
             }
             Err(e) =>
@@ -532,9 +532,9 @@ fn open(&mut self, args: &[OpTy<'tcx, Provenance>]) -> InterpResult<'tcx, i32> {
 
         let mut options = OpenOptions::new();
 
-        let o_rdonly = this.eval_libc_i32("O_RDONLY")?;
-        let o_wronly = this.eval_libc_i32("O_WRONLY")?;
-        let o_rdwr = this.eval_libc_i32("O_RDWR")?;
+        let o_rdonly = this.eval_libc_i32("O_RDONLY");
+        let o_wronly = this.eval_libc_i32("O_WRONLY");
+        let o_rdwr = this.eval_libc_i32("O_RDWR");
         // The first two bits of the flag correspond to the access mode in linux, macOS and
         // windows. We need to check that in fact the access mode flags for the current target
         // only use these two bits, otherwise we are in an unsupported target and should error.
@@ -561,17 +561,17 @@ fn open(&mut self, args: &[OpTy<'tcx, Provenance>]) -> InterpResult<'tcx, i32> {
         // options.
         let mut mirror = access_mode;
 
-        let o_append = this.eval_libc_i32("O_APPEND")?;
+        let o_append = this.eval_libc_i32("O_APPEND");
         if flag & o_append == o_append {
             options.append(true);
             mirror |= o_append;
         }
-        let o_trunc = this.eval_libc_i32("O_TRUNC")?;
+        let o_trunc = this.eval_libc_i32("O_TRUNC");
         if flag & o_trunc == o_trunc {
             options.truncate(true);
             mirror |= o_trunc;
         }
-        let o_creat = this.eval_libc_i32("O_CREAT")?;
+        let o_creat = this.eval_libc_i32("O_CREAT");
         if flag & o_creat == o_creat {
             // Get the mode.  On macOS, the argument type `mode_t` is actually `u16`, but
             // C integer promotion rules mean that on the ABI level, it gets passed as `u32`
@@ -591,7 +591,7 @@ fn open(&mut self, args: &[OpTy<'tcx, Provenance>]) -> InterpResult<'tcx, i32> {
 
             mirror |= o_creat;
 
-            let o_excl = this.eval_libc_i32("O_EXCL")?;
+            let o_excl = this.eval_libc_i32("O_EXCL");
             if flag & o_excl == o_excl {
                 mirror |= o_excl;
                 options.create_new(true);
@@ -599,17 +599,17 @@ fn open(&mut self, args: &[OpTy<'tcx, Provenance>]) -> InterpResult<'tcx, i32> {
                 options.create(true);
             }
         }
-        let o_cloexec = this.eval_libc_i32("O_CLOEXEC")?;
+        let o_cloexec = this.eval_libc_i32("O_CLOEXEC");
         if flag & o_cloexec == o_cloexec {
             // We do not need to do anything for this flag because `std` already sets it.
             // (Technically we do not support *not* setting this flag, but we ignore that.)
             mirror |= o_cloexec;
         }
         if this.tcx.sess.target.os == "linux" {
-            let o_tmpfile = this.eval_libc_i32("O_TMPFILE")?;
+            let o_tmpfile = this.eval_libc_i32("O_TMPFILE");
             if flag & o_tmpfile == o_tmpfile {
                 // if the flag contains `O_TMPFILE` then we return a graceful error
-                let eopnotsupp = this.eval_libc("EOPNOTSUPP")?;
+                let eopnotsupp = this.eval_libc("EOPNOTSUPP");
                 this.set_last_error(eopnotsupp)?;
                 return Ok(-1);
             }
@@ -657,18 +657,18 @@ fn fcntl(&mut self, args: &[OpTy<'tcx, Provenance>]) -> InterpResult<'tcx, i32>
         }
 
         // We only support getting the flags for a descriptor.
-        if cmd == this.eval_libc_i32("F_GETFD")? {
+        if cmd == this.eval_libc_i32("F_GETFD") {
             // Currently this is the only flag that `F_GETFD` returns. It is OK to just return the
             // `FD_CLOEXEC` value without checking if the flag is set for the file because `std`
             // always sets this flag when opening a file. However we still need to check that the
             // file itself is open.
             if this.machine.file_handler.handles.contains_key(&fd) {
-                Ok(this.eval_libc_i32("FD_CLOEXEC")?)
+                Ok(this.eval_libc_i32("FD_CLOEXEC"))
             } else {
                 this.handle_not_found()
             }
-        } else if cmd == this.eval_libc_i32("F_DUPFD")?
-            || cmd == this.eval_libc_i32("F_DUPFD_CLOEXEC")?
+        } else if cmd == this.eval_libc_i32("F_DUPFD")
+            || cmd == this.eval_libc_i32("F_DUPFD_CLOEXEC")
         {
             // Note that we always assume the FD_CLOEXEC flag is set for every open file, in part
             // because exec() isn't supported. The F_DUPFD and F_DUPFD_CLOEXEC commands only
@@ -697,7 +697,7 @@ fn fcntl(&mut self, args: &[OpTy<'tcx, Provenance>]) -> InterpResult<'tcx, i32>
                 }
                 None => this.handle_not_found(),
             }
-        } else if this.tcx.sess.target.os == "macos" && cmd == this.eval_libc_i32("F_FULLFSYNC")? {
+        } else if this.tcx.sess.target.os == "macos" && cmd == this.eval_libc_i32("F_FULLFSYNC") {
             if let Some(file_descriptor) = this.machine.file_handler.handles.get(&fd) {
                 // FIXME: Support fullfsync for all FDs
                 let FileHandle { file, writable } = file_descriptor.as_file_handle()?;
@@ -830,14 +830,14 @@ fn lseek64(
         let offset = this.read_scalar(offset_op)?.to_i64()?;
         let whence = this.read_scalar(whence_op)?.to_i32()?;
 
-        let seek_from = if whence == this.eval_libc_i32("SEEK_SET")? {
+        let seek_from = if whence == this.eval_libc_i32("SEEK_SET") {
             SeekFrom::Start(u64::try_from(offset).unwrap())
-        } else if whence == this.eval_libc_i32("SEEK_CUR")? {
+        } else if whence == this.eval_libc_i32("SEEK_CUR") {
             SeekFrom::Current(offset)
-        } else if whence == this.eval_libc_i32("SEEK_END")? {
+        } else if whence == this.eval_libc_i32("SEEK_END") {
             SeekFrom::End(offset)
         } else {
-            let einval = this.eval_libc("EINVAL")?;
+            let einval = this.eval_libc("EINVAL");
             this.set_last_error(einval)?;
             return Ok(Scalar::from_i64(-1));
         };
@@ -916,7 +916,7 @@ fn macos_stat(
         // Reject if isolation is enabled.
         if let IsolatedOp::Reject(reject_with) = this.machine.isolated_op {
             this.reject_in_isolation("`stat`", reject_with)?;
-            let eacc = this.eval_libc("EACCES")?;
+            let eacc = this.eval_libc("EACCES");
             this.set_last_error(eacc)?;
             return Ok(Scalar::from_i32(-1));
         }
@@ -945,7 +945,7 @@ fn macos_lstat(
         // Reject if isolation is enabled.
         if let IsolatedOp::Reject(reject_with) = this.machine.isolated_op {
             this.reject_in_isolation("`lstat`", reject_with)?;
-            let eacc = this.eval_libc("EACCES")?;
+            let eacc = this.eval_libc("EACCES");
             this.set_last_error(eacc)?;
             return Ok(Scalar::from_i32(-1));
         }
@@ -1003,7 +1003,7 @@ fn linux_statx(
 
         // If the statxbuf or pathname pointers are null, the function fails with `EFAULT`.
         if this.ptr_is_null(statxbuf_ptr)? || this.ptr_is_null(pathname_ptr)? {
-            let efault = this.eval_libc("EFAULT")?;
+            let efault = this.eval_libc("EFAULT");
             this.set_last_error(efault)?;
             return Ok(-1);
         }
@@ -1014,13 +1014,13 @@ fn linux_statx(
         // as `isize`s instead of having the proper types. Thus, we have to recover the layout of
         // `statxbuf_op` by using the `libc::statx` struct type.
         let statxbuf = {
-            let statx_layout = this.libc_ty_layout("statx")?;
+            let statx_layout = this.libc_ty_layout("statx");
             MPlaceTy::from_aligned_ptr(statxbuf_ptr, statx_layout)
         };
 
         let path = this.read_path_from_c_str(pathname_ptr)?.into_owned();
         // See <https://github.com/rust-lang/rust/pull/79196> for a discussion of argument sizes.
-        let at_ampty_path = this.eval_libc_i32("AT_EMPTY_PATH")?;
+        let at_ampty_path = this.eval_libc_i32("AT_EMPTY_PATH");
         let empty_path_flag = flags & at_ampty_path == at_ampty_path;
         // We only support:
         // * interpreting `path` as an absolute directory,
@@ -1030,7 +1030,7 @@ fn linux_statx(
         // Other behaviors cannot be tested from `libstd` and thus are not implemented. If you
         // found this error, please open an issue reporting it.
         if !(path.is_absolute()
-            || dirfd == this.eval_libc_i32("AT_FDCWD")?
+            || dirfd == this.eval_libc_i32("AT_FDCWD")
             || (path.as_os_str().is_empty() && empty_path_flag))
         {
             throw_unsup_format!(
@@ -1043,16 +1043,16 @@ fn linux_statx(
         // Reject if isolation is enabled.
         if let IsolatedOp::Reject(reject_with) = this.machine.isolated_op {
             this.reject_in_isolation("`statx`", reject_with)?;
-            let ecode = if path.is_absolute() || dirfd == this.eval_libc_i32("AT_FDCWD")? {
+            let ecode = if path.is_absolute() || dirfd == this.eval_libc_i32("AT_FDCWD") {
                 // since `path` is provided, either absolute or
                 // relative to CWD, `EACCES` is the most relevant.
-                this.eval_libc("EACCES")?
+                this.eval_libc("EACCES")
             } else {
                 // `dirfd` is set to target file, and `path` is empty
                 // (or we would have hit the `throw_unsup_format`
                 // above). `EACCES` would violate the spec.
                 assert!(empty_path_flag);
-                this.eval_libc("EBADF")?
+                this.eval_libc("EBADF")
             };
             this.set_last_error(ecode)?;
             return Ok(-1);
@@ -1062,12 +1062,11 @@ fn linux_statx(
         // However `statx` is allowed to return information that was not requested or to not
         // return information that was requested. This `mask` represents the information we can
         // actually provide for any target.
-        let mut mask =
-            this.eval_libc("STATX_TYPE")?.to_u32()? | this.eval_libc("STATX_SIZE")?.to_u32()?;
+        let mut mask = this.eval_libc_u32("STATX_TYPE") | this.eval_libc_u32("STATX_SIZE");
 
         // If the `AT_SYMLINK_NOFOLLOW` flag is set, we query the file's metadata without following
         // symbolic links.
-        let follow_symlink = flags & this.eval_libc("AT_SYMLINK_NOFOLLOW")?.to_i32()? == 0;
+        let follow_symlink = flags & this.eval_libc_i32("AT_SYMLINK_NOFOLLOW") == 0;
 
         // If the path is empty, and the AT_EMPTY_PATH flag is set, we query the open file
         // represented by dirfd, whether it's a directory or otherwise.
@@ -1096,7 +1095,7 @@ fn linux_statx(
         let (access_sec, access_nsec) = metadata
             .accessed
             .map(|tup| {
-                mask |= this.eval_libc("STATX_ATIME")?.to_u32()?;
+                mask |= this.eval_libc_u32("STATX_ATIME");
                 InterpResult::Ok(tup)
             })
             .unwrap_or_else(|| Ok((0, 0)))?;
@@ -1104,7 +1103,7 @@ fn linux_statx(
         let (created_sec, created_nsec) = metadata
             .created
             .map(|tup| {
-                mask |= this.eval_libc("STATX_BTIME")?.to_u32()?;
+                mask |= this.eval_libc_u32("STATX_BTIME");
                 InterpResult::Ok(tup)
             })
             .unwrap_or_else(|| Ok((0, 0)))?;
@@ -1112,7 +1111,7 @@ fn linux_statx(
         let (modified_sec, modified_nsec) = metadata
             .modified
             .map(|tup| {
-                mask |= this.eval_libc("STATX_MTIME")?.to_u32()?;
+                mask |= this.eval_libc_u32("STATX_MTIME");
                 InterpResult::Ok(tup)
             })
             .unwrap_or_else(|| Ok((0, 0)))?;
@@ -1185,7 +1184,7 @@ fn rename(
         let newpath_ptr = this.read_pointer(newpath_op)?;
 
         if this.ptr_is_null(oldpath_ptr)? || this.ptr_is_null(newpath_ptr)? {
-            let efault = this.eval_libc("EFAULT")?;
+            let efault = this.eval_libc("EFAULT");
             this.set_last_error(efault)?;
             return Ok(-1);
         }
@@ -1272,7 +1271,7 @@ fn opendir(
         // Reject if isolation is enabled.
         if let IsolatedOp::Reject(reject_with) = this.machine.isolated_op {
             this.reject_in_isolation("`opendir`", reject_with)?;
-            let eacc = this.eval_libc("EACCES")?;
+            let eacc = this.eval_libc("EACCES");
             this.set_last_error(eacc)?;
             return Ok(Scalar::null_ptr(this));
         }
@@ -1308,7 +1307,7 @@ fn linux_readdir64(
         // Reject if isolation is enabled.
         if let IsolatedOp::Reject(reject_with) = this.machine.isolated_op {
             this.reject_in_isolation("`readdir`", reject_with)?;
-            let eacc = this.eval_libc("EBADF")?;
+            let eacc = this.eval_libc("EBADF");
             this.set_last_error(eacc)?;
             return Ok(Scalar::null_ptr(this));
         }
@@ -1337,7 +1336,7 @@ fn linux_readdir64(
                 let name_bytes = os_str_to_bytes(&name)?;
                 let name_len = u64::try_from(name_bytes.len()).unwrap();
 
-                let dirent64_layout = this.libc_ty_layout("dirent64")?;
+                let dirent64_layout = this.libc_ty_layout("dirent64");
                 let d_name_offset = dirent64_layout.fields.offset(4 /* d_name */).bytes();
                 let size = d_name_offset.checked_add(name_len).unwrap();
 
@@ -1532,13 +1531,13 @@ fn ftruncate64(
                         let result = file.set_len(length);
                         this.try_unwrap_io_result(result.map(|_| 0i32))?
                     } else {
-                        let einval = this.eval_libc("EINVAL")?;
+                        let einval = this.eval_libc("EINVAL");
                         this.set_last_error(einval)?;
                         -1
                     }
                 } else {
                     // The file is not writable
-                    let einval = this.eval_libc("EINVAL")?;
+                    let einval = this.eval_libc("EINVAL");
                     this.set_last_error(einval)?;
                     -1
                 }
@@ -1612,15 +1611,15 @@ fn sync_file_range(
         let flags = this.read_scalar(flags_op)?.to_i32()?;
 
         if offset < 0 || nbytes < 0 {
-            let einval = this.eval_libc("EINVAL")?;
+            let einval = this.eval_libc("EINVAL");
             this.set_last_error(einval)?;
             return Ok(Scalar::from_i32(-1));
         }
-        let allowed_flags = this.eval_libc_i32("SYNC_FILE_RANGE_WAIT_BEFORE")?
-            | this.eval_libc_i32("SYNC_FILE_RANGE_WRITE")?
-            | this.eval_libc_i32("SYNC_FILE_RANGE_WAIT_AFTER")?;
+        let allowed_flags = this.eval_libc_i32("SYNC_FILE_RANGE_WAIT_BEFORE")
+            | this.eval_libc_i32("SYNC_FILE_RANGE_WRITE")
+            | this.eval_libc_i32("SYNC_FILE_RANGE_WAIT_AFTER");
         if flags & allowed_flags != flags {
-            let einval = this.eval_libc("EINVAL")?;
+            let einval = this.eval_libc("EINVAL");
             this.set_last_error(einval)?;
             return Ok(Scalar::from_i32(-1));
         }
@@ -1657,7 +1656,7 @@ fn readlink(
         // Reject if isolation is enabled.
         if let IsolatedOp::Reject(reject_with) = this.machine.isolated_op {
             this.reject_in_isolation("`readlink`", reject_with)?;
-            let eacc = this.eval_libc("EACCES")?;
+            let eacc = this.eval_libc("EACCES");
             this.set_last_error(eacc)?;
             return Ok(-1);
         }
@@ -1702,7 +1701,7 @@ fn isatty(
             }
         }
         // Fallback when the FD was not found or isolation is enabled.
-        let enotty = this.eval_libc("ENOTTY")?;
+        let enotty = this.eval_libc("ENOTTY");
         this.set_last_error(enotty)?;
         Ok(Scalar::from_i32(0))
     }
@@ -1721,7 +1720,7 @@ fn realpath(
         // Reject if isolation is enabled.
         if let IsolatedOp::Reject(reject_with) = this.machine.isolated_op {
             this.reject_in_isolation("`realpath`", reject_with)?;
-            let eacc = this.eval_libc("EACCES")?;
+            let eacc = this.eval_libc("EACCES");
             this.set_last_error(eacc)?;
             return Ok(Scalar::from_machine_usize(0, this));
         }
@@ -1730,7 +1729,7 @@ fn realpath(
         match result {
             Ok(resolved) => {
                 let path_max = this
-                    .eval_libc_i32("PATH_MAX")?
+                    .eval_libc_i32("PATH_MAX")
                     .try_into()
                     .expect("PATH_MAX does not fit in u64");
                 let dest = if this.ptr_is_null(processed_ptr)? {
@@ -1752,7 +1751,7 @@ fn realpath(
                         // Note that we do not explicitly handle `FILENAME_MAX`
                         // (different from `PATH_MAX` above) as it is Linux-specific and
                         // seems like a bit of a mess anyway: <https://eklitzke.org/path-max-is-tricky>.
-                        let enametoolong = this.eval_libc("ENAMETOOLONG")?;
+                        let enametoolong = this.eval_libc("ENAMETOOLONG");
                         this.set_last_error(enametoolong)?;
                         return Ok(Scalar::from_machine_usize(0, this));
                     }
@@ -1785,7 +1784,7 @@ fn mkstemp(&mut self, template_op: &OpTy<'tcx, Provenance>) -> InterpResult<'tcx
         //   * The value of `TMP_MAX` is at least 25.
         //   * On XSI-conformant systems, the value of `TMP_MAX` is at least 10000.
         // See <https://pubs.opengroup.org/onlinepubs/9699919799/basedefs/stdio.h.html>.
-        let max_attempts = this.eval_libc("TMP_MAX")?.to_u32()?;
+        let max_attempts = this.eval_libc_u32("TMP_MAX");
 
         // Get the raw bytes from the template -- as a byte slice, this is a string in the target
         // (and the target is unix, so a byte slice is the right representation).
@@ -1796,7 +1795,7 @@ fn mkstemp(&mut self, template_op: &OpTy<'tcx, Provenance>) -> InterpResult<'tcx
         // Reject if isolation is enabled.
         if let IsolatedOp::Reject(reject_with) = this.machine.isolated_op {
             this.reject_in_isolation("`mkstemp`", reject_with)?;
-            let eacc = this.eval_libc("EACCES")?;
+            let eacc = this.eval_libc("EACCES");
             this.set_last_error(eacc)?;
             return Ok(-1);
         }
@@ -1814,7 +1813,7 @@ fn mkstemp(&mut self, template_op: &OpTy<'tcx, Provenance>) -> InterpResult<'tcx
 
         // If we don't find the suffix, it is an error.
         if last_six_char_bytes != suffix_bytes {
-            let einval = this.eval_libc("EINVAL")?;
+            let einval = this.eval_libc("EINVAL");
             this.set_last_error(einval)?;
             return Ok(-1);
         }
@@ -1890,7 +1889,7 @@ fn mkstemp(&mut self, template_op: &OpTy<'tcx, Provenance>) -> InterpResult<'tcx
         }
 
         // We ran out of attempts to create the file, return an error.
-        let eexist = this.eval_libc("EEXIST")?;
+        let eexist = this.eval_libc("EEXIST");
         this.set_last_error(eexist)?;
         Ok(-1)
     }
@@ -1968,7 +1967,7 @@ fn from_meta<'tcx>(
             "S_IFLNK"
         };
 
-        let mode = ecx.eval_libc(mode_name)?;
+        let mode = ecx.eval_libc(mode_name);
 
         let size = metadata.len();
 
index 34076e842d55b51226df6ddfcf1ce6f1dc3f450b..ff7b2b352f2d17d0fb36c088ae24b5d35d081ca0 100644 (file)
@@ -88,11 +88,11 @@ fn emulate_foreign_item_by_name(
                 // argument, we have to also check all arguments *before* it to ensure that they
                 // have the right type.
 
-                let sys_getrandom = this.eval_libc("SYS_getrandom")?.to_machine_usize(this)?;
+                let sys_getrandom = this.eval_libc("SYS_getrandom").to_machine_usize(this)?;
 
-                let sys_statx = this.eval_libc("SYS_statx")?.to_machine_usize(this)?;
+                let sys_statx = this.eval_libc("SYS_statx").to_machine_usize(this)?;
 
-                let sys_futex = this.eval_libc("SYS_futex")?.to_machine_usize(this)?;
+                let sys_futex = this.eval_libc("SYS_futex").to_machine_usize(this)?;
 
                 if args.is_empty() {
                     throw_ub_format!(
@@ -150,7 +150,7 @@ fn emulate_foreign_item_by_name(
                 this.read_scalar(cpusetsize)?.to_machine_usize(this)?;
                 this.deref_operand(mask)?;
                 // FIXME: we just return an error; `num_cpus` then falls back to `sysconf`.
-                let einval = this.eval_libc("EINVAL")?;
+                let einval = this.eval_libc("EINVAL");
                 this.set_last_error(einval)?;
                 this.write_scalar(Scalar::from_i32(-1), dest)?;
             }
index 31461e4c9fd384d23e2efd761a993108f665a1c4..ef43c9b0ff438bca79b8e543d0f8fbfa05357407 100644 (file)
@@ -37,12 +37,12 @@ pub fn futex<'tcx>(
     let addr = MPlaceTy::from_aligned_ptr(addr, this.machine.layouts.i32);
     let addr_usize = addr.ptr.addr().bytes();
 
-    let futex_private = this.eval_libc_i32("FUTEX_PRIVATE_FLAG")?;
-    let futex_wait = this.eval_libc_i32("FUTEX_WAIT")?;
-    let futex_wait_bitset = this.eval_libc_i32("FUTEX_WAIT_BITSET")?;
-    let futex_wake = this.eval_libc_i32("FUTEX_WAKE")?;
-    let futex_wake_bitset = this.eval_libc_i32("FUTEX_WAKE_BITSET")?;
-    let futex_realtime = this.eval_libc_i32("FUTEX_CLOCK_REALTIME")?;
+    let futex_private = this.eval_libc_i32("FUTEX_PRIVATE_FLAG");
+    let futex_wait = this.eval_libc_i32("FUTEX_WAIT");
+    let futex_wait_bitset = this.eval_libc_i32("FUTEX_WAIT_BITSET");
+    let futex_wake = this.eval_libc_i32("FUTEX_WAKE");
+    let futex_wake_bitset = this.eval_libc_i32("FUTEX_WAKE_BITSET");
+    let futex_realtime = this.eval_libc_i32("FUTEX_CLOCK_REALTIME");
 
     // FUTEX_PRIVATE enables an optimization that stops it from working across processes.
     // Miri doesn't support that anyway, so we ignore that flag.
@@ -79,7 +79,7 @@ pub fn futex<'tcx>(
             };
 
             if bitset == 0 {
-                let einval = this.eval_libc("EINVAL")?;
+                let einval = this.eval_libc("EINVAL");
                 this.set_last_error(einval)?;
                 this.write_scalar(Scalar::from_machine_isize(-1, this), dest)?;
                 return Ok(());
@@ -99,7 +99,7 @@ pub fn futex<'tcx>(
                 let duration = match this.read_timespec(&timeout)? {
                     Some(duration) => duration,
                     None => {
-                        let einval = this.eval_libc("EINVAL")?;
+                        let einval = this.eval_libc("EINVAL");
                         this.set_last_error(einval)?;
                         this.write_scalar(Scalar::from_machine_isize(-1, this), dest)?;
                         return Ok(());
@@ -194,7 +194,7 @@ impl<'mir, 'tcx: 'mir> MachineCallback<'mir, 'tcx> for Callback<'tcx> {
                         fn call(&self, this: &mut MiriInterpCx<'mir, 'tcx>) -> InterpResult<'tcx> {
                             this.unblock_thread(self.thread);
                             this.futex_remove_waiter(self.addr_usize, self.thread);
-                            let etimedout = this.eval_libc("ETIMEDOUT")?;
+                            let etimedout = this.eval_libc("ETIMEDOUT");
                             this.set_last_error(etimedout)?;
                             this.write_scalar(Scalar::from_machine_isize(-1, this), &self.dest)?;
 
@@ -211,7 +211,7 @@ fn call(&self, this: &mut MiriInterpCx<'mir, 'tcx>) -> InterpResult<'tcx> {
             } else {
                 // The futex value doesn't match the expected value, so we return failure
                 // right away without sleeping: -1 and errno set to EAGAIN.
-                let eagain = this.eval_libc("EAGAIN")?;
+                let eagain = this.eval_libc("EAGAIN");
                 this.set_last_error(eagain)?;
                 this.write_scalar(Scalar::from_machine_isize(-1, this), dest)?;
             }
@@ -237,7 +237,7 @@ fn call(&self, this: &mut MiriInterpCx<'mir, 'tcx>) -> InterpResult<'tcx> {
                 u32::MAX
             };
             if bitset == 0 {
-                let einval = this.eval_libc("EINVAL")?;
+                let einval = this.eval_libc("EINVAL");
                 this.set_last_error(einval)?;
                 this.write_scalar(Scalar::from_machine_isize(-1, this), dest)?;
                 return Ok(());
index 282bfc8024f55464d3381dddcaf28f249e6ff269..d616126cb2ab7f6c9d14f5d0ffda114a0b903c0e 100644 (file)
@@ -176,7 +176,7 @@ fn emulate_foreign_item_by_name(
             "pthread_setname_np" => {
                 let [name] = this.check_shim(abi, Abi::C { unwind: false }, link_name, args)?;
                 let thread = this.pthread_self()?;
-                let max_len = this.eval_libc("MAXTHREADNAMESIZE")?.to_machine_usize(this)?;
+                let max_len = this.eval_libc("MAXTHREADNAMESIZE").to_machine_usize(this)?;
                 let res = this.pthread_setname_np(
                     thread,
                     this.read_scalar(name)?,
index f9b5774f0090e05ece1d5e2703386a2452091fae..b3c474dd3c9f19ddcedac12142ebaa72a238126b 100644 (file)
@@ -21,14 +21,14 @@ fn is_mutex_kind_default<'mir, 'tcx: 'mir>(
     ecx: &mut MiriInterpCx<'mir, 'tcx>,
     kind: i32,
 ) -> InterpResult<'tcx, bool> {
-    Ok(kind == ecx.eval_libc_i32("PTHREAD_MUTEX_DEFAULT")?)
+    Ok(kind == ecx.eval_libc_i32("PTHREAD_MUTEX_DEFAULT"))
 }
 
 fn is_mutex_kind_normal<'mir, 'tcx: 'mir>(
     ecx: &mut MiriInterpCx<'mir, 'tcx>,
     kind: i32,
 ) -> InterpResult<'tcx, bool> {
-    let mutex_normal_kind = ecx.eval_libc_i32("PTHREAD_MUTEX_NORMAL")?;
+    let mutex_normal_kind = ecx.eval_libc_i32("PTHREAD_MUTEX_NORMAL");
     Ok(kind == (mutex_normal_kind | PTHREAD_MUTEX_NORMAL_FLAG))
 }
 
@@ -217,7 +217,7 @@ fn pthread_mutexattr_init(
     ) -> InterpResult<'tcx, i32> {
         let this = self.eval_context_mut();
 
-        let default_kind = this.eval_libc_i32("PTHREAD_MUTEX_DEFAULT")?;
+        let default_kind = this.eval_libc_i32("PTHREAD_MUTEX_DEFAULT");
         mutexattr_set_kind(this, attr_op, default_kind)?;
 
         Ok(0)
@@ -231,7 +231,7 @@ fn pthread_mutexattr_settype(
         let this = self.eval_context_mut();
 
         let kind = this.read_scalar(kind_op)?.to_i32()?;
-        if kind == this.eval_libc_i32("PTHREAD_MUTEX_NORMAL")? {
+        if kind == this.eval_libc_i32("PTHREAD_MUTEX_NORMAL") {
             // In `glibc` implementation, the numeric values of
             // `PTHREAD_MUTEX_NORMAL` and `PTHREAD_MUTEX_DEFAULT` are equal.
             // However, a mutex created by explicitly passing
@@ -247,17 +247,17 @@ fn pthread_mutexattr_settype(
             let normal_kind = kind | PTHREAD_MUTEX_NORMAL_FLAG;
             // Check that after setting the flag, the kind is distinguishable
             // from all other kinds.
-            assert_ne!(normal_kind, this.eval_libc_i32("PTHREAD_MUTEX_DEFAULT")?);
-            assert_ne!(normal_kind, this.eval_libc_i32("PTHREAD_MUTEX_ERRORCHECK")?);
-            assert_ne!(normal_kind, this.eval_libc_i32("PTHREAD_MUTEX_RECURSIVE")?);
+            assert_ne!(normal_kind, this.eval_libc_i32("PTHREAD_MUTEX_DEFAULT"));
+            assert_ne!(normal_kind, this.eval_libc_i32("PTHREAD_MUTEX_ERRORCHECK"));
+            assert_ne!(normal_kind, this.eval_libc_i32("PTHREAD_MUTEX_RECURSIVE"));
             mutexattr_set_kind(this, attr_op, normal_kind)?;
-        } else if kind == this.eval_libc_i32("PTHREAD_MUTEX_DEFAULT")?
-            || kind == this.eval_libc_i32("PTHREAD_MUTEX_ERRORCHECK")?
-            || kind == this.eval_libc_i32("PTHREAD_MUTEX_RECURSIVE")?
+        } else if kind == this.eval_libc_i32("PTHREAD_MUTEX_DEFAULT")
+            || kind == this.eval_libc_i32("PTHREAD_MUTEX_ERRORCHECK")
+            || kind == this.eval_libc_i32("PTHREAD_MUTEX_RECURSIVE")
         {
             mutexattr_set_kind(this, attr_op, kind)?;
         } else {
-            let einval = this.eval_libc_i32("EINVAL")?;
+            let einval = this.eval_libc_i32("EINVAL");
             return Ok(einval);
         }
 
@@ -299,7 +299,7 @@ fn pthread_mutex_init(
 
         let attr = this.read_pointer(attr_op)?;
         let kind = if this.ptr_is_null(attr)? {
-            this.eval_libc_i32("PTHREAD_MUTEX_DEFAULT")?
+            this.eval_libc_i32("PTHREAD_MUTEX_DEFAULT")
         } else {
             mutexattr_get_kind(this, attr_op)?
         };
@@ -331,9 +331,9 @@ fn pthread_mutex_lock(&mut self, mutex_op: &OpTy<'tcx, Provenance>) -> InterpRes
                     throw_ub_format!("trying to acquire already locked default mutex");
                 } else if is_mutex_kind_normal(this, kind)? {
                     throw_machine_stop!(TerminationInfo::Deadlock);
-                } else if kind == this.eval_libc_i32("PTHREAD_MUTEX_ERRORCHECK")? {
-                    this.eval_libc_i32("EDEADLK")
-                } else if kind == this.eval_libc_i32("PTHREAD_MUTEX_RECURSIVE")? {
+                } else if kind == this.eval_libc_i32("PTHREAD_MUTEX_ERRORCHECK") {
+                    Ok(this.eval_libc_i32("EDEADLK"))
+                } else if kind == this.eval_libc_i32("PTHREAD_MUTEX_RECURSIVE") {
                     this.mutex_lock(id, active_thread);
                     Ok(0)
                 } else {
@@ -362,14 +362,14 @@ fn pthread_mutex_trylock(
         if this.mutex_is_locked(id) {
             let owner_thread = this.mutex_get_owner(id);
             if owner_thread != active_thread {
-                this.eval_libc_i32("EBUSY")
+                Ok(this.eval_libc_i32("EBUSY"))
             } else {
                 if is_mutex_kind_default(this, kind)?
                     || is_mutex_kind_normal(this, kind)?
-                    || kind == this.eval_libc_i32("PTHREAD_MUTEX_ERRORCHECK")?
+                    || kind == this.eval_libc_i32("PTHREAD_MUTEX_ERRORCHECK")
                 {
-                    this.eval_libc_i32("EBUSY")
-                } else if kind == this.eval_libc_i32("PTHREAD_MUTEX_RECURSIVE")? {
+                    Ok(this.eval_libc_i32("EBUSY"))
+                } else if kind == this.eval_libc_i32("PTHREAD_MUTEX_RECURSIVE") {
                     this.mutex_lock(id, active_thread);
                     Ok(0)
                 } else {
@@ -410,10 +410,10 @@ fn pthread_mutex_unlock(
                 throw_ub_format!(
                     "unlocked a PTHREAD_MUTEX_NORMAL mutex that was not locked by the current thread"
                 );
-            } else if kind == this.eval_libc_i32("PTHREAD_MUTEX_ERRORCHECK")?
-                || kind == this.eval_libc_i32("PTHREAD_MUTEX_RECURSIVE")?
+            } else if kind == this.eval_libc_i32("PTHREAD_MUTEX_ERRORCHECK")
+                || kind == this.eval_libc_i32("PTHREAD_MUTEX_RECURSIVE")
             {
-                this.eval_libc_i32("EPERM")
+                Ok(this.eval_libc_i32("EPERM"))
             } else {
                 throw_unsup_format!("called pthread_mutex_unlock on an unsupported type of mutex");
             }
@@ -471,7 +471,7 @@ fn pthread_rwlock_tryrdlock(
         let active_thread = this.get_active_thread();
 
         if this.rwlock_is_write_locked(id) {
-            this.eval_libc_i32("EBUSY")
+            Ok(this.eval_libc_i32("EBUSY"))
         } else {
             this.rwlock_reader_lock(id, active_thread);
             Ok(0)
@@ -518,7 +518,7 @@ fn pthread_rwlock_trywrlock(
         let active_thread = this.get_active_thread();
 
         if this.rwlock_is_locked(id) {
-            this.eval_libc_i32("EBUSY")
+            Ok(this.eval_libc_i32("EBUSY"))
         } else {
             this.rwlock_writer_lock(id, active_thread);
             Ok(0)
@@ -575,7 +575,7 @@ fn pthread_condattr_init(
         // The default value of the clock attribute shall refer to the system
         // clock.
         // https://pubs.opengroup.org/onlinepubs/9699919799/functions/pthread_condattr_setclock.html
-        let default_clock_id = this.eval_libc_i32("CLOCK_REALTIME")?;
+        let default_clock_id = this.eval_libc_i32("CLOCK_REALTIME");
         condattr_set_clock_id(this, attr_op, default_clock_id)?;
 
         Ok(0)
@@ -589,12 +589,12 @@ fn pthread_condattr_setclock(
         let this = self.eval_context_mut();
 
         let clock_id = this.read_scalar(clock_id_op)?.to_i32()?;
-        if clock_id == this.eval_libc_i32("CLOCK_REALTIME")?
-            || clock_id == this.eval_libc_i32("CLOCK_MONOTONIC")?
+        if clock_id == this.eval_libc_i32("CLOCK_REALTIME")
+            || clock_id == this.eval_libc_i32("CLOCK_MONOTONIC")
         {
             condattr_set_clock_id(this, attr_op, clock_id)?;
         } else {
-            let einval = this.eval_libc_i32("EINVAL")?;
+            let einval = this.eval_libc_i32("EINVAL");
             return Ok(Scalar::from_i32(einval));
         }
 
@@ -638,7 +638,7 @@ fn pthread_cond_init(
 
         let attr = this.read_pointer(attr_op)?;
         let clock_id = if this.ptr_is_null(attr)? {
-            this.eval_libc_i32("CLOCK_REALTIME")?
+            this.eval_libc_i32("CLOCK_REALTIME")
         } else {
             condattr_get_clock_id(this, attr_op)?
         };
@@ -718,16 +718,16 @@ fn pthread_cond_timedwait(
         let duration = match this.read_timespec(&this.deref_operand(abstime_op)?)? {
             Some(duration) => duration,
             None => {
-                let einval = this.eval_libc("EINVAL")?;
+                let einval = this.eval_libc("EINVAL");
                 this.write_scalar(einval, dest)?;
                 return Ok(());
             }
         };
 
-        let timeout_time = if clock_id == this.eval_libc_i32("CLOCK_REALTIME")? {
+        let timeout_time = if clock_id == this.eval_libc_i32("CLOCK_REALTIME") {
             this.check_no_isolation("`pthread_cond_timedwait` with `CLOCK_REALTIME`")?;
             Time::RealTime(SystemTime::UNIX_EPOCH.checked_add(duration).unwrap())
-        } else if clock_id == this.eval_libc_i32("CLOCK_MONOTONIC")? {
+        } else if clock_id == this.eval_libc_i32("CLOCK_MONOTONIC") {
             Time::Monotonic(this.machine.clock.anchor().checked_add(duration).unwrap())
         } else {
             throw_unsup_format!("unsupported clock id: {}", clock_id);
@@ -763,7 +763,7 @@ fn call(&self, ecx: &mut MiriInterpCx<'mir, 'tcx>) -> InterpResult<'tcx> {
                 ecx.condvar_remove_waiter(self.id, self.active_thread);
 
                 // Set the return value: we timed out.
-                let etimedout = ecx.eval_libc("ETIMEDOUT")?;
+                let etimedout = ecx.eval_libc("ETIMEDOUT");
                 ecx.write_scalar(etimedout, &self.dest)?;
 
                 Ok(())
index 5b9dc90f0f0060c63524e4297e83aec4d8301532..4f7b028d35dbfaf6705c8b05f78933d40f300dd0 100644 (file)
@@ -84,7 +84,7 @@ fn pthread_setname_np(
 
         // Comparing with `>=` to account for null terminator.
         if name.len() >= max_name_len {
-            return this.eval_libc("ERANGE");
+            return Ok(this.eval_libc("ERANGE"));
         }
 
         this.set_thread_name(thread, name);
@@ -107,7 +107,7 @@ fn pthread_getname_np(
         let name = this.get_thread_name(thread).to_owned();
         let (success, _written) = this.write_c_str(&name, name_out, len)?;
 
-        if success { Ok(Scalar::from_u32(0)) } else { this.eval_libc("ERANGE") }
+        Ok(if success { Scalar::from_u32(0) } else { this.eval_libc("ERANGE") })
     }
 
     fn sched_yield(&mut self) -> InterpResult<'tcx, i32> {
index 6b043c6d2c9e1c723d2d242d1ff12e896f3a61c7..61cb3b382b3c3ceca68e458f596a8d525d64d4f8 100644 (file)
@@ -170,7 +170,7 @@ fn InitOnceBeginInitialize(
         match this.init_once_status(id) {
             InitOnceStatus::Uninitialized => {
                 this.init_once_begin(id);
-                this.write_scalar(this.eval_windows("c", "TRUE")?, &pending_place)?;
+                this.write_scalar(this.eval_windows("c", "TRUE"), &pending_place)?;
             }
             InitOnceStatus::Begun => {
                 // Someone else is already on it.
@@ -195,8 +195,8 @@ fn call(&self, this: &mut MiriInterpCx<'mir, 'tcx>) -> InterpResult<'tcx> {
                                 unreachable!(
                                     "status should have either been set to begun or complete"
                                 ),
-                            InitOnceStatus::Begun => this.eval_windows("c", "TRUE")?,
-                            InitOnceStatus::Complete => this.eval_windows("c", "FALSE")?,
+                            InitOnceStatus::Begun => this.eval_windows("c", "TRUE"),
+                            InitOnceStatus::Complete => this.eval_windows("c", "FALSE"),
                         };
 
                         this.write_scalar(pending, &self.pending_place)?;
@@ -213,12 +213,12 @@ fn call(&self, this: &mut MiriInterpCx<'mir, 'tcx>) -> InterpResult<'tcx> {
             }
             InitOnceStatus::Complete => {
                 this.init_once_observe_completed(id);
-                this.write_scalar(this.eval_windows("c", "FALSE")?, &pending_place)?;
+                this.write_scalar(this.eval_windows("c", "FALSE"), &pending_place)?;
             }
         }
 
         // This always succeeds (even if the thread is blocked, we will succeed if we ever unblock).
-        this.eval_windows("c", "TRUE")
+        Ok(this.eval_windows("c", "TRUE"))
     }
 
     fn InitOnceComplete(
@@ -235,7 +235,7 @@ fn InitOnceComplete(
 
         let success = if flags == 0 {
             true
-        } else if flags == this.eval_windows("c", "INIT_ONCE_INIT_FAILED")?.to_u32()? {
+        } else if flags == this.eval_windows_u32("c", "INIT_ONCE_INIT_FAILED") {
             false
         } else {
             throw_unsup_format!("unsupported `dwFlags` {flags} in `InitOnceBeginInitialize`");
@@ -258,7 +258,7 @@ fn InitOnceComplete(
             this.init_once_fail(id)?;
         }
 
-        this.eval_windows("c", "TRUE")
+        Ok(this.eval_windows("c", "TRUE"))
     }
 
     fn WaitOnAddress(
@@ -280,14 +280,14 @@ fn WaitOnAddress(
         let addr = ptr.addr().bytes();
 
         if size > 8 || !size.is_power_of_two() {
-            let invalid_param = this.eval_windows("c", "ERROR_INVALID_PARAMETER")?;
+            let invalid_param = this.eval_windows("c", "ERROR_INVALID_PARAMETER");
             this.set_last_error(invalid_param)?;
             this.write_scalar(Scalar::from_i32(0), dest)?;
             return Ok(());
         };
         let size = Size::from_bytes(size);
 
-        let timeout_time = if timeout_ms == this.eval_windows("c", "INFINITE")?.to_u32()? {
+        let timeout_time = if timeout_ms == this.eval_windows_u32("c", "INFINITE") {
             None
         } else {
             let duration = Duration::from_millis(timeout_ms.into());
@@ -325,7 +325,7 @@ impl<'mir, 'tcx: 'mir> MachineCallback<'mir, 'tcx> for Callback<'tcx> {
                     fn call(&self, this: &mut MiriInterpCx<'mir, 'tcx>) -> InterpResult<'tcx> {
                         this.unblock_thread(self.thread);
                         this.futex_remove_waiter(self.addr, self.thread);
-                        let error_timeout = this.eval_windows("c", "ERROR_TIMEOUT")?;
+                        let error_timeout = this.eval_windows("c", "ERROR_TIMEOUT");
                         this.set_last_error(error_timeout)?;
                         this.write_scalar(Scalar::from_i32(0), &self.dest)?;
 
@@ -377,7 +377,7 @@ fn SleepConditionVariableSRW(
         let timeout_ms = this.read_scalar(timeout_op)?.to_u32()?;
         let flags = this.read_scalar(flags_op)?.to_u32()?;
 
-        let timeout_time = if timeout_ms == this.eval_windows("c", "INFINITE")?.to_u32()? {
+        let timeout_time = if timeout_ms == this.eval_windows_u32("c", "INFINITE") {
             None
         } else {
             let duration = Duration::from_millis(timeout_ms.into());
@@ -431,9 +431,9 @@ fn call(&self, this: &mut MiriInterpCx<'mir, 'tcx>) -> InterpResult<'tcx> {
 
                     this.condvar_remove_waiter(self.condvar_id, self.thread);
 
-                    let error_timeout = this.eval_windows("c", "ERROR_TIMEOUT")?;
+                    let error_timeout = this.eval_windows("c", "ERROR_TIMEOUT");
                     this.set_last_error(error_timeout)?;
-                    this.write_scalar(this.eval_windows("c", "FALSE")?, &self.dest)?;
+                    this.write_scalar(this.eval_windows("c", "FALSE"), &self.dest)?;
                     Ok(())
                 }
             }
@@ -451,7 +451,7 @@ fn call(&self, this: &mut MiriInterpCx<'mir, 'tcx>) -> InterpResult<'tcx> {
             );
         }
 
-        this.eval_windows("c", "TRUE")
+        Ok(this.eval_windows("c", "TRUE"))
     }
 
     fn WakeConditionVariable(&mut self, condvar_op: &OpTy<'tcx, Provenance>) -> InterpResult<'tcx> {
index 25a5194caa096540d997df4c13dfe33c42ca9464..c3a450db48dc763e1fc01f3c28450f53aeb3a8c5 100644 (file)
@@ -34,7 +34,7 @@ fn CreateThread(
         };
 
         let stack_size_param_is_a_reservation =
-            this.eval_windows("c", "STACK_SIZE_PARAM_IS_A_RESERVATION")?.to_u32()?;
+            this.eval_windows_u32("c", "STACK_SIZE_PARAM_IS_A_RESERVATION");
 
         // We ignore the stack size, so we also ignore the
         // `STACK_SIZE_PARAM_IS_A_RESERVATION` flag.
@@ -73,7 +73,7 @@ fn WaitForSingleObject(
             _ => this.invalid_handle("WaitForSingleObject")?,
         };
 
-        if timeout != this.eval_windows("c", "INFINITE")?.to_u32()? {
+        if timeout != this.eval_windows_u32("c", "INFINITE") {
             throw_unsup_format!("`WaitForSingleObject` with non-infinite timeout");
         }