Skip to content

Commit 7a28667

Browse files
authored
Fix ICE due to mishandling of Aggregate rvalue for raw pointers to str (#3448)
We were missing a match arm for the case where a raw pointer to a string slice was created from a thin pointer and the string size. Resolves #3312 By submitting this pull request, I confirm that my contribution is made under the terms of the Apache 2.0 and MIT licenses.
1 parent 56e2a2f commit 7a28667

File tree

5 files changed

+56
-0
lines changed

5 files changed

+56
-0
lines changed

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

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -694,6 +694,14 @@ impl<'tcx> GotocCtx<'tcx> {
694694
let meta = self.codegen_operand_stable(&operands[1]);
695695
slice_fat_ptr(typ, data_cast, meta, &self.symbol_table)
696696
}
697+
TyKind::RigidTy(RigidTy::Str) => {
698+
let pointee_goto_typ = Type::unsigned_int(8);
699+
// cast data to pointer with specified type
700+
let data_cast =
701+
data.cast_to(Type::Pointer { typ: Box::new(pointee_goto_typ) });
702+
let meta = self.codegen_operand_stable(&operands[1]);
703+
slice_fat_ptr(typ, data_cast, meta, &self.symbol_table)
704+
}
697705
TyKind::RigidTy(RigidTy::Adt(..)) => {
698706
let pointee_goto_typ = self.codegen_ty_stable(pointee_ty);
699707
let data_cast =

tests/kani/Str/raw_ptr.rs

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
// Copyright Kani Contributors
2+
// SPDX-License-Identifier: Apache-2.0 OR MIT
3+
//! Checks that Kani can handle creating pointers for slices from raw parts.
4+
//! This used to trigger an ICE reported in <https://github.com/model-checking/kani/issues/3312>.
5+
#![feature(ptr_metadata)]
6+
7+
#[derive(kani::Arbitrary)]
8+
struct AscII {
9+
#[safety_constraint(*inner < 128)]
10+
inner: u8,
11+
}
12+
13+
#[kani::proof]
14+
fn check_from_raw() {
15+
let ascii: [AscII; 5] = kani::any();
16+
let slice_ptr: *const [AscII] = &ascii;
17+
let (ptr, metadata) = slice_ptr.to_raw_parts();
18+
let str_ptr: *const str = std::ptr::from_raw_parts(ptr, metadata);
19+
assert!(unsafe { (&*str_ptr).is_ascii() });
20+
}

tests/perf/smol_str/Cargo.toml

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
# Copyright Kani Contributors
2+
# SPDX-License-Identifier: Apache-2.0 OR MIT
3+
4+
[package]
5+
name = "check_smol_str"
6+
version = "0.1.0"
7+
edition = "2021"
8+
9+
[dependencies]
10+
# Make dependency fixed to ensure the test stays the same.
11+
smol_str = "=0.2.2"

tests/perf/smol_str/expected

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
Checking harness check_new...
2+
VERIFICATION:- SUCCESSFUL
3+
4+
Complete - 1 successfully verified harnesses, 0 failures, 1 total.

tests/perf/smol_str/src/lib.rs

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
// Copyright Kani Contributors
2+
// SPDX-License-Identifier: Apache-2.0 OR MIT
3+
//! Test that Kani can correctly verify the cedar implementation of `SmolStr`
4+
//! An ICE was initially reported for this case in:
5+
//! <https://github.com/model-checking/kani/issues/3312>
6+
7+
#[kani::proof]
8+
#[kani::unwind(4)]
9+
fn check_new() {
10+
let data: [char; 3] = kani::any();
11+
let input: String = data.iter().collect();
12+
smol_str::SmolStr::new(&input);
13+
}

0 commit comments

Comments
 (0)