@@ -1880,12 +1880,11 @@ impl<'tcx> GotocCtx<'tcx> {
18801880 "`dst` must be properly aligned" ,
18811881 loc,
18821882 ) ;
1883- let deref = dst. dereference ( ) ;
1884- if deref. typ ( ) . sizeof ( & self . symbol_table ) == 0 {
1883+ if self . is_zst_stable ( pointee_type_stable ( dst_typ) . unwrap ( ) ) {
18851884 // do not attempt to dereference (and assign) a ZST
18861885 align_check
18871886 } else {
1888- let expr = deref . assign ( src, loc) ;
1887+ let expr = dst . dereference ( ) . assign ( src, loc) ;
18891888 Stmt :: block ( vec ! [ align_check, expr] , loc)
18901889 }
18911890 }
@@ -1991,30 +1990,42 @@ impl<'tcx> GotocCtx<'tcx> {
19911990 let x = fargs. remove ( 0 ) ;
19921991 let y = fargs. remove ( 0 ) ;
19931992
1994- // if(same_object(x, y)) {
1995- // assert(x + 1 <= y || y + 1 <= x);
1996- // assume(x + 1 <= y || y + 1 <= x);
1997- // }
1998- let one = Expr :: int_constant ( 1 , Type :: c_int ( ) ) ;
1999- let non_overlapping =
2000- x. clone ( ) . plus ( one. clone ( ) ) . le ( y. clone ( ) ) . or ( y. clone ( ) . plus ( one. clone ( ) ) . le ( x. clone ( ) ) ) ;
2001- let non_overlapping_check = self . codegen_assert_assume (
2002- non_overlapping,
2003- PropertyClass :: SafetyCheck ,
2004- "memory regions pointed to by `x` and `y` must not overlap" ,
2005- loc,
2006- ) ;
2007- let non_overlapping_stmt =
2008- Stmt :: if_then_else ( x. clone ( ) . same_object ( y. clone ( ) ) , non_overlapping_check, None , loc) ;
1993+ if self . is_zst_stable ( pointee_type_stable ( farg_types[ 0 ] ) . unwrap ( ) ) {
1994+ // do not attempt to dereference (and assign) a ZST
1995+ Stmt :: skip ( loc)
1996+ } else {
1997+ // if(same_object(x, y)) {
1998+ // assert(x + 1 <= y || y + 1 <= x);
1999+ // assume(x + 1 <= y || y + 1 <= x);
2000+ // }
2001+ let one = Expr :: int_constant ( 1 , Type :: c_int ( ) ) ;
2002+ let non_overlapping = x
2003+ . clone ( )
2004+ . plus ( one. clone ( ) )
2005+ . le ( y. clone ( ) )
2006+ . or ( y. clone ( ) . plus ( one. clone ( ) ) . le ( x. clone ( ) ) ) ;
2007+ let non_overlapping_check = self . codegen_assert_assume (
2008+ non_overlapping,
2009+ PropertyClass :: SafetyCheck ,
2010+ "memory regions pointed to by `x` and `y` must not overlap" ,
2011+ loc,
2012+ ) ;
2013+ let non_overlapping_stmt = Stmt :: if_then_else (
2014+ x. clone ( ) . same_object ( y. clone ( ) ) ,
2015+ non_overlapping_check,
2016+ None ,
2017+ loc,
2018+ ) ;
20092019
2010- // T t = *y; *y = *x; *x = t;
2011- let deref_y = y. clone ( ) . dereference ( ) ;
2012- let ( temp_var, assign_to_t) =
2013- self . decl_temp_variable ( deref_y. typ ( ) . clone ( ) , Some ( deref_y) , loc) ;
2014- let assign_to_y = y. dereference ( ) . assign ( x. clone ( ) . dereference ( ) , loc) ;
2015- let assign_to_x = x. dereference ( ) . assign ( temp_var, loc) ;
2020+ // T t = *y; *y = *x; *x = t;
2021+ let deref_y = y. clone ( ) . dereference ( ) ;
2022+ let ( temp_var, assign_to_t) =
2023+ self . decl_temp_variable ( deref_y. typ ( ) . clone ( ) , Some ( deref_y) , loc) ;
2024+ let assign_to_y = y. dereference ( ) . assign ( x. clone ( ) . dereference ( ) , loc) ;
2025+ let assign_to_x = x. dereference ( ) . assign ( temp_var, loc) ;
20162026
2017- Stmt :: block ( vec ! [ non_overlapping_stmt, assign_to_t, assign_to_y, assign_to_x] , loc)
2027+ Stmt :: block ( vec ! [ non_overlapping_stmt, assign_to_t, assign_to_y, assign_to_x] , loc)
2028+ }
20182029 }
20192030}
20202031
0 commit comments