File tree Expand file tree Collapse file tree 7 files changed +107
-16
lines changed
kani-compiler/src/codegen_cprover_gotoc/codegen Expand file tree Collapse file tree 7 files changed +107
-16
lines changed Original file line number Diff line number Diff line change 33
44use crate :: codegen_cprover_gotoc:: GotocCtx ;
55use rustc_middle:: mir:: { BasicBlock , BasicBlockData } ;
6+ use tracing:: debug;
67
78impl < ' tcx > GotocCtx < ' tcx > {
89 /// Generates Goto-C for a basic block.
@@ -12,6 +13,7 @@ impl<'tcx> GotocCtx<'tcx> {
1213 /// This function does not return a value, but mutates state with
1314 /// `self.current_fn_mut().push_onto_block(...)`
1415 pub fn codegen_block ( & mut self , bb : BasicBlock , bbd : & BasicBlockData < ' tcx > ) {
16+ debug ! ( ?bb, "Codegen basicblock" ) ;
1517 self . current_fn_mut ( ) . set_current_bb ( bb) ;
1618 let label: String = self . current_fn ( ) . find_label ( & bb) ;
1719 // the first statement should be labelled. if there is no statements, then the
Original file line number Diff line number Diff line change @@ -12,6 +12,7 @@ use kani_queries::UserInput;
1212use rustc_ast:: Attribute ;
1313use rustc_hir:: def:: DefKind ;
1414use rustc_hir:: def_id:: DefId ;
15+ use rustc_middle:: mir:: traversal:: reverse_postorder;
1516use rustc_middle:: mir:: { Body , HasLocalDecls , Local } ;
1617use rustc_middle:: ty:: layout:: FnAbiOf ;
1718use rustc_middle:: ty:: { self , Instance } ;
@@ -88,7 +89,7 @@ impl<'tcx> GotocCtx<'tcx> {
8889 self . codegen_function_prelude ( ) ;
8990 self . codegen_declare_variables ( ) ;
9091
91- mir . basic_blocks . iter_enumerated ( ) . for_each ( |( bb, bbd) | self . codegen_block ( bb, bbd) ) ;
92+ reverse_postorder ( mir ) . for_each ( |( bb, bbd) | self . codegen_block ( bb, bbd) ) ;
9293
9394 let loc = self . codegen_span ( & mir. span ) ;
9495 let stmts = self . current_fn_mut ( ) . extract_block ( ) ;
Original file line number Diff line number Diff line change 44use smallvec:: { smallvec, SmallVec } ;
55
66#[ kani:: proof]
7+ #[ kani:: unwind( 4 ) ]
78pub fn check_vec ( ) {
89 // Create small vec with three elements.
910 let chars: SmallVec < [ char ; 3 ] > = smallvec ! [ kani:: any( ) , kani:: any( ) , kani:: any( ) ] ;
Original file line number Diff line number Diff line change 1+ // Copyright Kani Contributors
2+ // SPDX-License-Identifier: Apache-2.0 OR MIT
3+
4+ //! This test checks whether dropping objects passed through
5+ //! std::sync::mpsc::channel is handled.
6+ //! This test only passes on MacOS today, so we duplicate the test for now.
7+ #![ cfg( target_os = "macos" ) ]
8+
9+ use std:: sync:: mpsc:: * ;
10+
11+ static mut CELL : i32 = 0 ;
12+
13+ struct DropSetCELLToOne { }
14+
15+ impl Drop for DropSetCELLToOne {
16+ fn drop ( & mut self ) {
17+ unsafe {
18+ CELL = 1 ;
19+ }
20+ }
21+ }
22+
23+ #[ kani:: unwind( 1 ) ]
24+ #[ kani:: proof]
25+ fn main ( ) {
26+ {
27+ let ( send, recv) = channel :: < DropSetCELLToOne > ( ) ;
28+ send. send ( DropSetCELLToOne { } ) . unwrap ( ) ;
29+ let _to_drop: DropSetCELLToOne = recv. recv ( ) . unwrap ( ) ;
30+ }
31+ assert_eq ! ( unsafe { CELL } , 1 , "Drop should be called" ) ;
32+ }
Original file line number Diff line number Diff line change 99// kani::unwind(2) takes longer than 10m on a M1 Mac. For details,
1010// please see: https://github.com/model-checking/kani/issues/1286
1111
12- use std:: sync:: mpsc:: * ;
12+ #[ cfg( target_os = "linux" ) ]
13+ mod fixme_harness {
14+ use std:: sync:: mpsc:: * ;
1315
14- static mut CELL : i32 = 0 ;
16+ static mut CELL : i32 = 0 ;
1517
16- struct DropSetCELLToOne { }
18+ struct DropSetCELLToOne { }
1719
18- impl Drop for DropSetCELLToOne {
19- fn drop ( & mut self ) {
20- unsafe {
21- CELL = 1 ;
20+ impl Drop for DropSetCELLToOne {
21+ fn drop ( & mut self ) {
22+ unsafe {
23+ CELL = 1 ;
24+ }
2225 }
2326 }
27+
28+ #[ kani:: unwind( 1 ) ]
29+ #[ kani:: proof]
30+ fn main ( ) {
31+ {
32+ let ( send, recv) = channel :: < DropSetCELLToOne > ( ) ;
33+ send. send ( DropSetCELLToOne { } ) . unwrap ( ) ;
34+ let _to_drop: DropSetCELLToOne = recv. recv ( ) . unwrap ( ) ;
35+ }
36+ assert_eq ! ( unsafe { CELL } , 1 , "Drop should be called" ) ;
37+ }
2438}
2539
26- #[ kani:: unwind( 1 ) ]
27- #[ kani:: proof]
28- fn main ( ) {
29- {
30- let ( send, recv) = channel :: < DropSetCELLToOne > ( ) ;
31- send. send ( DropSetCELLToOne { } ) . unwrap ( ) ;
32- let _to_drop: DropSetCELLToOne = recv. recv ( ) . unwrap ( ) ;
40+ #[ cfg( target_os = "macos" ) ]
41+ mod forced_failure {
42+ #[ kani:: proof]
43+ fn just_panic ( ) {
44+ panic ! ( "This test only fails on linux" ) ;
3345 }
34- assert_eq ! ( unsafe { CELL } , 1 , "Drop should be called" ) ;
3546}
Original file line number Diff line number Diff line change 1+ // Copyright Kani Contributors
2+ // SPDX-License-Identifier: Apache-2.0 OR MIT
3+ //
4+ //! Ensure that Kani identifies that there is not loop in this code.
5+ //! This was related to https://github.com/model-checking/kani/issues/2164
6+ fn loop_free < T : Default > ( b : bool , other : T ) -> T {
7+ match b {
8+ true => T :: default ( ) ,
9+ false => other,
10+ }
11+ }
12+
13+ /// Set the unwind to 1 so this test will fail instead of running forever.
14+ #[ kani:: proof]
15+ #[ kani:: unwind( 1 ) ]
16+ fn check_no_loop ( ) {
17+ let b: bool = kani:: any ( ) ;
18+ let result = loop_free ( b, 5 ) ;
19+ assert ! ( result == 5 || ( b && result == 0 ) )
20+ }
Original file line number Diff line number Diff line change 1+ // Copyright Kani Contributors
2+ // SPDX-License-Identifier: Apache-2.0 OR MIT
3+ //
4+ //! Ensure that Kani correctly unwinds the loop with drop instructions.
5+ //! This was related to https://github.com/model-checking/kani/issues/2164
6+
7+ /// Dummy function with a for loop that only runs 2 iterations.
8+ fn bounded_loop < T : Default > ( b : bool , other : T ) -> T {
9+ let mut ret = other;
10+ for i in 0 ..2 {
11+ ret = match b {
12+ true => T :: default ( ) ,
13+ false => ret,
14+ } ;
15+ }
16+ return ret;
17+ }
18+
19+ /// Harness that should succeed. We add a conservative loop bound.
20+ #[ kani:: proof]
21+ #[ kani:: unwind( 3 ) ]
22+ fn harness ( ) {
23+ let _ = bounded_loop ( kani:: any ( ) , ( ) ) ;
24+ }
You can’t perform that action at this time.
0 commit comments