@@ -603,6 +603,7 @@ impl<'tcx> GotocCtx<'tcx> {
603
603
pub fn codegen_statement ( & mut self , stmt : & Statement < ' tcx > ) -> Stmt {
604
604
let _trace_span = info_span ! ( "CodegenStatement" , statement = ?stmt) . entered ( ) ;
605
605
debug ! ( "handling statement {:?}" , stmt) ;
606
+ let location = self . codegen_span ( & stmt. source_info . span ) ;
606
607
match & stmt. kind {
607
608
StatementKind :: Assign ( box ( l, r) ) => {
608
609
let lty = self . place_ty ( l) ;
@@ -617,15 +618,32 @@ impl<'tcx> GotocCtx<'tcx> {
617
618
// where the reference is implicit.
618
619
unwrap_or_return_codegen_unimplemented_stmt ! ( self , self . codegen_place( l) )
619
620
. goto_expr
620
- . assign ( self . codegen_rvalue ( r) . address_of ( ) , Location :: none ( ) )
621
+ . assign ( self . codegen_rvalue ( r) . address_of ( ) , location )
621
622
} else if rty. is_bool ( ) {
622
623
unwrap_or_return_codegen_unimplemented_stmt ! ( self , self . codegen_place( l) )
623
624
. goto_expr
624
- . assign ( self . codegen_rvalue ( r) . cast_to ( Type :: c_bool ( ) ) , Location :: none ( ) )
625
+ . assign ( self . codegen_rvalue ( r) . cast_to ( Type :: c_bool ( ) ) , location )
625
626
} else {
626
627
unwrap_or_return_codegen_unimplemented_stmt ! ( self , self . codegen_place( l) )
627
628
. goto_expr
628
- . assign ( self . codegen_rvalue ( r) , Location :: none ( ) )
629
+ . assign ( self . codegen_rvalue ( r) , location)
630
+ }
631
+ }
632
+ StatementKind :: Deinit ( place) => {
633
+ // From rustc doc: "This writes `uninit` bytes to the entire place."
634
+ // Thus, we assign nondet() value to the entire place.
635
+ let dst_mir_ty = self . place_ty ( place) ;
636
+ let dst_type = self . codegen_ty ( dst_mir_ty) ;
637
+ let layout = self . layout_of ( dst_mir_ty) ;
638
+ if layout. is_zst ( ) || dst_type. sizeof_in_bits ( & self . symbol_table ) == 0 {
639
+ // We ignore assignment for all zero size types
640
+ // Ignore generators too for now:
641
+ // https://github.com/model-checking/kani/issues/416
642
+ Stmt :: skip ( location)
643
+ } else {
644
+ unwrap_or_return_codegen_unimplemented_stmt ! ( self , self . codegen_place( place) )
645
+ . goto_expr
646
+ . assign ( dst_type. nondet ( ) , location)
629
647
}
630
648
}
631
649
StatementKind :: SetDiscriminant { place, variant_index } => {
@@ -638,16 +656,16 @@ impl<'tcx> GotocCtx<'tcx> {
638
656
. codegen_unimplemented (
639
657
"ty::Generator" ,
640
658
Type :: code ( vec ! [ ] , Type :: empty ( ) ) ,
641
- Location :: none ( ) ,
659
+ location . clone ( ) ,
642
660
"https://github.com/model-checking/kani/issues/416" ,
643
661
)
644
- . as_stmt ( Location :: none ( ) ) ;
662
+ . as_stmt ( location ) ;
645
663
}
646
664
_ => unreachable ! ( ) ,
647
665
} ;
648
666
let layout = self . layout_of ( pt) ;
649
667
match & layout. variants {
650
- Variants :: Single { .. } => Stmt :: skip ( Location :: none ( ) ) ,
668
+ Variants :: Single { .. } => Stmt :: skip ( location ) ,
651
669
Variants :: Multiple { tag, tag_encoding, .. } => match tag_encoding {
652
670
TagEncoding :: Direct => {
653
671
let discr = def. discriminant_for_variant ( self . tcx , * variant_index) ;
@@ -671,7 +689,7 @@ impl<'tcx> GotocCtx<'tcx> {
671
689
)
672
690
. goto_expr
673
691
. member ( "case" , & self . symbol_table )
674
- . assign ( discr, Location :: none ( ) )
692
+ . assign ( discr, location )
675
693
}
676
694
TagEncoding :: Niche { dataful_variant, niche_variants, niche_start } => {
677
695
if dataful_variant != variant_index {
@@ -686,27 +704,28 @@ impl<'tcx> GotocCtx<'tcx> {
686
704
let niche_value =
687
705
variant_index. as_u32 ( ) - niche_variants. start ( ) . as_u32 ( ) ;
688
706
let niche_value = ( niche_value as u128 ) . wrapping_add ( * niche_start) ;
689
- let value = if niche_value == 0 && tag. value == Primitive :: Pointer {
690
- discr_ty. null ( )
691
- } else {
692
- Expr :: int_constant ( niche_value, discr_ty. clone ( ) )
693
- } ;
707
+ let value =
708
+ if niche_value == 0 && tag. primitive ( ) == Primitive :: Pointer {
709
+ discr_ty. null ( )
710
+ } else {
711
+ Expr :: int_constant ( niche_value, discr_ty. clone ( ) )
712
+ } ;
694
713
let place = unwrap_or_return_codegen_unimplemented_stmt ! (
695
714
self ,
696
715
self . codegen_place( place)
697
716
)
698
717
. goto_expr ;
699
718
self . codegen_get_niche ( place, offset, discr_ty)
700
- . assign ( value, Location :: none ( ) )
719
+ . assign ( value, location )
701
720
} else {
702
- Stmt :: skip ( Location :: none ( ) )
721
+ Stmt :: skip ( location )
703
722
}
704
723
}
705
724
} ,
706
725
}
707
726
}
708
- StatementKind :: StorageLive ( _) => Stmt :: skip ( Location :: none ( ) ) , // TODO: fix me
709
- StatementKind :: StorageDead ( _) => Stmt :: skip ( Location :: none ( ) ) , // TODO: fix me
727
+ StatementKind :: StorageLive ( _) => Stmt :: skip ( location ) , // TODO: fix me
728
+ StatementKind :: StorageDead ( _) => Stmt :: skip ( location ) , // TODO: fix me
710
729
StatementKind :: CopyNonOverlapping ( box mir:: CopyNonOverlapping {
711
730
ref src,
712
731
ref dst,
@@ -719,26 +738,21 @@ impl<'tcx> GotocCtx<'tcx> {
719
738
let sz = Expr :: int_constant ( sz, Type :: size_t ( ) ) ;
720
739
let n = sz. mul ( count) ;
721
740
let dst = dst. cast_to ( Type :: void_pointer ( ) ) ;
722
- let e = BuiltinFn :: Memcpy . call ( vec ! [ dst, src, n. clone( ) ] , Location :: none ( ) ) ;
741
+ let e = BuiltinFn :: Memcpy . call ( vec ! [ dst, src, n. clone( ) ] , location . clone ( ) ) ;
723
742
724
743
// The C implementation of memcpy does not allow an invalid pointer for
725
744
// the src/dst, but the LLVM implementation specifies that a copy with
726
745
// length zero is a no-op. This comes up specifically when handling
727
746
// the empty string; CBMC will fail on passing a reference to empty
728
747
// string unless we codegen this zero check.
729
748
// https://llvm.org/docs/LangRef.html#llvm-memcpy-intrinsic
730
- Stmt :: if_then_else (
731
- n. is_zero ( ) . not ( ) ,
732
- e. as_stmt ( Location :: none ( ) ) ,
733
- None ,
734
- Location :: none ( ) ,
735
- )
749
+ Stmt :: if_then_else ( n. is_zero ( ) . not ( ) , e. as_stmt ( location. clone ( ) ) , None , location)
736
750
}
737
751
StatementKind :: FakeRead ( _)
738
752
| StatementKind :: Retag ( _, _)
739
753
| StatementKind :: AscribeUserType ( _, _)
740
754
| StatementKind :: Nop
741
- | StatementKind :: Coverage { .. } => Stmt :: skip ( Location :: none ( ) ) ,
755
+ | StatementKind :: Coverage { .. } => Stmt :: skip ( location ) ,
742
756
}
743
757
. with_location ( self . codegen_span ( & stmt. source_info . span ) )
744
758
}
0 commit comments