Skip to content

Commit 08659d3

Browse files
authored
Update rust toolchain to 2023-04-29 (#2452)
1 parent 19b7a7d commit 08659d3

File tree

15 files changed

+71
-35
lines changed

15 files changed

+71
-35
lines changed

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

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -504,7 +504,10 @@ impl<'tcx> GotocCtx<'tcx> {
504504
"nearbyintf32" => codegen_simple_intrinsic!(Nearbyintf),
505505
"nearbyintf64" => codegen_simple_intrinsic!(Nearbyint),
506506
"needs_drop" => codegen_intrinsic_const!(),
507-
"offset" => self.codegen_offset(intrinsic, instance, fargs, p, loc),
507+
// As of https://github.com/rust-lang/rust/pull/110822 the `offset` intrinsic is lowered to `mir::BinOp::Offset`
508+
"offset" => unreachable!(
509+
"Expected `core::intrinsics::unreachable` to be handled by `BinOp::OffSet`"
510+
),
508511
"powf32" => unstable_codegen!(codegen_simple_intrinsic!(Powf)),
509512
"powf64" => unstable_codegen!(codegen_simple_intrinsic!(Pow)),
510513
"powif32" => unstable_codegen!(codegen_simple_intrinsic!(Powif)),
@@ -1729,7 +1732,7 @@ impl<'tcx> GotocCtx<'tcx> {
17291732
/// Returns a tuple with:
17301733
/// * The result expression of the computation.
17311734
/// * An assertion statement to ensure the operation has not overflowed.
1732-
fn count_in_bytes(
1735+
pub fn count_in_bytes(
17331736
&mut self,
17341737
count: Expr,
17351738
ty: Ty<'tcx>,

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

Lines changed: 33 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@ use cbmc::MachineModel;
1818
use cbmc::{btree_string_map, InternString, InternedString};
1919
use num::bigint::BigInt;
2020
use rustc_abi::FieldIdx;
21-
use rustc_index::vec::IndexVec;
21+
use rustc_index::IndexVec;
2222
use rustc_middle::mir::{AggregateKind, BinOp, CastKind, NullOp, Operand, Place, Rvalue, UnOp};
2323
use rustc_middle::ty::adjustment::PointerCast;
2424
use rustc_middle::ty::layout::LayoutOf;
@@ -294,6 +294,7 @@ impl<'tcx> GotocCtx<'tcx> {
294294

295295
fn codegen_rvalue_binary_op(
296296
&mut self,
297+
ty: Ty<'tcx>,
297298
op: &BinOp,
298299
e1: &Operand<'tcx>,
299300
e2: &Operand<'tcx>,
@@ -317,7 +318,32 @@ impl<'tcx> GotocCtx<'tcx> {
317318
BinOp::Offset => {
318319
let ce1 = self.codegen_operand(e1);
319320
let ce2 = self.codegen_operand(e2);
320-
ce1.plus(ce2)
321+
322+
// Check that computing `offset` in bytes would not overflow
323+
let (offset_bytes, bytes_overflow_check) = self.count_in_bytes(
324+
ce2.clone().cast_to(Type::ssize_t()),
325+
ty,
326+
Type::ssize_t(),
327+
"offset",
328+
loc,
329+
);
330+
331+
// Check that the computation would not overflow an `isize` which is UB:
332+
// https://doc.rust-lang.org/std/primitive.pointer.html#method.offset
333+
// These checks may allow a wrapping-around behavior in CBMC:
334+
// https://github.com/model-checking/kani/issues/1150
335+
let overflow_res = ce1.clone().cast_to(Type::ssize_t()).add_overflow(offset_bytes);
336+
let overflow_check = self.codegen_assert_assume(
337+
overflow_res.overflowed.not(),
338+
PropertyClass::ArithmeticOverflow,
339+
"attempt to compute offset which would overflow",
340+
loc,
341+
);
342+
let res = ce1.clone().plus(ce2);
343+
Expr::statement_expression(
344+
vec![bytes_overflow_check, overflow_check, res.as_stmt(loc)],
345+
ce1.typ().clone(),
346+
)
321347
}
322348
}
323349
}
@@ -548,7 +574,7 @@ impl<'tcx> GotocCtx<'tcx> {
548574
self.codegen_operand(operand).transmute_to(goto_typ, &self.symbol_table)
549575
}
550576
Rvalue::BinaryOp(op, box (ref e1, ref e2)) => {
551-
self.codegen_rvalue_binary_op(op, e1, e2, loc)
577+
self.codegen_rvalue_binary_op(res_ty, op, e1, e2, loc)
552578
}
553579
Rvalue::CheckedBinaryOp(op, box (ref e1, ref e2)) => {
554580
self.codegen_rvalue_checked_binary_op(op, e1, e2, res_ty)
@@ -560,6 +586,10 @@ impl<'tcx> GotocCtx<'tcx> {
560586
NullOp::SizeOf => Expr::int_constant(layout.size.bytes_usize(), Type::size_t())
561587
.with_size_of_annotation(self.codegen_ty(t)),
562588
NullOp::AlignOf => Expr::int_constant(layout.align.abi.bytes(), Type::size_t()),
589+
NullOp::OffsetOf(fields) => Expr::int_constant(
590+
layout.offset_of_subfield(self, fields.iter().map(|f| f.index())).bytes(),
591+
Type::size_t(),
592+
),
563593
}
564594
}
565595
Rvalue::ShallowInitBox(ref operand, content_ty) => {

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

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ use cbmc::utils::aggr_tag;
77
use cbmc::{InternString, InternedString};
88
use rustc_ast::ast::Mutability;
99
use rustc_hir::{LangItem, Unsafety};
10-
use rustc_index::vec::IndexVec;
10+
use rustc_index::IndexVec;
1111
use rustc_middle::mir::{HasLocalDecls, Local, Operand, Place, Rvalue};
1212
use rustc_middle::ty::layout::LayoutOf;
1313
use rustc_middle::ty::print::with_no_trimmed_paths;
@@ -666,7 +666,7 @@ impl<'tcx> GotocCtx<'tcx> {
666666
}
667667
_ => {
668668
// This hash is documented to be the same no matter the crate context
669-
let id_u64 = self.tcx.type_id_hash(t);
669+
let id_u64 = self.tcx.type_id_hash(t).as_u64();
670670
format!("_{id_u64}").intern()
671671
}
672672
}

kani-compiler/src/kani_middle/metadata.rs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ use std::path::Path;
88
use crate::kani_middle::attributes::test_harness_name;
99
use kani_metadata::{ArtifactType, HarnessAttributes, HarnessMetadata};
1010
use rustc_hir::def_id::DefId;
11-
use rustc_middle::ty::{Instance, InstanceDef, TyCtxt, WithOptConstParam};
11+
use rustc_middle::ty::{Instance, InstanceDef, TyCtxt};
1212

1313
use super::{attributes::extract_harness_attributes, SourceLocation};
1414

@@ -24,7 +24,7 @@ pub fn gen_proof_metadata(tcx: TyCtxt, def_id: DefId, base_name: &Path) -> Harne
2424
tcx.symbol_name(Instance::mono(tcx, def_id)).to_string()
2525
};
2626

27-
let body = tcx.instance_mir(InstanceDef::Item(WithOptConstParam::unknown(def_id)));
27+
let body = tcx.instance_mir(InstanceDef::Item(def_id));
2828
let loc = SourceLocation::new(tcx, &body.span);
2929
let file_stem = format!("{}_{mangled_name}", base_name.file_stem().unwrap().to_str().unwrap());
3030
let model_file = base_name.with_file_name(file_stem).with_extension(ArtifactType::SymTabGoto);
@@ -52,7 +52,7 @@ pub fn gen_test_metadata<'tcx>(
5252
) -> HarnessMetadata {
5353
let pretty_name = test_harness_name(tcx, test_desc);
5454
let mangled_name = tcx.symbol_name(test_fn).to_string();
55-
let body = tcx.instance_mir(InstanceDef::Item(WithOptConstParam::unknown(test_desc)));
55+
let body = tcx.instance_mir(InstanceDef::Item(test_desc));
5656
let loc = SourceLocation::new(tcx, &body.span);
5757
let file_stem = format!("{}_{mangled_name}", base_name.file_stem().unwrap().to_str().unwrap());
5858
let model_file = base_name.with_file_name(file_stem).with_extension(ArtifactType::SymTabGoto);

kani-compiler/src/kani_middle/reachability.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,7 @@ use rustc_middle::span_bug;
3131
use rustc_middle::ty::adjustment::PointerCast;
3232
use rustc_middle::ty::{
3333
Closure, ClosureKind, ConstKind, Instance, InstanceDef, ParamEnv, Ty, TyCtxt, TyKind,
34-
TypeFoldable, VtblEntry, WithOptConstParam,
34+
TypeFoldable, VtblEntry,
3535
};
3636

3737
use crate::kani_middle::coercion;
@@ -111,7 +111,7 @@ where
111111
let def_kind = tcx.def_kind(def_id);
112112
if matches!(def_kind, DefKind::Const) && predicate(tcx, def_id) {
113113
let instance = Instance::mono(tcx, def_id);
114-
let body = tcx.instance_mir(InstanceDef::Item(WithOptConstParam::unknown(def_id)));
114+
let body = tcx.instance_mir(InstanceDef::Item(def_id));
115115
let mut collector =
116116
MonoItemsFnCollector { tcx, body, instance, collected: FxHashSet::default() };
117117
collector.visit_body(body);

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

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -118,8 +118,10 @@ pub fn mk_rustc_arg(stub_mapping: &FxHashMap<DefPathHash, DefPathHash>) -> Strin
118118
// as an association list.
119119
let mut pairs = Vec::new();
120120
for (k, v) in stub_mapping {
121-
let kparts = k.0.as_value();
122-
let vparts = v.0.as_value();
121+
let (k_a, k_b) = k.0.split();
122+
let kparts = (k_a.as_u64(), k_b.as_u64());
123+
let (v_a, v_b) = v.0.split();
124+
let vparts = (v_a.as_u64(), v_b.as_u64());
123125
pairs.push((kparts, vparts));
124126
}
125127
// Store our serialized mapping as a fake LLVM argument (safe to do since

kani-driver/src/cbmc_property_renderer.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -535,7 +535,7 @@ fn has_unwinding_assertion_failures(properties: &Vec<Property>) -> bool {
535535
/// definition.
536536
fn modify_undefined_function_checks(mut properties: Vec<Property>) -> (Vec<Property>, bool) {
537537
let mut has_unknown_location_checks = false;
538-
for mut prop in &mut properties {
538+
for prop in &mut properties {
539539
if let Some(function) = &prop.source_location.function
540540
&& prop.description == DEFAULT_ASSERTION
541541
&& prop.source_location.file.is_none()

rust-toolchain.toml

Lines changed: 1 addition & 1 deletion
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-2023-04-16"
5+
channel = "nightly-2023-04-29"
66
components = ["llvm-tools-preview", "rustc-dev", "rust-src", "rustfmt"]

tests/expected/offset-from-bytes-overflow/main.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ use std::convert::TryInto;
99
fn main() {
1010
let v: &[u128] = &[0; 10];
1111
let v_0: *const u128 = &v[0];
12-
let high_offset = usize::MAX / (std::mem::size_of::<u128>() * 2);
12+
let high_offset = usize::MAX / (std::mem::size_of::<u128>());
1313
unsafe {
1414
let v_wrap: *const u128 = v_0.add(high_offset.try_into().unwrap());
1515
let _ = v_wrap.offset_from(v_0);

tests/expected/offset-i32-fail/main.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,6 @@ fn test_offset() {
1212
let ptr: *const i32 = arr.as_ptr();
1313

1414
unsafe {
15-
let x = *offset(ptr, 3);
15+
let x = *offset(ptr, 3isize);
1616
}
1717
}

tests/expected/offset-overflow/main.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,6 @@ fn test_offset_overflow() {
1212
let ptr: *const u8 = s.as_ptr();
1313

1414
unsafe {
15-
let _ = offset(ptr, isize::MAX);
15+
let _d = offset(ptr, isize::MAX / 8);
1616
}
1717
}

tests/expected/offset-u8-fail/main.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,6 @@ fn test_offset() {
1212
let ptr: *const u8 = s.as_ptr();
1313

1414
unsafe {
15-
let x = *offset(ptr, 3) as char;
15+
let x = *offset(ptr, 3isize) as char;
1616
}
1717
}

tests/kani/Intrinsics/Offset/offset_i32_ok.rs

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -11,10 +11,10 @@ fn test_offset() {
1111
let ptr: *const i32 = arr.as_ptr();
1212

1313
unsafe {
14-
assert_eq!(*offset(ptr, 0), 1);
15-
assert_eq!(*offset(ptr, 1), 2);
16-
assert_eq!(*offset(ptr, 2), 3);
17-
assert_eq!(*offset(ptr, 2).sub(1), 2);
14+
assert_eq!(*offset(ptr, 0isize), 1);
15+
assert_eq!(*offset(ptr, 1isize), 2);
16+
assert_eq!(*offset(ptr, 2isize), 3);
17+
assert_eq!(*offset(ptr, 2isize).sub(1), 2);
1818

1919
// This wouldn't be okay because it's
2020
// more than one byte past the object
@@ -24,8 +24,8 @@ fn test_offset() {
2424
// that goes 1 element behind the original one
2525
let other_ptr: *const i32 = ptr.add(1);
2626

27-
assert_eq!(*offset(other_ptr, 0), 2);
28-
assert_eq!(*offset(other_ptr, 1), 3);
29-
assert_eq!(*offset(other_ptr, 1).sub(1), 2);
27+
assert_eq!(*offset(other_ptr, 0isize), 2);
28+
assert_eq!(*offset(other_ptr, 1isize), 3);
29+
assert_eq!(*offset(other_ptr, 1isize).sub(1), 2);
3030
}
3131
}

tests/kani/Intrinsics/Offset/offset_u8_ok.rs

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -11,21 +11,21 @@ fn test_offset() {
1111
let ptr: *const u8 = s.as_ptr();
1212

1313
unsafe {
14-
assert_eq!(*offset(ptr, 0) as char, '1');
15-
assert_eq!(*offset(ptr, 1) as char, '2');
16-
assert_eq!(*offset(ptr, 2) as char, '3');
17-
assert_eq!(*offset(ptr, 2).sub(1) as char, '2');
14+
assert_eq!(*offset(ptr, 0isize) as char, '1');
15+
assert_eq!(*offset(ptr, 1isize) as char, '2');
16+
assert_eq!(*offset(ptr, 2isize) as char, '3');
17+
assert_eq!(*offset(ptr, 2isize).sub(1) as char, '2');
1818

1919
// This is okay because it's one byte past the object,
2020
// but dereferencing it is UB
21-
let _x = offset(ptr, 3);
21+
let _x = offset(ptr, 3isize);
2222

2323
// Check that the results are the same with a pointer
2424
// that goes 1 element behind the original one
2525
let other_ptr: *const u8 = ptr.add(1);
2626

27-
assert_eq!(*offset(other_ptr, 0) as char, '2');
28-
assert_eq!(*offset(other_ptr, 1) as char, '3');
29-
assert_eq!(*offset(other_ptr, 1).sub(1) as char, '2');
27+
assert_eq!(*offset(other_ptr, 0isize) as char, '2');
28+
assert_eq!(*offset(other_ptr, 1isize) as char, '3');
29+
assert_eq!(*offset(other_ptr, 1isize).sub(1) as char, '2');
3030
}
3131
}

tests/script-based-pre/check-output/singlefile.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ pub fn main() {
1111
monomorphize::<usize>();
1212
let x = [true; 2];
1313
let ref_to_str = &"";
14+
assert!(ref_to_str.is_empty());
1415
let test_enum = TestEnum::Variant1(true);
1516
}
1617

0 commit comments

Comments
 (0)