Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Upgrade Rust toolchain to nightly-2024-03-29 #3116

Merged
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
21 commits
Select commit Hold shift + click to select a range
c89426c
Upgrade Rust toolchain to nightly-2024-03-29
feliperodri Mar 29, 2024
6e33108
Correctly use NullOp::UbChecks
feliperodri Mar 29, 2024
7d69cab
Update calls to ty::RawPtr
feliperodri Mar 29, 2024
0e52fed
Remove use of pretty_ty
feliperodri Mar 29, 2024
fdf28f6
Add #[allow(dead_code)] to avoid spurious warnings
feliperodri Mar 29, 2024
cd134a8
Remove dead code
feliperodri Mar 29, 2024
851362e
Update kani-compiler/src/kani_middle/transform/body.rs
tautschnig Apr 4, 2024
f93193c
fixup! Update kani-compiler/src/kani_middle/transform/body.rs
tautschnig Apr 4, 2024
31c549d
Implement typed_swap intrinsic
tautschnig Apr 4, 2024
20e1e17
Merge remote-tracking branch 'origin/main' into toolchain-upgrade-202…
tautschnig Apr 4, 2024
c270426
fixup! Remove use of pretty_ty
tautschnig Apr 4, 2024
1b4a535
Add #[allow(dead_code)] to keep clippy happy
tautschnig Apr 4, 2024
3077014
fixup! fixup! Update kani-compiler/src/kani_middle/transform/body.rs
tautschnig Apr 4, 2024
85f0818
Merge branch 'main' into toolchain-upgrade-2024-03-29
tautschnig Apr 4, 2024
d4abc03
Add test for typed_swap
tautschnig Apr 5, 2024
fc083d6
Add typed_swap to documentation
tautschnig Apr 5, 2024
7344be8
fixup! Add test for typed_swap
tautschnig Apr 5, 2024
518fd07
typed_swap: use x, y
tautschnig Apr 5, 2024
4dc6be4
Check types
tautschnig Apr 5, 2024
50d34e6
Restore start/end column fields
tautschnig Apr 5, 2024
1573607
Merge remote-tracking branch 'origin/main' into toolchain-upgrade-202…
tautschnig Apr 5, 2024
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
1 change: 1 addition & 0 deletions docs/src/rust-feature-support/intrinsics.md
Original file line number Diff line number Diff line change
Expand Up @@ -220,6 +220,7 @@ truncf64 | Yes | |
try | No | [#267](https://github.com/model-checking/kani/issues/267) |
type_id | Yes | |
type_name | Yes | |
typed_swap | Yes | |
unaligned_volatile_load | No | See [Notes - Concurrency](#concurrency) |
unaligned_volatile_store | No | See [Notes - Concurrency](#concurrency) |
unchecked_add | Yes | |
Expand Down
42 changes: 42 additions & 0 deletions kani-compiler/src/codegen_cprover_gotoc/codegen/intrinsic.rs
Original file line number Diff line number Diff line change
Expand Up @@ -580,6 +580,7 @@ impl<'tcx> GotocCtx<'tcx> {
"truncf64" => codegen_simple_intrinsic!(Trunc),
"type_id" => codegen_intrinsic_const!(),
"type_name" => codegen_intrinsic_const!(),
"typed_swap" => self.codegen_swap(fargs, farg_types, loc),
"unaligned_volatile_load" => {
unstable_codegen!(
self.codegen_expr_to_place_stable(place, fargs.remove(0).dereference())
Expand Down Expand Up @@ -1943,6 +1944,47 @@ impl<'tcx> GotocCtx<'tcx> {
let zero = Type::size_t().zero();
cast_ptr.rem(align).eq(zero)
}

/// Swaps the memory contents pointed to by arguments `x` and `y`, respectively, which is
/// required for the `typed_swap` intrinsic.
///
/// The standard library API requires that `x` and `y` are readable and writable as their
/// (common) type (which auto-generated checks for dereferencing will take care of), and the
/// memory regions pointed to must be non-overlapping.
pub fn codegen_swap(&mut self, mut fargs: Vec<Expr>, farg_types: &[Ty], loc: Location) -> Stmt {
// two parameters, and both must be raw pointers with the same base type
assert!(fargs.len() == 2);
assert!(farg_types[0].kind().is_raw_ptr());
assert!(farg_types[0] == farg_types[1]);

let x = fargs.remove(0);
let y = fargs.remove(0);

// if(same_object(x, y)) {
// assert(x + 1 <= y || y + 1 <= x);
// assume(x + 1 <= y || y + 1 <= x);
adpaco-aws marked this conversation as resolved.
Show resolved Hide resolved
// }
let one = Expr::int_constant(1, Type::c_int());
tautschnig marked this conversation as resolved.
Show resolved Hide resolved
let non_overlapping =
x.clone().plus(one.clone()).le(y.clone()).or(y.clone().plus(one.clone()).le(x.clone()));
let non_overlapping_check = self.codegen_assert_assume(
non_overlapping,
PropertyClass::SafetyCheck,
"memory regions pointed to by `x` and `y` must not overlap",
loc,
);
let non_overlapping_stmt =
Stmt::if_then_else(x.clone().same_object(y.clone()), non_overlapping_check, None, loc);

// T t = *y; *y = *x; *x = t;
let deref_y = y.clone().dereference();
let (temp_var, assign_to_t) =
self.decl_temp_variable(deref_y.typ().clone(), Some(deref_y), loc);
let assign_to_y = y.dereference().assign(x.clone().dereference(), loc);
let assign_to_x = x.dereference().assign(temp_var, loc);

Stmt::block(vec![non_overlapping_stmt, assign_to_t, assign_to_y, assign_to_x], loc)
}
}

fn instance_args(instance: &Instance) -> GenericArgs {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -725,7 +725,7 @@ impl<'tcx> GotocCtx<'tcx> {
.bytes(),
Type::size_t(),
),
NullOp::UbCheck(_) => Expr::c_false(),
NullOp::UbChecks => Expr::c_false(),
}
}
Rvalue::ShallowInitBox(ref operand, content_ty) => {
Expand Down
11 changes: 4 additions & 7 deletions kani-compiler/src/codegen_cprover_gotoc/codegen/typ.rs
Original file line number Diff line number Diff line change
Expand Up @@ -570,7 +570,7 @@ impl<'tcx> GotocCtx<'tcx> {
// Note: This is not valid C but CBMC seems to be ok with it.
ty::Slice(e) => self.codegen_ty(*e).flexible_array_of(),
ty::Str => Type::unsigned_int(8).flexible_array_of(),
ty::Ref(_, t, _) | ty::RawPtr(ty::TypeAndMut { ty: t, .. }) => self.codegen_ty_ref(*t),
ty::Ref(_, t, _) | ty::RawPtr(t, _) => self.codegen_ty_ref(*t),
ty::FnDef(def_id, args) => {
let instance =
Instance::resolve(self.tcx, ty::ParamEnv::reveal_all(), *def_id, args)
Expand Down Expand Up @@ -993,7 +993,7 @@ impl<'tcx> GotocCtx<'tcx> {
| ty::Foreign(_)
| ty::Coroutine(..)
| ty::Int(_)
| ty::RawPtr(_)
| ty::RawPtr(_, _)
| ty::Ref(..)
| ty::Tuple(_)
| ty::Uint(_) => self.codegen_ty(pointee_type).to_pointer(),
Expand Down Expand Up @@ -1352,10 +1352,7 @@ impl<'tcx> GotocCtx<'tcx> {
// `F16` and `F128` are not yet handled.
// Tracked here: <https://github.com/model-checking/kani/issues/3069>
Primitive::F16 | Primitive::F128 => unimplemented!(),
Primitive::Pointer(_) => Ty::new_ptr(
self.tcx,
ty::TypeAndMut { ty: self.tcx.types.u8, mutbl: Mutability::Not },
),
Primitive::Pointer(_) => Ty::new_ptr(self.tcx, self.tcx.types.u8, Mutability::Not),
}
}

Expand Down Expand Up @@ -1659,7 +1656,7 @@ fn common_vtable_fields(drop_in_place: Type) -> Vec<DatatypeComponent> {
pub fn pointee_type(mir_type: Ty) -> Option<Ty> {
match mir_type.kind() {
ty::Ref(_, pointee_type, _) => Some(*pointee_type),
ty::RawPtr(ty::TypeAndMut { ty: pointee_type, .. }) => Some(*pointee_type),
ty::RawPtr(pointee_type, _) => Some(*pointee_type),
_ => None,
}
}
Expand Down
5 changes: 0 additions & 5 deletions kani-compiler/src/codegen_cprover_gotoc/context/goto_ctx.rs
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,6 @@ use crate::kani_queries::QueryDb;
use cbmc::goto_program::{DatatypeComponent, Expr, Location, Stmt, Symbol, SymbolTable, Type};
use cbmc::utils::aggr_tag;
use cbmc::{InternedString, MachineModel};
use kani_metadata::HarnessMetadata;
use rustc_data_structures::fx::FxHashMap;
use rustc_middle::span_bug;
use rustc_middle::ty::layout::{
Expand Down Expand Up @@ -61,8 +60,6 @@ pub struct GotocCtx<'tcx> {
/// map from symbol identifier to string literal
/// TODO: consider making the map from Expr to String instead
pub str_literals: FxHashMap<InternedString, String>,
pub proof_harnesses: Vec<HarnessMetadata>,
pub test_harnesses: Vec<HarnessMetadata>,
/// a global counter for generating unique IDs for checks
pub global_checks_count: u64,
/// A map of unsupported constructs that were found while codegen
Expand Down Expand Up @@ -98,8 +95,6 @@ impl<'tcx> GotocCtx<'tcx> {
current_fn: None,
type_map: FxHashMap::default(),
str_literals: FxHashMap::default(),
proof_harnesses: vec![],
test_harnesses: vec![],
global_checks_count: 0,
unsupported_constructs: FxHashMap::default(),
concurrent_constructs: FxHashMap::default(),
Expand Down
8 changes: 5 additions & 3 deletions kani-compiler/src/kani_middle/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,7 @@ pub mod transform;
/// error was found.
pub fn check_crate_items(tcx: TyCtxt, ignore_asm: bool) {
let krate = tcx.crate_name(LOCAL_CRATE);
for item in tcx.hir_crate_items(()).items() {
for item in tcx.hir().items() {
let def_id = item.owner_id.def_id.to_def_id();
KaniAttributes::for_item(tcx, def_id).check_attributes();
if tcx.def_kind(def_id) == DefKind::GlobalAsm {
Expand Down Expand Up @@ -127,9 +127,11 @@ pub fn dump_mir_items(tcx: TyCtxt, items: &[MonoItem], output: &Path) {
pub struct SourceLocation {
pub filename: String,
pub start_line: usize,
pub start_col: usize,
#[allow(dead_code)]
pub start_col: usize, // set, but not currently used in Goto output
pub end_line: usize,
pub end_col: usize,
#[allow(dead_code)]
pub end_col: usize, // set, but not currently used in Goto output
}

impl SourceLocation {
Expand Down
8 changes: 2 additions & 6 deletions kani-compiler/src/kani_middle/reachability.rs
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,6 @@ use rustc_middle::ty::{TyCtxt, VtblEntry};
use rustc_smir::rustc_internal;
use stable_mir::mir::alloc::{AllocId, GlobalAlloc};
use stable_mir::mir::mono::{Instance, InstanceKind, MonoItem, StaticDef};
use stable_mir::mir::pretty::pretty_ty;
use stable_mir::mir::{
visit::Location, Body, CastKind, Constant, MirVisitor, PointerCoercion, Rvalue, Terminator,
TerminatorKind,
Expand Down Expand Up @@ -434,7 +433,7 @@ impl<'a, 'tcx> MirVisitor for MonoItemsFnCollector<'a, 'tcx> {
`{}`. The function `{}` \
cannot be stubbed by `{}` due to \
generic bounds not being met. Callee: {}",
pretty_ty(receiver_ty.kind()),
receiver_ty,
trait_,
caller,
self.tcx.def_path_str(stub),
Expand All @@ -453,10 +452,7 @@ impl<'a, 'tcx> MirVisitor for MonoItemsFnCollector<'a, 'tcx> {
objects in the modifies clause (including return types) \
implement `{}`.\nThis is a strict condition to use \
function contracts as verified stubs.",
pretty_ty(receiver_ty.kind()),
trait_,
callee,
trait_,
receiver_ty, trait_, callee, trait_,
),
);
} else {
Expand Down
8 changes: 4 additions & 4 deletions kani-compiler/src/kani_middle/transform/body.rs
Original file line number Diff line number Diff line change
Expand Up @@ -173,7 +173,7 @@ impl MutableBody {
let terminator = Terminator { kind, span };
self.split_bb(source, terminator);
}
CheckType::Panic(..) | CheckType::NoCore => {
CheckType::Panic | CheckType::NoCore => {
tcx.sess
.dcx()
.struct_err("Failed to instrument the code. Cannot find `kani::assert`")
Expand Down Expand Up @@ -231,7 +231,7 @@ pub enum CheckType {
/// This is used by default when the `kani` crate is available.
Assert(Instance),
/// When the `kani` crate is not available, we have to model the check as an `if { panic!() }`.
Panic(Instance),
Panic,
/// When building non-core crate, such as `rustc-std-workspace-core`, we cannot
/// instrument code, but we can still compile them.
NoCore,
Expand All @@ -246,8 +246,8 @@ impl CheckType {
pub fn new(tcx: TyCtxt) -> CheckType {
if let Some(instance) = find_instance(tcx, "KaniAssert") {
CheckType::Assert(instance)
} else if let Some(instance) = find_instance(tcx, "panic_str") {
CheckType::Panic(instance)
} else if find_instance(tcx, "panic_str").is_some() {
CheckType::Panic
} else {
CheckType::NoCore
}
Expand Down
11 changes: 2 additions & 9 deletions kani-driver/src/call_cbmc.rs
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ use std::time::{Duration, Instant};

use crate::args::{OutputFormat, VerificationArgs};
use crate::cbmc_output_parser::{
extract_results, process_cbmc_output, CheckStatus, ParserItem, Property, VerificationOutput,
extract_results, process_cbmc_output, CheckStatus, Property, VerificationOutput,
};
use crate::cbmc_property_renderer::{format_coverage, format_result, kani_cbmc_output_filter};
use crate::session::KaniSession;
Expand Down Expand Up @@ -45,9 +45,6 @@ pub struct VerificationResult {
pub status: VerificationStatus,
/// The compact representation for failed properties
pub failed_properties: FailedProperties,
/// The parsed output, message by message, of CBMC. However, the `Result` message has been
/// removed and is available in `results` instead.
pub messages: Option<Vec<ParserItem>>,
/// The `Result` properties in detail or the exit_status of CBMC.
/// Note: CBMC process exit status is only potentially useful if `status` is `Failure`.
/// Kani will see CBMC report "failure" that's actually success (interpreting "failed"
Expand Down Expand Up @@ -254,15 +251,14 @@ impl VerificationResult {
start_time: Instant,
) -> VerificationResult {
let runtime = start_time.elapsed();
let (items, results) = extract_results(output.processed_items);
let (_, results) = extract_results(output.processed_items);

if let Some(results) = results {
let (status, failed_properties) =
verification_outcome_from_properties(&results, should_panic);
VerificationResult {
status,
failed_properties,
messages: Some(items),
results: Ok(results),
runtime,
generated_concrete_test: false,
Expand All @@ -272,7 +268,6 @@ impl VerificationResult {
VerificationResult {
status: VerificationStatus::Failure,
failed_properties: FailedProperties::Other,
messages: Some(items),
results: Err(output.process_status),
runtime,
generated_concrete_test: false,
Expand All @@ -284,7 +279,6 @@ impl VerificationResult {
VerificationResult {
status: VerificationStatus::Success,
failed_properties: FailedProperties::None,
messages: None,
results: Ok(vec![]),
runtime: Duration::from_secs(0),
generated_concrete_test: false,
Expand All @@ -295,7 +289,6 @@ impl VerificationResult {
VerificationResult {
status: VerificationStatus::Failure,
failed_properties: FailedProperties::Other,
messages: None,
// on failure, exit codes in theory might be used,
// but `mock_failure` should never be used in a context where they will,
// so again use something weird:
Expand Down
3 changes: 0 additions & 3 deletions kani-driver/src/cbmc_output_parser.rs
Original file line number Diff line number Diff line change
Expand Up @@ -287,9 +287,7 @@ fn filepath(file: String) -> String {
#[derive(Clone, Debug, Deserialize)]
#[serde(rename_all = "camelCase")]
pub struct TraceItem {
pub thread: u32,
pub step_type: String,
pub hidden: bool,
pub lhs: Option<String>,
pub source_location: Option<SourceLocation>,
pub value: Option<TraceValue>,
Expand All @@ -301,7 +299,6 @@ pub struct TraceItem {
/// The fields included right now are relevant to primitive types.
#[derive(Clone, Debug, Deserialize)]
pub struct TraceValue {
pub name: String,
pub binary: Option<String>,
pub data: Option<TraceData>,
pub width: Option<u32>,
Expand Down
3 changes: 0 additions & 3 deletions kani-driver/src/concrete_playback/test_generator.rs
Original file line number Diff line number Diff line change
Expand Up @@ -588,9 +588,7 @@ mod tests {
line: None,
},
trace: Some(vec![TraceItem {
thread: 0,
step_type: "assignment".to_string(),
hidden: false,
lhs: Some("goto_symex$$return_value".to_string()),
source_location: Some(SourceLocation {
column: None,
Expand All @@ -599,7 +597,6 @@ mod tests {
line: None,
}),
value: Some(TraceValue {
name: "".to_string(),
binary: Some("0000001100000001".to_string()),
data: Some(TraceData::NonBool("385".to_string())),
width: Some(16),
Expand Down
2 changes: 1 addition & 1 deletion rust-toolchain.toml
Original file line number Diff line number Diff line change
Expand Up @@ -2,5 +2,5 @@
# SPDX-License-Identifier: Apache-2.0 OR MIT

[toolchain]
channel = "nightly-2024-03-21"
channel = "nightly-2024-03-29"
components = ["llvm-tools-preview", "rustc-dev", "rust-src", "rustfmt"]
21 changes: 21 additions & 0 deletions tests/kani/Intrinsics/typed_swap.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
// Copyright Kani Contributors
// SPDX-License-Identifier: Apache-2.0 OR MIT

// Check that `typed_swap` yields the expected results.
// https://doc.rust-lang.org/nightly/std/intrinsics/fn.typed_swap.html

#![feature(core_intrinsics)]
#![allow(internal_features)]

#[kani::proof]
fn test_typed_swap_u32() {
let mut a: u32 = kani::any();
let a_before = a;
let mut b: u32 = kani::any();
let b_before = b;
unsafe {
std::intrinsics::typed_swap(&mut a, &mut b);
}
assert!(b == a_before);
assert!(a == b_before);
}
Loading