Skip to content

Commit 3007e84

Browse files
authored
Upgrade to CBMC 5.68.0 (with fixes) (model-checking#1811)
1 parent 33e226b commit 3007e84

File tree

23 files changed

+87
-81
lines changed

23 files changed

+87
-81
lines changed

cprover_bindings/src/env.rs

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,13 @@ use super::goto_program::{Expr, Location, Symbol, Type};
1212
use super::MachineModel;
1313
use num::bigint::BigInt;
1414
fn int_constant<T>(name: &str, value: T) -> Symbol
15+
where
16+
T: Into<BigInt>,
17+
{
18+
Symbol::constant(name, name, name, Expr::int_constant(value, Type::integer()), Location::none())
19+
}
20+
21+
fn int_constant_c_int<T>(name: &str, value: T) -> Symbol
1522
where
1623
T: Into<BigInt>,
1724
{
@@ -23,7 +30,7 @@ fn int_constant_from_bool(name: &str, value: bool) -> Symbol {
2330
name,
2431
name,
2532
name,
26-
Expr::int_constant(if value { 1 } else { 0 }, Type::c_int()),
33+
Expr::int_constant(if value { 1 } else { 0 }, Type::integer()),
2734
Location::none(),
2835
)
2936
}
@@ -58,7 +65,9 @@ pub fn machine_model_symbols(mm: &MachineModel) -> Vec<Symbol> {
5865
),
5966
int_constant("__CPROVER_architecture_wchar_t_width", mm.wchar_t_width),
6067
int_constant("__CPROVER_architecture_word_size", mm.word_size),
61-
int_constant("__CPROVER_rounding_mode", mm.rounding_mode),
68+
// `__CPROVER_rounding_mode` doesn't use `integer` type.
69+
// More details in <https://github.com/diffblue/cbmc/issues/7282>
70+
int_constant_c_int("__CPROVER_rounding_mode", mm.rounding_mode),
6271
]
6372
}
6473

cprover_bindings/src/goto_program/symtab_transformer/transformer.rs

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -55,6 +55,7 @@ pub trait Transformer: Sized {
5555
Type::IncompleteStruct { tag } => self.transform_type_incomplete_struct(*tag),
5656
Type::IncompleteUnion { tag } => self.transform_type_incomplete_union(*tag),
5757
Type::InfiniteArray { typ } => self.transform_type_infinite_array(typ),
58+
Type::Integer => self.transform_type_integer(),
5859
Type::Pointer { typ } => self.transform_type_pointer(typ),
5960
Type::Signedbv { width } => self.transform_type_signedbv(width),
6061
Type::Struct { tag, components } => self.transform_type_struct(*tag, components),
@@ -154,6 +155,11 @@ pub trait Transformer: Sized {
154155
transformed_typ.infinite_array_of()
155156
}
156157

158+
/// Transforms a CPROVER integer type
159+
fn transform_type_integer(&mut self) -> Type {
160+
Type::integer()
161+
}
162+
157163
/// Transforms a pointer type (`typ*`)
158164
fn transform_type_pointer(&mut self, typ: &Type) -> Type {
159165
let transformed_typ = self.transform_type(typ);

cprover_bindings/src/goto_program/typ.rs

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,8 @@ pub enum Type {
4646
IncompleteStruct { tag: InternedString },
4747
/// `union x {}`
4848
IncompleteUnion { tag: InternedString },
49+
/// `integer`: A machine independent integer
50+
Integer,
4951
/// CBMC specific. `typ x[__CPROVER_infinity()]`
5052
InfiniteArray { typ: Box<Type> },
5153
/// `typ*`
@@ -163,6 +165,7 @@ impl DatatypeComponent {
163165
| Double
164166
| FlexibleArray { .. }
165167
| Float
168+
| Integer
166169
| Pointer { .. }
167170
| Signedbv { .. }
168171
| Struct { .. }
@@ -343,6 +346,7 @@ impl Type {
343346
IncompleteStruct { .. } => unreachable!("IncompleteStruct doesn't have a sizeof"),
344347
IncompleteUnion { .. } => unreachable!("IncompleteUnion doesn't have a sizeof"),
345348
InfiniteArray { .. } => unreachable!("InfiniteArray doesn't have a sizeof"),
349+
Integer => unreachable!("Integer doesn't have a sizeof"),
346350
Pointer { .. } => st.machine_model().pointer_width,
347351
Signedbv { width } => *width,
348352
Struct { components, .. } => {
@@ -527,7 +531,7 @@ impl Type {
527531
pub fn is_integer(&self) -> bool {
528532
let concrete = self.unwrap_typedef();
529533
match concrete {
530-
CInteger(_) | Signedbv { .. } | Unsignedbv { .. } => true,
534+
CInteger(_) | Integer | Signedbv { .. } | Unsignedbv { .. } => true,
531535
_ => false,
532536
}
533537
}
@@ -540,6 +544,7 @@ impl Type {
540544
| CInteger(_)
541545
| Double
542546
| Float
547+
| Integer
543548
| Pointer { .. }
544549
| Signedbv { .. }
545550
| Struct { .. }
@@ -595,6 +600,7 @@ impl Type {
595600
| Double
596601
| Empty
597602
| Float
603+
| Integer
598604
| Pointer { .. }
599605
| Signedbv { .. }
600606
| Unsignedbv { .. } => true,
@@ -877,6 +883,7 @@ impl Type {
877883
| CInteger(_)
878884
| Double
879885
| Float
886+
| Integer
880887
| Pointer { .. }
881888
| Signedbv { .. }
882889
| Struct { .. }
@@ -1025,6 +1032,10 @@ impl Type {
10251032
InfiniteArray { typ: Box::new(self) }
10261033
}
10271034

1035+
pub fn integer() -> Self {
1036+
Integer
1037+
}
1038+
10281039
/// self *
10291040
pub fn to_pointer(self) -> Self {
10301041
Pointer { typ: Box::new(self) }
@@ -1256,6 +1267,7 @@ impl Type {
12561267
| CInteger(_)
12571268
| Double
12581269
| Float
1270+
| Integer
12591271
| Pointer { .. }
12601272
| Signedbv { .. }
12611273
| Unsignedbv { .. } => self.zero(),
@@ -1364,6 +1376,7 @@ impl Type {
13641376
Type::InfiniteArray { typ } => {
13651377
format!("infinite_array_of_{}", typ.to_identifier())
13661378
}
1379+
Type::Integer => "integer".to_string(),
13671380
Type::Pointer { typ } => format!("pointer_to_{}", typ.to_identifier()),
13681381
Type::Signedbv { width } => format!("signed_bv_{width}"),
13691382
Type::Struct { tag, .. } => format!("struct_{tag}"),

cprover_bindings/src/irep/to_irep.rs

Lines changed: 8 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -140,14 +140,16 @@ impl ToIrep for DatatypeComponent {
140140
impl ToIrep for Expr {
141141
fn to_irep(&self, mm: &MachineModel) -> Irep {
142142
if let ExprValue::IntConstant(i) = self.value() {
143-
let width = self.typ().native_width(mm).unwrap();
143+
let typ_width = self.typ().native_width(mm);
144+
let irep_value = if let Some(width) = typ_width {
145+
Irep::just_bitpattern_id(i.clone(), width, self.typ().is_signed(mm))
146+
} else {
147+
Irep::just_int_id(i.clone())
148+
};
144149
Irep {
145150
id: IrepId::Constant,
146151
sub: vec![],
147-
named_sub: linear_map![(
148-
IrepId::Value,
149-
Irep::just_bitpattern_id(i.clone(), width, self.typ().is_signed(mm))
150-
)],
152+
named_sub: linear_map![(IrepId::Value, irep_value,)],
151153
}
152154
.with_location(self.location(), mm)
153155
.with_type(self.typ(), mm)
@@ -652,6 +654,7 @@ impl ToIrep for Type {
652654
named_sub: linear_map![(IrepId::Size, infinity)],
653655
}
654656
}
657+
Type::Integer => Irep::just_id(IrepId::Integer),
655658
Type::Pointer { typ } => Irep {
656659
id: IrepId::Pointer,
657660
sub: vec![typ.to_irep(mm)],

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

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -174,6 +174,7 @@ impl<'tcx> GotocCtx<'tcx> {
174174
Type::IncompleteStruct { .. } => todo!(),
175175
Type::IncompleteUnion { .. } => todo!(),
176176
Type::InfiniteArray { .. } => todo!(),
177+
Type::Integer => write!(out, "integer")?,
177178
Type::Pointer { typ } => {
178179
write!(out, "*")?;
179180
debug_write_type(ctx, typ, out, indent)?;

kani-dependencies

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,3 @@
1-
CBMC_VERSION="5.67.0"
1+
CBMC_VERSION="5.69.1"
22
# If you update this version number, remember to bump it in `src/setup.rs` too
33
CBMC_VIEWER_VERSION="3.6"

kani-driver/src/call_cbmc.rs

Lines changed: 11 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -124,12 +124,17 @@ impl KaniSession {
124124
args.push("--validate-ssa-equation".into());
125125
}
126126

127-
if !self.args.visualize
128-
&& self.args.concrete_playback.is_none()
129-
&& !self.args.no_slice_formula
130-
{
131-
args.push("--slice-formula".into());
132-
}
127+
// Push `--slice-formula` argument.
128+
// Previously, this would happen if the condition below was satisfied:
129+
// ```rust
130+
// if !self.args.visualize
131+
// && self.args.concrete_playback.is_none()
132+
// && !self.args.no_slice_formula
133+
// ```
134+
// But for some reason, not pushing it causes a CBMC invariant violation
135+
// since version 5.68.0.
136+
// <https://github.com/model-checking/kani/issues/1810>
137+
args.push("--slice-formula".into());
133138

134139
if self.args.concrete_playback.is_some() {
135140
args.push("--trace".into());

library/kani/kani_lib.c

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,13 @@ void *calloc(size_t nmemb, size_t size);
1111

1212
typedef __CPROVER_bool bool;
1313

14+
/// Mapping unit to `void` works for functions with no return type but not for
15+
/// variables with type unit. We treat both uniformly by declaring an empty
16+
/// struct type: `struct Unit {}` and a global variable `struct Unit VoidUnit`
17+
/// returned by all void functions (both declared by the Kani compiler).
18+
struct Unit;
19+
extern struct Unit VoidUnit;
20+
1421
// `assert` then `assume`
1522
#define __KANI_assert(cond, msg) \
1623
do { \
@@ -70,7 +77,7 @@ uint8_t *__rust_alloc_zeroed(size_t size, size_t align)
7077
// definition.
7178
// For safety, refer to the documentation of GlobalAlloc::dealloc:
7279
// https://doc.rust-lang.org/std/alloc/trait.GlobalAlloc.html#tymethod.dealloc
73-
void __rust_dealloc(uint8_t *ptr, size_t size, size_t align)
80+
struct Unit __rust_dealloc(uint8_t *ptr, size_t size, size_t align)
7481
{
7582
// TODO: Ensure we are doing the right thing with align
7683
// https://github.com/model-checking/kani/issues/1168
@@ -79,6 +86,7 @@ void __rust_dealloc(uint8_t *ptr, size_t size, size_t align)
7986
__KANI_assert(__CPROVER_OBJECT_SIZE(ptr) == size,
8087
"rust_dealloc must be called on an object whose allocated size matches its layout");
8188
free(ptr);
89+
return VoidUnit;
8290
}
8391

8492
// This is a C implementation of the __rust_realloc function that has the following signature:

scripts/kani-regression.sh

Lines changed: 0 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -87,16 +87,6 @@ fi
8787
# Check codegen of firecracker
8888
time "$SCRIPT_DIR"/codegen-firecracker.sh
8989

90-
# Check that we can use Kani on crates with a diamond dependency graph,
91-
# with two different versions of the same crate.
92-
#
93-
# dependency1
94-
# / \ v0.1.0
95-
# main dependency3
96-
# \ / v0.1.1
97-
# dependency2
98-
time "$KANI_DIR"/tests/kani-dependency-test/diamond-dependency/run-dependency-test.sh
99-
10090
# Check that documentation compiles.
10191
cargo doc --workspace --no-deps --exclude std
10292

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
VERIFICATION:- SUCCESSFUL

tests/kani-dependency-test/diamond-dependency/run-dependency-test.sh

Lines changed: 0 additions & 53 deletions
This file was deleted.

tests/kani/ForeignItems/lib.c

Lines changed: 25 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,13 @@
77
#include <stdio.h>
88
#include <string.h>
99

10+
/// Mapping unit to `void` works for functions with no return type but not for
11+
/// variables with type unit. We treat both uniformly by declaring an empty
12+
/// struct type: `struct Unit {}` and a global variable `struct Unit VoidUnit`
13+
/// returned by all void functions (both declared by the Kani compiler).
14+
struct Unit;
15+
extern struct Unit VoidUnit;
16+
1017
size_t my_add(size_t num, ...)
1118
{
1219
va_list argp;
@@ -48,7 +55,15 @@ struct Foo2 {
4855

4956
uint32_t S = 12;
5057

51-
void update_static() { S++; }
58+
// Note: We changed the return type from `void` to `struct Unit` when upgrading
59+
// to a newer CBMC version with stricter type-checking. This is a temporary
60+
// change until C-FFI support is added.
61+
// <https://github.com/model-checking/kani/issues/1817>
62+
struct Unit update_static()
63+
{
64+
S++;
65+
return VoidUnit;
66+
}
5267

5368
uint32_t takes_int(uint32_t i) { return i + 2; }
5469

@@ -63,7 +78,15 @@ uint32_t takes_ptr_option(uint32_t *p)
6378
}
6479
}
6580

66-
void mutates_ptr(uint32_t *p) { *p -= 1; }
81+
// Note: We changed the return type from `void` to `struct Unit` when upgrading
82+
// to a newer CBMC version with stricter type-checking. This is a temporary
83+
// change until C-FFI support is added.
84+
// <https://github.com/model-checking/kani/issues/1817>
85+
struct Unit mutates_ptr(uint32_t *p)
86+
{
87+
*p -= 1;
88+
return VoidUnit;
89+
}
6790

6891
uint32_t name_in_c(uint32_t i) { return i + 2; }
6992

0 commit comments

Comments
 (0)