@@ -60,7 +60,7 @@ fn cast_tys<'bv>(bv: BV<'bv>, tys: &[SimpleTy], pw: PointerWidth) -> BV<'bv> {
6060 tys. windows ( 2 ) . fold ( bv, |y, w| cast_bv ( y, w[ 0 ] , w[ 1 ] , pw) )
6161}
6262
63- thread_local ! ( static Z3_CONFIG : Config = Config :: new( ) ) ;
63+ thread_local ! ( static Z3_CONFIG : Config = { let mut c = Config :: new( ) ; c . set_model_generation ( true ) ; c } ) ;
6464thread_local ! ( static Z3_CONTEXT : Context = Z3_CONFIG . with( |cfg| Context :: new( cfg) ) ) ;
6565
6666// Verify `check_double_cast` using Z3
@@ -98,12 +98,23 @@ fn verify_double_cast(pw: PointerWidth, tys: Vec<SimpleTy>) -> bool {
9898
9999 let x = BV :: new_const ( & ctx, "x" , ty_bit_width ( tys[ 0 ] , pw) ) ;
100100 let y = cast_tys ( x. clone ( ) , & tys[ ..] , pw) ;
101- let z = cast_tys ( x, & min_tys[ ..] , pw) ;
101+ let z = cast_tys ( x. clone ( ) , & min_tys[ ..] , pw) ;
102102
103103 // Check the full type list against the minimized one
104104 let solver = Solver :: new ( & ctx) ;
105105 solver. assert ( & z. _eq ( & y) . not ( ) ) ;
106- solver. check ( ) == SatResult :: Unsat
106+ if solver. check ( ) == SatResult :: Unsat {
107+ true
108+ } else {
109+ let model = solver. get_model ( ) . unwrap ( ) ;
110+ panic ! (
111+ "{}b counterexample:\n {:?} =>\n {:?} via tys {tys:?} vs.\n {:?} via min_tys {min_tys:?}" ,
112+ pw. 0 ,
113+ model. eval( & x, true ) . unwrap( ) ,
114+ model. eval( & y, true ) . unwrap( ) ,
115+ model. eval( & z, true ) . unwrap( )
116+ )
117+ }
107118 } )
108119}
109120
0 commit comments