Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
41 commits
Select commit Hold shift + click to select a range
80a207a
genmc/*: Fix paths and naming for graph-related includes
michaliskok Jan 31, 2026
e77d11d
genmc/exploration: Have {inc,dec}_pos take a count argument
michaliskok Jan 31, 2026
535df2e
genmc/api: Add a curr_pos()
michaliskok Jan 31, 2026
66330fa
genmc/api: Add a MallocResult type
michaliskok Jan 31, 2026
912e6e5
diagnostics,genmc*: Add type to signal execution abortion
michaliskok Mar 28, 2026
ca6e184
diagnostics: End sentences with a period
michaliskok Apr 10, 2026
99ac0a7
Add shims for non-blocking sockets and non-blocking socket operations
WhySoBad Mar 30, 2026
5e2c5b2
avoid duplicating read/write_all logic
RalfJung Apr 12, 2026
ff96bec
feat: add `accept4` with SOCK_NONBLOCK test
WhySoBad Apr 12, 2026
0f36702
Merge pull request #4938 from WhySoBad/network-socket-non-blocking
RalfJung Apr 12, 2026
142d79d
genmc/*: Update GenMC calls to match the new API for NAs
michaliskok Feb 3, 2026
d42fe71
genmc/exploration: Add a FIXME for join
michaliskok Apr 12, 2026
8ac00e5
genmc: Replace BUG_ON() w/ VERIFY()
michaliskok Apr 6, 2026
a428be2
genmc/setup: Don't use InterpreterCallbacks
michaliskok Apr 6, 2026
8a3c8cb
genmc/lib: GENMC_DEBUG has been renamed to ENABLE_GENMC_DEBUG
michaliskok Apr 6, 2026
a8685f7
genmc/build: ENABLE_GENMC_DEBUG is available in config.h
michaliskok Apr 6, 2026
7f7fdd4
genmc/build: Don't add labels for non-atomics to graphs
michaliskok Apr 8, 2026
75897f9
tests/genmc: Bless new results
michaliskok Apr 8, 2026
4fe9768
genmc/build: Bump GenMC version
michaliskok Apr 8, 2026
66cdfc4
tweak some comments
RalfJung Apr 12, 2026
66dd587
Merge pull request #4949 from michaliskok/genmc-no-nas
RalfJung Apr 12, 2026
385756c
genmc*: Don't split up non-atomic accesses to smaller chunks
michaliskok Apr 10, 2026
a6d043a
Merge pull request #4956 from michaliskok/genmc-no-split-nas
RalfJung Apr 13, 2026
c0d6de7
build(deps): bump rand from 0.9.2 to 0.9.3
dependabot[bot] Apr 14, 2026
4e84b77
Merge pull request #4960 from rust-lang/dependabot/cargo/rand-0.9.3
RalfJung Apr 14, 2026
3896b15
genmc tests: add -Zmiri-genmc by default
RalfJung Apr 14, 2026
b2ffd38
Merge pull request #4961 from RalfJung/genmc-tests
RalfJung Apr 14, 2026
abc05d7
Allow changing socket blocking state
WhySoBad Apr 9, 2026
bae3b39
Merge pull request #4955 from WhySoBad/network-socket-set-non-blocking
RalfJung Apr 14, 2026
fabc30d
fix 'cargo miri nextest <verb> --help' output
RalfJung Apr 16, 2026
9b9dc07
Merge pull request #4966 from RalfJung/help
RalfJung Apr 16, 2026
0560fde
remove vec_unique.default.stderr
quiode Apr 17, 2026
47f6f0b
Merge pull request #4967 from quiode/remove-vec_unique.default.stderr
RalfJung Apr 17, 2026
2bdf361
Prepare for merging from rust-lang/rust
Apr 19, 2026
ed395bb
Merge ref '6f109d8a2da2' from rust-lang/rust
Apr 19, 2026
8aefb07
clippy
RalfJung Apr 19, 2026
bf61e56
Merge pull request #4969 from rust-lang/rustup-2026-04-19
RalfJung Apr 19, 2026
08e9e17
Prepare for merging from rust-lang/rust
Apr 20, 2026
366676b
Merge ref 'e22c616e4e87' from rust-lang/rust
Apr 20, 2026
d5ebbc4
fmt
Apr 20, 2026
ecd6316
Merge pull request #4970 from rust-lang/rustup-2026-04-20
RalfJung Apr 20, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions src/tools/miri/Cargo.lock
Original file line number Diff line number Diff line change
Expand Up @@ -1162,9 +1162,9 @@ checksum = "69cdb34c158ceb288df11e18b4bd39de994f6657d83847bdffdbd7f346754b0f"

[[package]]
name = "rand"
version = "0.9.2"
version = "0.9.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "6db2770f06117d490610c7488547d543617b21bfa07796d7a12f6f1bd53850d1"
checksum = "7ec095654a25171c2124e9e3393a930bddbffdc939556c914957a4c3e0a87166"
dependencies = [
"rand_chacha",
"rand_core",
Expand Down
4 changes: 3 additions & 1 deletion src/tools/miri/cargo-miri/src/phases.rs
Original file line number Diff line number Diff line change
Expand Up @@ -87,7 +87,9 @@ pub fn phase_cargo_miri(mut args: impl Iterator<Item = String>) {
println!("`cargo miri {verb}` supports the same flags as `cargo {verb}`:\n");
let mut cmd = cargo();
cmd.arg(verb);
cmd.arg("--help");
// Forward all arguments (some of them can influence the help output, e.g.
// the nextest verb).
cmd.args(args);
exec(cmd);
}
_ => {
Expand Down
9 changes: 3 additions & 6 deletions src/tools/miri/genmc-sys/build.rs
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ mod downloading {
/// The GenMC repository the we get our commit from.
pub(crate) const GENMC_GITHUB_URL: &str = "https://github.com/MPI-SWS/genmc.git";
/// The GenMC commit we depend on. It must be available on the specified GenMC repository.
pub(crate) const GENMC_COMMIT: &str = "22d3d0b44dedb4e8e1aae3330e546465e4664529";
pub(crate) const GENMC_COMMIT: &str = "29b03a66402c4453fc77901ef3be90bb55707cd4";

/// Ensure that a local GenMC repo is present and set to the correct commit.
/// Return the path of the GenMC repo clone.
Expand Down Expand Up @@ -159,6 +159,7 @@ fn compile_cpp_dependencies(genmc_path: &Path) {
.out_dir(genmc_build_dir)
.profile(GENMC_CMAKE_PROFILE)
.define("BUILD_LLI", "OFF")
.define("EMIT_NA_LABELS", "OFF")
.define("GENMC_DEBUG", if enable_genmc_debug { "ON" } else { "OFF" });

// The actual compilation happens here:
Expand All @@ -172,7 +173,7 @@ fn compile_cpp_dependencies(genmc_path: &Path) {
// Part 2:
// Compile the cxx_bridge (the link between the Rust and C++ code).

let genmc_include_dir = genmc_install_dir.join("include").join("genmc");
let genmc_include_dir = genmc_install_dir.join("include");

// These are all the C++ files we need to compile, which needs to be updated if more C++ files are added to Miri.
// We use absolute paths since relative paths can confuse IDEs when attempting to go-to-source on a path in a compiler error.
Expand All @@ -181,10 +182,6 @@ fn compile_cpp_dependencies(genmc_path: &Path) {
.map(|file| std::path::absolute(cpp_files_base_path.join(file)).unwrap());

let mut bridge = cxx_build::bridge("src/lib.rs");
// FIXME(genmc,cmake): Remove once the GenMC debug setting is available in the config.h file.
if enable_genmc_debug {
bridge.define("ENABLE_GENMC_DEBUG", None);
}
bridge
.opt_level(2)
.debug(true) // Same settings that GenMC uses (default for cmake `RelWithDebInfo`)
Expand Down
150 changes: 97 additions & 53 deletions src/tools/miri/genmc-sys/cpp/include/MiriInterface.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -5,17 +5,17 @@
#include "rust/cxx.h"

// GenMC generated headers:
#include "config.h"
#include "genmc/config.h"

// Miri `genmc-sys/src_cpp` headers:
#include "ResultHandling.hpp"

// GenMC headers:
#include "ExecutionGraph/EventLabel.hpp"
#include "Support/MemOrdering.hpp"
#include "Support/RMWOps.hpp"
#include "Verification/Config.hpp"
#include "Verification/GenMCDriver.hpp"
#include "genmc/Execution/EventLabel.hpp"
#include "genmc/Support/MemOrdering.hpp"
#include "genmc/Support/RMWOps.hpp"
#include "genmc/Verification/Config.hpp"
#include "genmc/Verification/GenMCDriver.hpp"

// C++ headers:
#include <cstdint>
Expand All @@ -36,6 +36,7 @@ struct StoreResult;
struct ReadModifyWriteResult;
struct CompareExchangeResult;
struct MutexLockResult;
struct MallocResult;

// GenMC uses `int` for its thread IDs.
using ThreadId = int;
Expand Down Expand Up @@ -86,13 +87,15 @@ struct MiriGenmcShim : private GenMCDriver {

/**** Memory access handling ****/

[[nodiscard]] LoadResult handle_load(
[[nodiscard]] LoadResult handle_atomic_load(
ThreadId thread_id,
uint64_t address,
uint64_t size,
MemOrdering ord,
GenmcScalar old_val
);
[[nodiscard]] LoadResult
handle_non_atomic_load(ThreadId thread_id, uint64_t address, uint64_t size);
[[nodiscard]] ReadModifyWriteResult handle_read_modify_write(
ThreadId thread_id,
uint64_t address,
Expand All @@ -113,20 +116,22 @@ struct MiriGenmcShim : private GenMCDriver {
MemOrdering fail_load_ordering,
bool can_fail_spuriously
);
[[nodiscard]] StoreResult handle_store(
[[nodiscard]] StoreResult handle_atomic_store(
ThreadId thread_id,
uint64_t address,
uint64_t size,
GenmcScalar value,
GenmcScalar old_val,
MemOrdering ord
);
[[nodiscard]] StoreResult
handle_non_atomic_store(ThreadId thread_id, uint64_t address, uint64_t size);

void handle_fence(ThreadId thread_id, MemOrdering ord);

/**** Memory (de)allocation ****/

auto handle_malloc(ThreadId thread_id, uint64_t size, uint64_t alignment) -> uint64_t;
auto handle_malloc(ThreadId thread_id, uint64_t size, uint64_t alignment) -> MallocResult;

/** Returns null on success, or an error string if an error occurs. */
auto handle_free(ThreadId thread_id, uint64_t address) -> std::unique_ptr<std::string>;
Expand Down Expand Up @@ -203,33 +208,15 @@ struct MiriGenmcShim : private GenMCDriver {
auto get_estimation_results() const -> EstimationResult;

private:
/** Increment the event index in the given thread by 1 and return the new event. */
[[nodiscard]] inline auto inc_pos(ThreadId tid) -> Event {
/** Returns the current event for a given thread. */
inline auto curr_pos(ThreadId tid) -> Event {
ERROR_ON(tid >= threads_action_.size(), "ThreadId out of bounds");
return ++threads_action_[tid].event;
return threads_action_[tid].event;
}
/** Decrement the event index in the given thread by 1 and return the new event. */
inline auto dec_pos(ThreadId tid) -> Event {
/** Increment the event index in the given thread by `count`. */
inline void inc_pos(ThreadId tid, unsigned int count) {
ERROR_ON(tid >= threads_action_.size(), "ThreadId out of bounds");
return --threads_action_[tid].event;
}

/**
* Helper function for loads that need to reset the event counter when no value is returned.
* Same syntax as `GenMCDriver::handleLoad`, but this takes a thread id instead of an Event.
* Automatically calls `inc_pos` and `dec_pos` where needed for the given thread.
*/
template <EventLabel::EventLabelKind k, typename... Ts>
auto handle_load_reset_if_none(ThreadId tid, std::optional<SVal> old_val, Ts&&... params)
-> HandleResult<SVal> {
const auto pos = inc_pos(tid);
const auto ret =
GenMCDriver::handleLoad<k>(nullptr, pos, old_val, std::forward<Ts>(params)...);
// If we didn't get a value, we have to reset the index of the current thread.
if (!std::holds_alternative<SVal>(ret)) {
dec_pos(tid);
}
return ret;
threads_action_[tid].event.index += count;
}

/**
Expand Down Expand Up @@ -293,48 +280,72 @@ inline std::optional<SVal> try_to_sval(GenmcScalar scalar) {
namespace LoadResultExt {
inline LoadResult no_value() {
return LoadResult {
.invalid = false,
.error = std::unique_ptr<std::string>(nullptr),
.has_value = false,
.read_value = GenmcScalarExt::uninit(),
};
}

inline LoadResult from_value(SVal read_value) {
return LoadResult { .error = std::unique_ptr<std::string>(nullptr),
.has_value = true,
return LoadResult { .invalid = false,
.error = std::unique_ptr<std::string>(nullptr),
.read_value = GenmcScalarExt::from_sval(read_value) };
}

inline LoadResult from_error(std::unique_ptr<std::string> error) {
return LoadResult { .error = std::move(error),
.has_value = false,
return LoadResult { .invalid = false,
.error = std::move(error),
.read_value = GenmcScalarExt::uninit() };
}

inline LoadResult from_invalid() {
return LoadResult { .invalid = true, .error = nullptr, .read_value = GenmcScalarExt::uninit() };
}

} // namespace LoadResultExt

namespace StoreResultExt {
inline StoreResult ok(bool is_coherence_order_maximal_write) {
return StoreResult { /* error: */ std::unique_ptr<std::string>(nullptr),
is_coherence_order_maximal_write };
return StoreResult { .invalid = false,
.error = std::unique_ptr<std::string>(nullptr),
.is_coherence_order_maximal_write = is_coherence_order_maximal_write };
}

inline StoreResult from_error(std::unique_ptr<std::string> error) {
return StoreResult { .error = std::move(error), .is_coherence_order_maximal_write = false };
return StoreResult { .invalid = false,
.error = std::move(error),
.is_coherence_order_maximal_write = false };
}

inline StoreResult from_invalid() {
return StoreResult { .invalid = true,
.error = nullptr,
.is_coherence_order_maximal_write = false };
}
} // namespace StoreResultExt

namespace ReadModifyWriteResultExt {
inline ReadModifyWriteResult
ok(SVal old_value, SVal new_value, bool is_coherence_order_maximal_write) {
return ReadModifyWriteResult { .error = std::unique_ptr<std::string>(nullptr),
return ReadModifyWriteResult { .invalid = false,
.error = std::unique_ptr<std::string>(nullptr),
.old_value = GenmcScalarExt::from_sval(old_value),
.new_value = GenmcScalarExt::from_sval(new_value),
.is_coherence_order_maximal_write =
is_coherence_order_maximal_write };
}

inline ReadModifyWriteResult from_error(std::unique_ptr<std::string> error) {
return ReadModifyWriteResult { .error = std::move(error),
return ReadModifyWriteResult { .invalid = false,
.error = std::move(error),
.old_value = GenmcScalarExt::uninit(),
.new_value = GenmcScalarExt::uninit(),
.is_coherence_order_maximal_write = false };
}

inline ReadModifyWriteResult from_invalid() {
return ReadModifyWriteResult { .invalid = true,
.error = nullptr,
.old_value = GenmcScalarExt::uninit(),
.new_value = GenmcScalarExt::uninit(),
.is_coherence_order_maximal_write = false };
Expand All @@ -343,22 +354,33 @@ inline ReadModifyWriteResult from_error(std::unique_ptr<std::string> error) {

namespace CompareExchangeResultExt {
inline CompareExchangeResult success(SVal old_value, bool is_coherence_order_maximal_write) {
return CompareExchangeResult { .error = nullptr,
return CompareExchangeResult { .invalid = false,
.error = nullptr,
.old_value = GenmcScalarExt::from_sval(old_value),
.is_success = true,
.is_coherence_order_maximal_write =
is_coherence_order_maximal_write };
}

inline CompareExchangeResult failure(SVal old_value) {
return CompareExchangeResult { .error = nullptr,
return CompareExchangeResult { .invalid = false,
.error = nullptr,
.old_value = GenmcScalarExt::from_sval(old_value),
.is_success = false,
.is_coherence_order_maximal_write = false };
}

inline CompareExchangeResult from_error(std::unique_ptr<std::string> error) {
return CompareExchangeResult { .error = std::move(error),
return CompareExchangeResult { .invalid = false,
.error = std::move(error),
.old_value = GenmcScalarExt::uninit(),
.is_success = false,
.is_coherence_order_maximal_write = false };
}

inline CompareExchangeResult from_invalid() {
return CompareExchangeResult { .invalid = true,
.error = nullptr,
.old_value = GenmcScalarExt::uninit(),
.is_success = false,
.is_coherence_order_maximal_write = false };
Expand All @@ -367,20 +389,42 @@ inline CompareExchangeResult from_error(std::unique_ptr<std::string> error) {

namespace MutexLockResultExt {
inline MutexLockResult ok(bool is_lock_acquired) {
return MutexLockResult { /* error: */ nullptr, /* is_reset: */ false, is_lock_acquired };
return MutexLockResult { .invalid = false,
.error = nullptr,
.is_reset = false,
.is_lock_acquired = is_lock_acquired };
}

inline MutexLockResult reset() {
return MutexLockResult { /* error: */ nullptr,
/* is_reset: */ true,
/* is_lock_acquired: */ false };
return MutexLockResult { .invalid = false,
.error = nullptr,
.is_reset = true,
.is_lock_acquired = false };
}

inline MutexLockResult from_error(std::unique_ptr<std::string> error) {
return MutexLockResult { /* error: */ std::move(error),
/* is_reset: */ false,
/* is_lock_acquired: */ false };
return MutexLockResult { .invalid = false,
.error = std::move(error),
.is_reset = false,
.is_lock_acquired = false };
}

inline MutexLockResult from_invalid() {
return MutexLockResult { .invalid = true,
.error = nullptr,
.is_reset = false,
.is_lock_acquired = false };
}
} // namespace MutexLockResultExt

namespace MallocResultExt {
inline MallocResult ok(SVal addr) {
return MallocResult { .error = nullptr, .address = addr.get() };
}

inline MallocResult from_error(std::unique_ptr<std::string> error) {
return MallocResult { .error = std::move(error), .address = 0UL };
}
} // namespace MallocResultExt

#endif /* GENMC_MIRI_INTERFACE_HPP */
2 changes: 1 addition & 1 deletion src/tools/miri/genmc-sys/cpp/include/ResultHandling.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
#include "rust/cxx.h"

// GenMC headers:
#include "Verification/VerificationError.hpp"
#include "genmc/Verification/VerificationError.hpp"

#include <format>
#include <memory>
Expand Down
Loading
Loading