@@ -25,6 +25,31 @@ trait IrepAdapter {
25
25
fn to_esbmc_irep ( self ) -> Irept ;
26
26
}
27
27
28
+ pub fn irep_contains ( irep : & Irept , id : & str ) -> bool {
29
+ if irep. id == id {
30
+ return true ;
31
+ }
32
+
33
+ for v in & irep. subt {
34
+ if irep_contains ( v, id) {
35
+ return true ;
36
+ }
37
+ }
38
+
39
+ for ( _, v) in & irep. named_subt {
40
+ if irep_contains ( v, id) {
41
+ return true ;
42
+ }
43
+ }
44
+
45
+ for ( _, v) in & irep. comments {
46
+ if irep_contains ( v, id) {
47
+ return true ;
48
+ }
49
+ }
50
+ false
51
+ }
52
+
28
53
impl From < CBMCParseResult > for ESBMCParseResult {
29
54
fn from ( data : CBMCParseResult ) -> Self {
30
55
let mut adapted = ESBMCParseResult {
@@ -50,7 +75,10 @@ impl From<CBMCParseResult> for ESBMCParseResult {
50
75
// A symbol might have been defined later, we need to check everything again
51
76
for symbol in & mut adapted. symbols_irep {
52
77
symbol. fix_type ( & type_cache) ;
53
- assert_ne ! ( symbol. named_subt[ "type" ] . id, "struct_tag" ) ;
78
+ if irep_contains ( symbol, "struct_tag" ) {
79
+ panic ! ( "Tag should have been filtered for {}" , symbol. to_string( ) ) ;
80
+ }
81
+
54
82
assert_ne ! ( symbol. named_subt[ "type" ] . id, "c_bool" ) ;
55
83
}
56
84
@@ -90,6 +118,9 @@ mod esbmcfixes {
90
118
pub fn fix_name ( name : & str ) -> String {
91
119
match name {
92
120
"__CPROVER__start" => String :: from ( "__ESBMC_main" ) ,
121
+ "_RNvNtNtCsesPP5EAma4_4core3num6verify24checked_unchecked_add_i8" => {
122
+ "__ESBMC_main" . to_string ( )
123
+ }
93
124
_ => String :: from ( name) ,
94
125
}
95
126
}
@@ -102,11 +133,7 @@ mod esbmcfixes {
102
133
if irep. id == "constant"
103
134
&& ![ "pointer" , "bool" ] . contains ( & irep. named_subt [ "type" ] . id . as_str ( ) )
104
135
{
105
- // Value ID might be the decimal/hexa representation, we want the binary one!
106
- let width: usize = irep. named_subt [ "type" ] . named_subt [ "width" ]
107
- . id
108
- . parse ( )
109
- . unwrap ( ) ;
136
+ // Value ID might be hexa representation or binary, we want the binary one!
110
137
if 32 != irep. named_subt [ "value" ] . id . len ( ) {
111
138
let number = u64:: from_str_radix ( & irep. named_subt [ "value" ] . id , 16 ) . unwrap ( ) ;
112
139
irep. named_subt . insert (
@@ -115,6 +142,7 @@ mod esbmcfixes {
115
142
) ;
116
143
}
117
144
}
145
+
118
146
let expressions: HashSet < String > = HashSet :: from (
119
147
[
120
148
"if" ,
@@ -132,6 +160,7 @@ mod esbmcfixes {
132
160
"=" ,
133
161
"<" ,
134
162
">" ,
163
+ "overflow_result-+" ,
135
164
"lshr" ,
136
165
"shl" ,
137
166
"address_of" ,
@@ -141,6 +170,7 @@ mod esbmcfixes {
141
170
"array_of" ,
142
171
"sideeffect" ,
143
172
"dereference" ,
173
+ "object_size" ,
144
174
"bitand" ,
145
175
"struct" ,
146
176
"return" ,
@@ -247,7 +277,6 @@ impl IrepAdapter for CBMCFunction {
247
277
impl IrepAdapter for CBMCSymbol {
248
278
fn to_esbmc_irep ( self ) -> Irept {
249
279
let mut result = Irept :: default ( ) ;
250
- //result.id = String::from("symbol");
251
280
result. named_subt . insert ( "type" . to_string ( ) , self . stype ) ;
252
281
result. named_subt . insert ( "symvalue" . to_string ( ) , self . value ) ;
253
282
@@ -265,16 +294,23 @@ impl IrepAdapter for CBMCSymbol {
265
294
266
295
let name = match self . name . as_str ( ) {
267
296
"__CPROVER__start" => "__ESBMC_main" . to_string ( ) ,
268
- // "__CPROVER_initialize" => "__ESBMC_init".to_string(),
297
+ "_RNvNtNtCsesPP5EAma4_4core3num6verify24checked_unchecked_add_i8" => {
298
+ "__ESBMC_main" . to_string ( )
299
+ }
269
300
_ => self . name . clone ( ) ,
270
301
} ;
271
302
272
303
let basename = match self . base_name . as_str ( ) {
273
304
"__CPROVER__start" => "__ESBMC_main" . to_string ( ) ,
274
- // "__CPROVER_initialize" => "__ESBMC_init".to_string(),
305
+ "_RNvNtNtCsesPP5EAma4_4core3num6verify24checked_unchecked_add_i8" => {
306
+ "__ESBMC_main" . to_string ( )
307
+ }
308
+
275
309
_ => self . base_name . clone ( ) ,
276
310
} ;
277
311
312
+ assert_ne ! ( basename, "num::verify::checked_unchecked_add_i8" ) ;
313
+
278
314
if self . is_type {
279
315
result
280
316
. named_subt
@@ -596,6 +632,9 @@ impl Irept {
596
632
}
597
633
598
634
if self . id == "pointer" && !self . named_subt . contains_key ( "subtype" ) {
635
+ for v in & mut self . subt {
636
+ v. fix_type ( cache) ;
637
+ }
599
638
let mut operands = Irept :: default ( ) ;
600
639
operands. subt = self . subt . clone ( ) ;
601
640
self . named_subt . insert ( "subtype" . to_string ( ) , operands) ;
@@ -645,6 +684,21 @@ impl Irept {
645
684
}
646
685
647
686
* self = cache[ & self . named_subt [ "identifier" ] ] . clone ( ) ;
687
+
688
+ // redo cache
689
+ if irep_contains ( self , "struct_tag" ) {
690
+ for v in & mut self . subt {
691
+ v. fix_type ( cache) ;
692
+ }
693
+
694
+ for ( _, v) in & mut self . named_subt {
695
+ v. fix_type ( cache) ;
696
+ }
697
+
698
+ for ( _, v) in & mut self . comments {
699
+ v. fix_type ( cache) ;
700
+ }
701
+ }
648
702
}
649
703
}
650
704
@@ -892,4 +946,15 @@ mod tests {
892
946
run_goto_test ( "first_steps.rs.goto" , & [ "--incremental-bmc" ] , 1 ) ;
893
947
run_goto_test ( "first-steps-pass.goto" , & [ "--incremental-bmc" ] , 0 ) ;
894
948
}
949
+
950
+ #[ test]
951
+ #[ ignore]
952
+ fn unchecked_add_contract ( ) {
953
+ // Disabled because ESBMC does not support: object_size, overflow_result-+
954
+ // run_goto_test(
955
+ // "checked_unchecked_add_i8.goto",
956
+ // &["--goto-functions-only"],
957
+ // 0,
958
+ // );
959
+ }
895
960
}
0 commit comments