@@ -603,6 +603,7 @@ impl<'tcx> GotocCtx<'tcx> {
603603 pub fn codegen_statement ( & mut self , stmt : & Statement < ' tcx > ) -> Stmt {
604604 let _trace_span = info_span ! ( "CodegenStatement" , statement = ?stmt) . entered ( ) ;
605605 debug ! ( "handling statement {:?}" , stmt) ;
606+ let location = self . codegen_span ( & stmt. source_info . span ) ;
606607 match & stmt. kind {
607608 StatementKind :: Assign ( box ( l, r) ) => {
608609 let lty = self . place_ty ( l) ;
@@ -617,15 +618,32 @@ impl<'tcx> GotocCtx<'tcx> {
617618 // where the reference is implicit.
618619 unwrap_or_return_codegen_unimplemented_stmt ! ( self , self . codegen_place( l) )
619620 . goto_expr
620- . assign ( self . codegen_rvalue ( r) . address_of ( ) , Location :: none ( ) )
621+ . assign ( self . codegen_rvalue ( r) . address_of ( ) , location )
621622 } else if rty. is_bool ( ) {
622623 unwrap_or_return_codegen_unimplemented_stmt ! ( self , self . codegen_place( l) )
623624 . 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 )
625626 } else {
626627 unwrap_or_return_codegen_unimplemented_stmt ! ( self , self . codegen_place( l) )
627628 . 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)
629647 }
630648 }
631649 StatementKind :: SetDiscriminant { place, variant_index } => {
@@ -638,16 +656,16 @@ impl<'tcx> GotocCtx<'tcx> {
638656 . codegen_unimplemented (
639657 "ty::Generator" ,
640658 Type :: code ( vec ! [ ] , Type :: empty ( ) ) ,
641- Location :: none ( ) ,
659+ location . clone ( ) ,
642660 "https://github.com/model-checking/kani/issues/416" ,
643661 )
644- . as_stmt ( Location :: none ( ) ) ;
662+ . as_stmt ( location ) ;
645663 }
646664 _ => unreachable ! ( ) ,
647665 } ;
648666 let layout = self . layout_of ( pt) ;
649667 match & layout. variants {
650- Variants :: Single { .. } => Stmt :: skip ( Location :: none ( ) ) ,
668+ Variants :: Single { .. } => Stmt :: skip ( location ) ,
651669 Variants :: Multiple { tag, tag_encoding, .. } => match tag_encoding {
652670 TagEncoding :: Direct => {
653671 let discr = def. discriminant_for_variant ( self . tcx , * variant_index) ;
@@ -671,7 +689,7 @@ impl<'tcx> GotocCtx<'tcx> {
671689 )
672690 . goto_expr
673691 . member ( "case" , & self . symbol_table )
674- . assign ( discr, Location :: none ( ) )
692+ . assign ( discr, location )
675693 }
676694 TagEncoding :: Niche { dataful_variant, niche_variants, niche_start } => {
677695 if dataful_variant != variant_index {
@@ -686,27 +704,28 @@ impl<'tcx> GotocCtx<'tcx> {
686704 let niche_value =
687705 variant_index. as_u32 ( ) - niche_variants. start ( ) . as_u32 ( ) ;
688706 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+ } ;
694713 let place = unwrap_or_return_codegen_unimplemented_stmt ! (
695714 self ,
696715 self . codegen_place( place)
697716 )
698717 . goto_expr ;
699718 self . codegen_get_niche ( place, offset, discr_ty)
700- . assign ( value, Location :: none ( ) )
719+ . assign ( value, location )
701720 } else {
702- Stmt :: skip ( Location :: none ( ) )
721+ Stmt :: skip ( location )
703722 }
704723 }
705724 } ,
706725 }
707726 }
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
710729 StatementKind :: CopyNonOverlapping ( box mir:: CopyNonOverlapping {
711730 ref src,
712731 ref dst,
@@ -719,26 +738,21 @@ impl<'tcx> GotocCtx<'tcx> {
719738 let sz = Expr :: int_constant ( sz, Type :: size_t ( ) ) ;
720739 let n = sz. mul ( count) ;
721740 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 ( ) ) ;
723742
724743 // The C implementation of memcpy does not allow an invalid pointer for
725744 // the src/dst, but the LLVM implementation specifies that a copy with
726745 // length zero is a no-op. This comes up specifically when handling
727746 // the empty string; CBMC will fail on passing a reference to empty
728747 // string unless we codegen this zero check.
729748 // 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)
736750 }
737751 StatementKind :: FakeRead ( _)
738752 | StatementKind :: Retag ( _, _)
739753 | StatementKind :: AscribeUserType ( _, _)
740754 | StatementKind :: Nop
741- | StatementKind :: Coverage { .. } => Stmt :: skip ( Location :: none ( ) ) ,
755+ | StatementKind :: Coverage { .. } => Stmt :: skip ( location ) ,
742756 }
743757 . with_location ( self . codegen_span ( & stmt. source_info . span ) )
744758 }
0 commit comments