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 2023-08-14 #2688

Merged
merged 1 commit into from
Aug 16, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
38 changes: 38 additions & 0 deletions kani-compiler/src/codegen_cprover_gotoc/codegen/intrinsic.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
use super::typ::{self, pointee_type};
use super::PropertyClass;
use crate::codegen_cprover_gotoc::GotocCtx;
use crate::unwrap_or_return_codegen_unimplemented_stmt;
use cbmc::goto_program::{
ArithmeticOverflowResult, BinaryOperator, BuiltinFn, Expr, Location, Stmt, Type,
};
Expand Down Expand Up @@ -408,6 +409,7 @@ impl<'tcx> GotocCtx<'tcx> {
),
"ceilf32" => codegen_simple_intrinsic!(Ceilf),
"ceilf64" => codegen_simple_intrinsic!(Ceil),
"compare_bytes" => self.codegen_compare_bytes(fargs, p, loc),
"copy" => self.codegen_copy(intrinsic, false, fargs, farg_types, Some(p), loc),
"copy_nonoverlapping" => unreachable!(
"Expected `core::intrinsics::unreachable` to be handled by `StatementKind::CopyNonOverlapping`"
Expand Down Expand Up @@ -987,6 +989,42 @@ impl<'tcx> GotocCtx<'tcx> {
Stmt::block(vec![src_align_check, dst_align_check, overflow_check, copy_expr], loc)
}

/// This is an intrinsic that was added in
/// https://github.com/rust-lang/rust/pull/114382 that is essentially the
/// same as memcmp: it compares two slices up to the specified length.
/// The implementation is the same as the hook for `memcmp`.
pub fn codegen_compare_bytes(
&mut self,
mut fargs: Vec<Expr>,
p: &Place<'tcx>,
loc: Location,
) -> Stmt {
let lhs = fargs.remove(0).cast_to(Type::void_pointer());
let rhs = fargs.remove(0).cast_to(Type::void_pointer());
let len = fargs.remove(0);
let (len_var, len_decl) = self.decl_temp_variable(len.typ().clone(), Some(len), loc);
let (lhs_var, lhs_decl) = self.decl_temp_variable(lhs.typ().clone(), Some(lhs), loc);
let (rhs_var, rhs_decl) = self.decl_temp_variable(rhs.typ().clone(), Some(rhs), loc);
let is_len_zero = len_var.clone().is_zero();
// We have to ensure that the pointers are valid even if we're comparing zero bytes.
// According to Rust's current definition (see https://github.com/model-checking/kani/issues/1489),
// this means they have to be non-null and aligned.
// But alignment is automatically satisfied because `memcmp` takes `*const u8` pointers.
let is_lhs_ok = lhs_var.clone().is_nonnull();
let is_rhs_ok = rhs_var.clone().is_nonnull();
let should_skip_pointer_checks = is_len_zero.and(is_lhs_ok).and(is_rhs_ok);
let place_expr =
unwrap_or_return_codegen_unimplemented_stmt!(self, self.codegen_place(&p)).goto_expr;
let res = should_skip_pointer_checks.ternary(
Expr::int_constant(0, place_expr.typ().clone()), // zero bytes are always equal (as long as pointers are nonnull and aligned)
BuiltinFn::Memcmp
.call(vec![lhs_var, rhs_var, len_var], loc)
.cast_to(place_expr.typ().clone()),
);
let code = place_expr.assign(res, loc).with_location(loc);
Stmt::block(vec![len_decl, lhs_decl, rhs_decl, code], loc)
}

// In some contexts (e.g., compilation-time evaluation),
// `ptr_guaranteed_cmp` compares two pointers and returns:
// * 2 if the result is unknown.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -345,7 +345,7 @@ impl CodegenBackend for GotocCodegenBackend {
codegen_results: CodegenResults,
outputs: &OutputFilenames,
) -> Result<(), ErrorGuaranteed> {
let requested_crate_types = sess.crate_types();
let requested_crate_types = &codegen_results.crate_info.crate_types;
for crate_type in requested_crate_types {
let out_fname = out_filename(
sess,
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-2023-08-07"
channel = "nightly-2023-08-14"
components = ["llvm-tools-preview", "rustc-dev", "rust-src", "rustfmt"]