Skip to content

Commit

Permalink
Auto merge of #113151 - RalfJung:miri, r=RalfJung,oli-obk
Browse files Browse the repository at this point in the history
update Miri

r? `@ghost`
  • Loading branch information
bors committed Jun 29, 2023
2 parents 94a94a9 + 6e3da5f commit 19e41ba
Show file tree
Hide file tree
Showing 205 changed files with 3,204 additions and 464 deletions.
26 changes: 25 additions & 1 deletion .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -156,13 +156,13 @@ jobs:
- name: mark the job as a failure
run: exit 1

# Send a Zulip notification when a cron job fails
cron-fail-notify:
name: cronjob failure notification
runs-on: ubuntu-latest
needs: [build, style]
if: github.event_name == 'schedule' && (failure() || cancelled())
steps:
# Send a Zulip notification
- name: Install zulip-send
run: pip3 install zulip
- name: Send Zulip notification
Expand All @@ -185,3 +185,27 @@ jobs:
Sincerely,
The Miri Cronjobs Bot' \
--user $ZULIP_BOT_EMAIL --api-key $ZULIP_API_TOKEN --site https://rust-lang.zulipchat.com
# Attempt to auto-sync with rustc
- name: install josh-proxy
run: cargo +stable install josh-proxy --git https://github.com/josh-project/josh --tag r22.12.06
- name: start josh-proxy
run: josh-proxy --local=$HOME/.cache/josh --remote=https://github.com --no-background &
- name: setup bot git name and email
run: |
git config --global user.name 'The Miri Conjob Bot'
git config --global user.email 'miri@cron.bot'
- name: get changes from rustc
run: ./miri rustc-pull
- name: format changes (if any)
run: |
./miri toolchain
./miri fmt --check || (./miri fmt && git commit -am "fmt")
- name: Push changes to a branch
run: |
git switch -c "rustup$(date -u +%Y-%m)"
git push
- name: Create Pull Request
run: gh pr create -B master --title 'Automatic sync from rustc' --body ''
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}

11 changes: 2 additions & 9 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

6 changes: 1 addition & 5 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -24,10 +24,6 @@ log = "0.4"
rand = "0.8"
smallvec = "1.7"

# A noop dependency that changes in the Rust repository, it's a bit of a hack.
# See the `src/tools/rustc-workspace-hack/README.md` file in `rust-lang/rust`
# for more information.
rustc-workspace-hack = "1.0.0"
measureme = "10.0.0"
ctrlc = "3.2.5"

Expand All @@ -40,7 +36,7 @@ libloading = "0.7"

[dev-dependencies]
colored = "2"
ui_test = "0.10"
ui_test = "0.11.6"
rustc_version = "0.4"
# Features chosen to match those required by env_logger, to avoid rebuilds
regex = { version = "1.5.5", default-features = false, features = ["perf", "std"] }
Expand Down
4 changes: 4 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -435,6 +435,9 @@ to Miri failing to detect cases of undefined behavior in a program.
so with this flag.
* `-Zmiri-force-page-size=<num>` overrides the default page size for an architecture, in multiples of 1k.
`4` is default for most targets. This value should always be a power of 2 and nonzero.
* `-Zmiri-unique-is-unique` performs additional aliasing checks for `core::ptr::Unique` to ensure
that it could theoretically be considered `noalias`. This flag is experimental and has
an effect only when used with `-Zmiri-tree-borrows`.

[function ABI]: https://doc.rust-lang.org/reference/items/functions.html#extern-function-qualifier

Expand Down Expand Up @@ -575,6 +578,7 @@ Definite bugs found:
* [`crossbeam-epoch` calling `assume_init` on a partly-initialized `MaybeUninit`](https://github.com/crossbeam-rs/crossbeam/pull/779)
* [`integer-encoding` dereferencing a misaligned pointer](https://github.com/dermesser/integer-encoding-rs/pull/23)
* [`rkyv` constructing a `Box<[u8]>` from an overaligned allocation](https://github.com/rkyv/rkyv/commit/a9417193a34757e12e24263178be8b2eebb72456)
* [Data race in `arc-swap`](https://github.com/vorner/arc-swap/issues/76)
* [Data race in `thread::scope`](https://github.com/rust-lang/rust/issues/98498)
* [`regex` incorrectly handling unaligned `Vec<u8>` buffers](https://www.reddit.com/r/rust/comments/vq3mmu/comment/ienc7t0?context=3)
* [Incorrect use of `compare_exchange_weak` in `once_cell`](https://github.com/matklad/once_cell/issues/186)
Expand Down
7 changes: 0 additions & 7 deletions cargo-miri/Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

5 changes: 0 additions & 5 deletions cargo-miri/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -20,11 +20,6 @@ serde_json = "1.0.40"
cargo_metadata = "0.15.0"
rustc-build-sysroot = "0.4.1"

# A noop dependency that changes in the Rust repository, it's a bit of a hack.
# See the `src/tools/rustc-workspace-hack/README.md` file in `rust-lang/rust`
# for more information.
rustc-workspace-hack = "1.0.0"

# Enable some feature flags that dev-dependencies need but dependencies
# do not. This makes `./miri install` after `./miri build` faster.
serde = { version = "*", features = ["derive"] }
Expand Down
2 changes: 1 addition & 1 deletion rust-version
Original file line number Diff line number Diff line change
@@ -1 +1 @@
33c3d101280c8eb3cd8af421bfb56a8afcc3881d
75726cae37317c7262b69d3e9fd11a3496a88d04
14 changes: 12 additions & 2 deletions src/bin/miri.rs
Original file line number Diff line number Diff line change
Expand Up @@ -31,9 +31,9 @@ use rustc_middle::{
query::{ExternProviders, LocalCrate},
ty::TyCtxt,
};
use rustc_session::{EarlyErrorHandler, CtfeBacktrace};
use rustc_session::config::{OptLevel, CrateType, ErrorOutputType};
use rustc_session::config::{CrateType, ErrorOutputType, OptLevel};
use rustc_session::search_paths::PathKind;
use rustc_session::{CtfeBacktrace, EarlyErrorHandler};

use miri::{BacktraceStyle, BorrowTrackerMethod, ProvenanceMode, RetagFields};

Expand Down Expand Up @@ -343,6 +343,8 @@ fn main() {
miri_config.borrow_tracker = None;
} else if arg == "-Zmiri-tree-borrows" {
miri_config.borrow_tracker = Some(BorrowTrackerMethod::TreeBorrows);
} else if arg == "-Zmiri-unique-is-unique" {
miri_config.unique_is_unique = true;
} else if arg == "-Zmiri-disable-data-race-detector" {
miri_config.data_race_detector = false;
miri_config.weak_memory_emulation = false;
Expand Down Expand Up @@ -560,6 +562,14 @@ fn main() {
rustc_args.push(arg);
}
}
// `-Zmiri-unique-is-unique` should only be used with `-Zmiri-tree-borrows`
if miri_config.unique_is_unique
&& !matches!(miri_config.borrow_tracker, Some(BorrowTrackerMethod::TreeBorrows))
{
show_error!(
"-Zmiri-unique-is-unique only has an effect when -Zmiri-tree-borrows is also used"
);
}

debug!("rustc arguments: {:?}", rustc_args);
debug!("crate arguments: {:?}", miri_config.args);
Expand Down
5 changes: 5 additions & 0 deletions src/borrow_tracker/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -103,6 +103,8 @@ pub struct GlobalStateInner {
pub tracked_call_ids: FxHashSet<CallId>,
/// Whether to recurse into datatypes when searching for pointers to retag.
pub retag_fields: RetagFields,
/// Whether `core::ptr::Unique` gets special (`Box`-like) handling.
pub unique_is_unique: bool,
}

impl VisitTags for GlobalStateInner {
Expand Down Expand Up @@ -170,6 +172,7 @@ impl GlobalStateInner {
tracked_pointer_tags: FxHashSet<BorTag>,
tracked_call_ids: FxHashSet<CallId>,
retag_fields: RetagFields,
unique_is_unique: bool,
) -> Self {
GlobalStateInner {
borrow_tracker_method,
Expand All @@ -180,6 +183,7 @@ impl GlobalStateInner {
tracked_pointer_tags,
tracked_call_ids,
retag_fields,
unique_is_unique,
}
}

Expand Down Expand Up @@ -244,6 +248,7 @@ impl BorrowTrackerMethod {
config.tracked_pointer_tags.clone(),
config.tracked_call_ids.clone(),
config.retag_fields,
config.unique_is_unique,
))
}
}
Expand Down
69 changes: 50 additions & 19 deletions src/borrow_tracker/tree_borrows/diagnostics.rs
Original file line number Diff line number Diff line change
Expand Up @@ -12,16 +12,46 @@ use crate::borrow_tracker::tree_borrows::{
use crate::borrow_tracker::{AccessKind, ProtectorKind};
use crate::*;

/// Cause of an access: either a real access or one
/// inserted by Tree Borrows due to a reborrow or a deallocation.
#[derive(Clone, Copy, Debug)]
pub enum AccessCause {
Explicit(AccessKind),
Reborrow,
Dealloc,
}

impl fmt::Display for AccessCause {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
match self {
Self::Explicit(kind) => write!(f, "{kind}"),
Self::Reborrow => write!(f, "reborrow"),
Self::Dealloc => write!(f, "deallocation"),
}
}
}

impl AccessCause {
fn print_as_access(self, is_foreign: bool) -> String {
let rel = if is_foreign { "foreign" } else { "child" };
match self {
Self::Explicit(kind) => format!("{rel} {kind}"),
Self::Reborrow => format!("reborrow (acting as a {rel} read access)"),
Self::Dealloc => format!("deallocation (acting as a {rel} write access)"),
}
}
}

/// Complete data for an event:
#[derive(Clone, Debug)]
pub struct Event {
/// Transformation of permissions that occured because of this event
/// Transformation of permissions that occured because of this event.
pub transition: PermTransition,
/// Kind of the access that triggered this event
pub access_kind: AccessKind,
/// Relative position of the tag to the one used for the access
/// Kind of the access that triggered this event.
pub access_cause: AccessCause,
/// Relative position of the tag to the one used for the access.
pub is_foreign: bool,
/// User-visible range of the access
/// User-visible range of the access.
pub access_range: AllocRange,
/// The transition recorded by this event only occured on a subrange of
/// `access_range`: a single access on `access_range` triggers several events,
Expand All @@ -36,7 +66,7 @@ pub struct Event {
/// the `TbError`, which should satisfy
/// `event.transition_range.contains(error.error_offset)`.
pub transition_range: Range<u64>,
/// Line of code that triggered this event
/// Line of code that triggered this event.
pub span: Span,
}

Expand Down Expand Up @@ -83,17 +113,19 @@ impl HistoryData {
self.events.push((Some(created.0.data()), msg_creation));
for &Event {
transition,
access_kind,
is_foreign,
access_cause,
access_range,
span,
transition_range: _,
} in &events
{
// NOTE: `transition_range` is explicitly absent from the error message, it has no significance
// to the user. The meaningful one is `access_range`.
self.events.push((Some(span.data()), format!("{this} later transitioned to {endpoint} due to a {rel} {access_kind} at offsets {access_range:?}", endpoint = transition.endpoint(), rel = if is_foreign { "foreign" } else { "child" })));
self.events.push((None, format!("this corresponds to {}", transition.summary())));
let access = access_cause.print_as_access(is_foreign);
self.events.push((Some(span.data()), format!("{this} later transitioned to {endpoint} due to a {access} at offsets {access_range:?}", endpoint = transition.endpoint())));
self.events
.push((None, format!("this transition corresponds to {}", transition.summary())));
}
}
}
Expand Down Expand Up @@ -238,9 +270,8 @@ pub(super) struct TbError<'node> {
/// On accesses rejected due to insufficient permissions, this is the
/// tag that lacked those permissions.
pub conflicting_info: &'node NodeDebugInfo,
/// Whether this was a Read or Write access. This field is ignored
/// when the error was triggered by a deallocation.
pub access_kind: AccessKind,
// What kind of access caused this error (read, write, reborrow, deallocation)
pub access_cause: AccessCause,
/// Which tag the access that caused this error was made through, i.e.
/// which tag was used to read/write/deallocate.
pub accessed_info: &'node NodeDebugInfo,
Expand All @@ -250,46 +281,46 @@ impl TbError<'_> {
/// Produce a UB error.
pub fn build<'tcx>(self) -> InterpError<'tcx> {
use TransitionError::*;
let kind = self.access_kind;
let cause = self.access_cause;
let accessed = self.accessed_info;
let conflicting = self.conflicting_info;
let accessed_is_conflicting = accessed.tag == conflicting.tag;
let title = format!("{cause} through {accessed} is forbidden");
let (title, details, conflicting_tag_name) = match self.error_kind {
ChildAccessForbidden(perm) => {
let conflicting_tag_name =
if accessed_is_conflicting { "accessed" } else { "conflicting" };
let title = format!("{kind} through {accessed} is forbidden");
let mut details = Vec::new();
if !accessed_is_conflicting {
details.push(format!(
"the accessed tag {accessed} is a child of the conflicting tag {conflicting}"
));
}
let access = cause.print_as_access(/* is_foreign */ false);
details.push(format!(
"the {conflicting_tag_name} tag {conflicting} has state {perm} which forbids child {kind}es"
"the {conflicting_tag_name} tag {conflicting} has state {perm} which forbids this {access}"
));
(title, details, conflicting_tag_name)
}
ProtectedTransition(transition) => {
let conflicting_tag_name = "protected";
let title = format!("{kind} through {accessed} is forbidden");
let access = cause.print_as_access(/* is_foreign */ true);
let details = vec![
format!(
"the accessed tag {accessed} is foreign to the {conflicting_tag_name} tag {conflicting} (i.e., it is not a child)"
),
format!(
"the access would cause the {conflicting_tag_name} tag {conflicting} to transition {transition}"
"this {access} would cause the {conflicting_tag_name} tag {conflicting} to transition {transition}"
),
format!(
"this is {loss}, which is not allowed for protected tags",
"this transition would be {loss}, which is not allowed for protected tags",
loss = transition.summary(),
),
];
(title, details, conflicting_tag_name)
}
ProtectedDealloc => {
let conflicting_tag_name = "strongly protected";
let title = format!("deallocation through {accessed} is forbidden");
let details = vec![
format!(
"the allocation of the accessed tag {accessed} also contains the {conflicting_tag_name} tag {conflicting}"
Expand Down
Loading

0 comments on commit 19e41ba

Please sign in to comment.