Skip to content

Commit a589e57

Browse files
Upgrade Rust toolchain to nightly-2024-03-29 (rust-lang#3116)
Resolves model-checking/kani#3115. Co-authored-by: Michael Tautschnig <[email protected]>
1 parent 36bf7c8 commit a589e57

File tree

13 files changed

+83
-42
lines changed

13 files changed

+83
-42
lines changed

docs/src/rust-feature-support/intrinsics.md

+1
Original file line numberDiff line numberDiff line change
@@ -220,6 +220,7 @@ truncf64 | Yes | |
220220
try | No | [#267](https://github.com/model-checking/kani/issues/267) |
221221
type_id | Yes | |
222222
type_name | Yes | |
223+
typed_swap | Yes | |
223224
unaligned_volatile_load | No | See [Notes - Concurrency](#concurrency) |
224225
unaligned_volatile_store | No | See [Notes - Concurrency](#concurrency) |
225226
unchecked_add | Yes | |

kani-compiler/src/codegen_cprover_gotoc/codegen/intrinsic.rs

+42
Original file line numberDiff line numberDiff line change
@@ -580,6 +580,7 @@ impl<'tcx> GotocCtx<'tcx> {
580580
"truncf64" => codegen_simple_intrinsic!(Trunc),
581581
"type_id" => codegen_intrinsic_const!(),
582582
"type_name" => codegen_intrinsic_const!(),
583+
"typed_swap" => self.codegen_swap(fargs, farg_types, loc),
583584
"unaligned_volatile_load" => {
584585
unstable_codegen!(
585586
self.codegen_expr_to_place_stable(place, fargs.remove(0).dereference())
@@ -1943,6 +1944,47 @@ impl<'tcx> GotocCtx<'tcx> {
19431944
let zero = Type::size_t().zero();
19441945
cast_ptr.rem(align).eq(zero)
19451946
}
1947+
1948+
/// Swaps the memory contents pointed to by arguments `x` and `y`, respectively, which is
1949+
/// required for the `typed_swap` intrinsic.
1950+
///
1951+
/// The standard library API requires that `x` and `y` are readable and writable as their
1952+
/// (common) type (which auto-generated checks for dereferencing will take care of), and the
1953+
/// memory regions pointed to must be non-overlapping.
1954+
pub fn codegen_swap(&mut self, mut fargs: Vec<Expr>, farg_types: &[Ty], loc: Location) -> Stmt {
1955+
// two parameters, and both must be raw pointers with the same base type
1956+
assert!(fargs.len() == 2);
1957+
assert!(farg_types[0].kind().is_raw_ptr());
1958+
assert!(farg_types[0] == farg_types[1]);
1959+
1960+
let x = fargs.remove(0);
1961+
let y = fargs.remove(0);
1962+
1963+
// if(same_object(x, y)) {
1964+
// assert(x + 1 <= y || y + 1 <= x);
1965+
// assume(x + 1 <= y || y + 1 <= x);
1966+
// }
1967+
let one = Expr::int_constant(1, Type::c_int());
1968+
let non_overlapping =
1969+
x.clone().plus(one.clone()).le(y.clone()).or(y.clone().plus(one.clone()).le(x.clone()));
1970+
let non_overlapping_check = self.codegen_assert_assume(
1971+
non_overlapping,
1972+
PropertyClass::SafetyCheck,
1973+
"memory regions pointed to by `x` and `y` must not overlap",
1974+
loc,
1975+
);
1976+
let non_overlapping_stmt =
1977+
Stmt::if_then_else(x.clone().same_object(y.clone()), non_overlapping_check, None, loc);
1978+
1979+
// T t = *y; *y = *x; *x = t;
1980+
let deref_y = y.clone().dereference();
1981+
let (temp_var, assign_to_t) =
1982+
self.decl_temp_variable(deref_y.typ().clone(), Some(deref_y), loc);
1983+
let assign_to_y = y.dereference().assign(x.clone().dereference(), loc);
1984+
let assign_to_x = x.dereference().assign(temp_var, loc);
1985+
1986+
Stmt::block(vec![non_overlapping_stmt, assign_to_t, assign_to_y, assign_to_x], loc)
1987+
}
19461988
}
19471989

19481990
fn instance_args(instance: &Instance) -> GenericArgs {

kani-compiler/src/codegen_cprover_gotoc/codegen/rvalue.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -725,7 +725,7 @@ impl<'tcx> GotocCtx<'tcx> {
725725
.bytes(),
726726
Type::size_t(),
727727
),
728-
NullOp::UbCheck(_) => Expr::c_false(),
728+
NullOp::UbChecks => Expr::c_false(),
729729
}
730730
}
731731
Rvalue::ShallowInitBox(ref operand, content_ty) => {

kani-compiler/src/codegen_cprover_gotoc/codegen/typ.rs

+4-7
Original file line numberDiff line numberDiff line change
@@ -570,7 +570,7 @@ impl<'tcx> GotocCtx<'tcx> {
570570
// Note: This is not valid C but CBMC seems to be ok with it.
571571
ty::Slice(e) => self.codegen_ty(*e).flexible_array_of(),
572572
ty::Str => Type::unsigned_int(8).flexible_array_of(),
573-
ty::Ref(_, t, _) | ty::RawPtr(ty::TypeAndMut { ty: t, .. }) => self.codegen_ty_ref(*t),
573+
ty::Ref(_, t, _) | ty::RawPtr(t, _) => self.codegen_ty_ref(*t),
574574
ty::FnDef(def_id, args) => {
575575
let instance =
576576
Instance::resolve(self.tcx, ty::ParamEnv::reveal_all(), *def_id, args)
@@ -993,7 +993,7 @@ impl<'tcx> GotocCtx<'tcx> {
993993
| ty::Foreign(_)
994994
| ty::Coroutine(..)
995995
| ty::Int(_)
996-
| ty::RawPtr(_)
996+
| ty::RawPtr(_, _)
997997
| ty::Ref(..)
998998
| ty::Tuple(_)
999999
| ty::Uint(_) => self.codegen_ty(pointee_type).to_pointer(),
@@ -1352,10 +1352,7 @@ impl<'tcx> GotocCtx<'tcx> {
13521352
// `F16` and `F128` are not yet handled.
13531353
// Tracked here: <https://github.com/model-checking/kani/issues/3069>
13541354
Primitive::F16 | Primitive::F128 => unimplemented!(),
1355-
Primitive::Pointer(_) => Ty::new_ptr(
1356-
self.tcx,
1357-
ty::TypeAndMut { ty: self.tcx.types.u8, mutbl: Mutability::Not },
1358-
),
1355+
Primitive::Pointer(_) => Ty::new_ptr(self.tcx, self.tcx.types.u8, Mutability::Not),
13591356
}
13601357
}
13611358

@@ -1659,7 +1656,7 @@ fn common_vtable_fields(drop_in_place: Type) -> Vec<DatatypeComponent> {
16591656
pub fn pointee_type(mir_type: Ty) -> Option<Ty> {
16601657
match mir_type.kind() {
16611658
ty::Ref(_, pointee_type, _) => Some(*pointee_type),
1662-
ty::RawPtr(ty::TypeAndMut { ty: pointee_type, .. }) => Some(*pointee_type),
1659+
ty::RawPtr(pointee_type, _) => Some(*pointee_type),
16631660
_ => None,
16641661
}
16651662
}

kani-compiler/src/codegen_cprover_gotoc/context/goto_ctx.rs

-5
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,6 @@ use crate::kani_queries::QueryDb;
2323
use cbmc::goto_program::{DatatypeComponent, Expr, Location, Stmt, Symbol, SymbolTable, Type};
2424
use cbmc::utils::aggr_tag;
2525
use cbmc::{InternedString, MachineModel};
26-
use kani_metadata::HarnessMetadata;
2726
use rustc_data_structures::fx::FxHashMap;
2827
use rustc_middle::span_bug;
2928
use rustc_middle::ty::layout::{
@@ -61,8 +60,6 @@ pub struct GotocCtx<'tcx> {
6160
/// map from symbol identifier to string literal
6261
/// TODO: consider making the map from Expr to String instead
6362
pub str_literals: FxHashMap<InternedString, String>,
64-
pub proof_harnesses: Vec<HarnessMetadata>,
65-
pub test_harnesses: Vec<HarnessMetadata>,
6663
/// a global counter for generating unique IDs for checks
6764
pub global_checks_count: u64,
6865
/// A map of unsupported constructs that were found while codegen
@@ -98,8 +95,6 @@ impl<'tcx> GotocCtx<'tcx> {
9895
current_fn: None,
9996
type_map: FxHashMap::default(),
10097
str_literals: FxHashMap::default(),
101-
proof_harnesses: vec![],
102-
test_harnesses: vec![],
10398
global_checks_count: 0,
10499
unsupported_constructs: FxHashMap::default(),
105100
concurrent_constructs: FxHashMap::default(),

kani-compiler/src/kani_middle/mod.rs

+5-3
Original file line numberDiff line numberDiff line change
@@ -46,7 +46,7 @@ pub mod transform;
4646
/// error was found.
4747
pub fn check_crate_items(tcx: TyCtxt, ignore_asm: bool) {
4848
let krate = tcx.crate_name(LOCAL_CRATE);
49-
for item in tcx.hir_crate_items(()).items() {
49+
for item in tcx.hir().items() {
5050
let def_id = item.owner_id.def_id.to_def_id();
5151
KaniAttributes::for_item(tcx, def_id).check_attributes();
5252
if tcx.def_kind(def_id) == DefKind::GlobalAsm {
@@ -127,9 +127,11 @@ pub fn dump_mir_items(tcx: TyCtxt, items: &[MonoItem], output: &Path) {
127127
pub struct SourceLocation {
128128
pub filename: String,
129129
pub start_line: usize,
130-
pub start_col: usize,
130+
#[allow(dead_code)]
131+
pub start_col: usize, // set, but not currently used in Goto output
131132
pub end_line: usize,
132-
pub end_col: usize,
133+
#[allow(dead_code)]
134+
pub end_col: usize, // set, but not currently used in Goto output
133135
}
134136

135137
impl SourceLocation {

kani-compiler/src/kani_middle/reachability.rs

+2-6
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,6 @@ use rustc_middle::ty::{TyCtxt, VtblEntry};
2525
use rustc_smir::rustc_internal;
2626
use stable_mir::mir::alloc::{AllocId, GlobalAlloc};
2727
use stable_mir::mir::mono::{Instance, InstanceKind, MonoItem, StaticDef};
28-
use stable_mir::mir::pretty::pretty_ty;
2928
use stable_mir::mir::{
3029
visit::Location, Body, CastKind, Constant, MirVisitor, PointerCoercion, Rvalue, Terminator,
3130
TerminatorKind,
@@ -434,7 +433,7 @@ impl<'a, 'tcx> MirVisitor for MonoItemsFnCollector<'a, 'tcx> {
434433
`{}`. The function `{}` \
435434
cannot be stubbed by `{}` due to \
436435
generic bounds not being met. Callee: {}",
437-
pretty_ty(receiver_ty.kind()),
436+
receiver_ty,
438437
trait_,
439438
caller,
440439
self.tcx.def_path_str(stub),
@@ -453,10 +452,7 @@ impl<'a, 'tcx> MirVisitor for MonoItemsFnCollector<'a, 'tcx> {
453452
objects in the modifies clause (including return types) \
454453
implement `{}`.\nThis is a strict condition to use \
455454
function contracts as verified stubs.",
456-
pretty_ty(receiver_ty.kind()),
457-
trait_,
458-
callee,
459-
trait_,
455+
receiver_ty, trait_, callee, trait_,
460456
),
461457
);
462458
} else {

kani-compiler/src/kani_middle/transform/body.rs

+4-4
Original file line numberDiff line numberDiff line change
@@ -173,7 +173,7 @@ impl MutableBody {
173173
let terminator = Terminator { kind, span };
174174
self.split_bb(source, terminator);
175175
}
176-
CheckType::Panic(..) | CheckType::NoCore => {
176+
CheckType::Panic | CheckType::NoCore => {
177177
tcx.sess
178178
.dcx()
179179
.struct_err("Failed to instrument the code. Cannot find `kani::assert`")
@@ -231,7 +231,7 @@ pub enum CheckType {
231231
/// This is used by default when the `kani` crate is available.
232232
Assert(Instance),
233233
/// When the `kani` crate is not available, we have to model the check as an `if { panic!() }`.
234-
Panic(Instance),
234+
Panic,
235235
/// When building non-core crate, such as `rustc-std-workspace-core`, we cannot
236236
/// instrument code, but we can still compile them.
237237
NoCore,
@@ -246,8 +246,8 @@ impl CheckType {
246246
pub fn new(tcx: TyCtxt) -> CheckType {
247247
if let Some(instance) = find_instance(tcx, "KaniAssert") {
248248
CheckType::Assert(instance)
249-
} else if let Some(instance) = find_instance(tcx, "panic_str") {
250-
CheckType::Panic(instance)
249+
} else if find_instance(tcx, "panic_str").is_some() {
250+
CheckType::Panic
251251
} else {
252252
CheckType::NoCore
253253
}

kani-driver/src/call_cbmc.rs

+2-9
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ use std::time::{Duration, Instant};
1111

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

259256
if let Some(results) = results {
260257
let (status, failed_properties) =
261258
verification_outcome_from_properties(&results, should_panic);
262259
VerificationResult {
263260
status,
264261
failed_properties,
265-
messages: Some(items),
266262
results: Ok(results),
267263
runtime,
268264
generated_concrete_test: false,
@@ -272,7 +268,6 @@ impl VerificationResult {
272268
VerificationResult {
273269
status: VerificationStatus::Failure,
274270
failed_properties: FailedProperties::Other,
275-
messages: Some(items),
276271
results: Err(output.process_status),
277272
runtime,
278273
generated_concrete_test: false,
@@ -284,7 +279,6 @@ impl VerificationResult {
284279
VerificationResult {
285280
status: VerificationStatus::Success,
286281
failed_properties: FailedProperties::None,
287-
messages: None,
288282
results: Ok(vec![]),
289283
runtime: Duration::from_secs(0),
290284
generated_concrete_test: false,
@@ -295,7 +289,6 @@ impl VerificationResult {
295289
VerificationResult {
296290
status: VerificationStatus::Failure,
297291
failed_properties: FailedProperties::Other,
298-
messages: None,
299292
// on failure, exit codes in theory might be used,
300293
// but `mock_failure` should never be used in a context where they will,
301294
// so again use something weird:

kani-driver/src/cbmc_output_parser.rs

-3
Original file line numberDiff line numberDiff line change
@@ -287,9 +287,7 @@ fn filepath(file: String) -> String {
287287
#[derive(Clone, Debug, Deserialize)]
288288
#[serde(rename_all = "camelCase")]
289289
pub struct TraceItem {
290-
pub thread: u32,
291290
pub step_type: String,
292-
pub hidden: bool,
293291
pub lhs: Option<String>,
294292
pub source_location: Option<SourceLocation>,
295293
pub value: Option<TraceValue>,
@@ -301,7 +299,6 @@ pub struct TraceItem {
301299
/// The fields included right now are relevant to primitive types.
302300
#[derive(Clone, Debug, Deserialize)]
303301
pub struct TraceValue {
304-
pub name: String,
305302
pub binary: Option<String>,
306303
pub data: Option<TraceData>,
307304
pub width: Option<u32>,

kani-driver/src/concrete_playback/test_generator.rs

-3
Original file line numberDiff line numberDiff line change
@@ -588,9 +588,7 @@ mod tests {
588588
line: None,
589589
},
590590
trace: Some(vec![TraceItem {
591-
thread: 0,
592591
step_type: "assignment".to_string(),
593-
hidden: false,
594592
lhs: Some("goto_symex$$return_value".to_string()),
595593
source_location: Some(SourceLocation {
596594
column: None,
@@ -599,7 +597,6 @@ mod tests {
599597
line: None,
600598
}),
601599
value: Some(TraceValue {
602-
name: "".to_string(),
603600
binary: Some("0000001100000001".to_string()),
604601
data: Some(TraceData::NonBool("385".to_string())),
605602
width: Some(16),

rust-toolchain.toml

+1-1
Original file line numberDiff line numberDiff line change
@@ -2,5 +2,5 @@
22
# SPDX-License-Identifier: Apache-2.0 OR MIT
33

44
[toolchain]
5-
channel = "nightly-2024-03-21"
5+
channel = "nightly-2024-03-29"
66
components = ["llvm-tools-preview", "rustc-dev", "rust-src", "rustfmt"]

tests/kani/Intrinsics/typed_swap.rs

+21
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
// Copyright Kani Contributors
2+
// SPDX-License-Identifier: Apache-2.0 OR MIT
3+
4+
// Check that `typed_swap` yields the expected results.
5+
// https://doc.rust-lang.org/nightly/std/intrinsics/fn.typed_swap.html
6+
7+
#![feature(core_intrinsics)]
8+
#![allow(internal_features)]
9+
10+
#[kani::proof]
11+
fn test_typed_swap_u32() {
12+
let mut a: u32 = kani::any();
13+
let a_before = a;
14+
let mut b: u32 = kani::any();
15+
let b_before = b;
16+
unsafe {
17+
std::intrinsics::typed_swap(&mut a, &mut b);
18+
}
19+
assert!(b == a_before);
20+
assert!(a == b_before);
21+
}

0 commit comments

Comments
 (0)