@@ -709,18 +709,22 @@ struct
709709 | _ -> Int c
710710 in
711711 (* handle special calls *)
712- begin match t with
713- | TInt (ik , _ ) ->
714- begin match x with
715- | ((Var v ), offs ) ->
716- if M. tracing then M. trace " invSpecial" " qry Result: %a\n " Queries.ML. pretty (ctx.ask (Queries. TmpSpecial (v, Offset.Exp. of_cil offs)));
717- let tv_opt = ID. to_bool c in
718- begin match tv_opt with
712+ begin match x, t with
713+ | (Var v , offs ), TInt (ik , _ ) ->
714+ let tmpSpecial = ctx.ask (Queries. TmpSpecial (v, Offset.Exp. of_cil offs)) in
715+ if M. tracing then M. trace " invSpecial" " qry Result: %a\n " Queries.ML. pretty tmpSpecial;
716+ begin match tmpSpecial with
717+ | `Lifted (Abs (ik , xInt )) ->
718+ let c' = ID. cast_to ik c in (* different ik! *)
719+ inv_exp (Int (ID. join c' (ID. neg c'))) xInt st
720+ | tmpSpecial ->
721+ begin match ID. to_bool c with
719722 | Some tv ->
720- begin match ctx.ask ( Queries. TmpSpecial (v, Offset.Exp. of_cil offs)) with
723+ begin match tmpSpecial with
721724 | `Lifted (Isfinite xFloat ) when tv -> inv_exp (Float (FD. finite (unroll_fk_of_exp xFloat))) xFloat st
722725 | `Lifted (Isnan xFloat ) when tv -> inv_exp (Float (FD. nan_of (unroll_fk_of_exp xFloat))) xFloat st
723726 (* should be correct according to C99 standard*)
727+ (* The following do to_bool and of_bool to convert Not{0} into 1 for downstream float inversions *)
724728 | `Lifted (Isgreater (xFloat , yFloat )) -> inv_exp (Int (ID. of_bool ik tv)) (BinOp (Gt , xFloat, yFloat, (typeOf xFloat))) st
725729 | `Lifted (Isgreaterequal (xFloat , yFloat )) -> inv_exp (Int (ID. of_bool ik tv)) (BinOp (Ge , xFloat, yFloat, (typeOf xFloat))) st
726730 | `Lifted (Isless (xFloat , yFloat )) -> inv_exp (Int (ID. of_bool ik tv)) (BinOp (Lt , xFloat, yFloat, (typeOf xFloat))) st
@@ -730,9 +734,8 @@ struct
730734 end
731735 | None -> update_lval c x c' ID. pretty
732736 end
733- | _ -> update_lval c x c' ID. pretty
734737 end
735- | _ -> update_lval c x c' ID. pretty
738+ | _ , _ -> update_lval c x c' ID. pretty
736739 end
737740 | Float c ->
738741 let c' = match t with
@@ -744,22 +747,19 @@ struct
744747 | _ -> Float c
745748 in
746749 (* handle special calls *)
747- begin match t with
748- | TFloat (fk , _ ) ->
749- begin match x with
750- | ((Var v ), offs ) ->
751- if M. tracing then M. trace " invSpecial" " qry Result: %a\n " Queries.ML. pretty (ctx.ask (Queries. TmpSpecial (v, Offset.Exp. of_cil offs)));
752- begin match ctx.ask (Queries. TmpSpecial (v, Offset.Exp. of_cil offs)) with
753- | `Lifted (Ceil (ret_fk , xFloat )) -> inv_exp (Float (FD. inv_ceil (FD. cast_to ret_fk c))) xFloat st
754- | `Lifted (Floor (ret_fk , xFloat )) -> inv_exp (Float (FD. inv_floor (FD. cast_to ret_fk c))) xFloat st
755- | `Lifted (Fabs (ret_fk , xFloat )) ->
756- let inv = FD. inv_fabs (FD. cast_to ret_fk c) in
757- if FD. is_bot inv then
758- raise Analyses. Deadcode
759- else
760- inv_exp (Float inv) xFloat st
761- | _ -> update_lval c x c' FD. pretty
762- end
750+ begin match x, t with
751+ | (Var v , offs ), TFloat (fk , _ ) ->
752+ let tmpSpecial = ctx.ask (Queries. TmpSpecial (v, Offset.Exp. of_cil offs)) in
753+ if M. tracing then M. trace " invSpecial" " qry Result: %a\n " Queries.ML. pretty tmpSpecial;
754+ begin match tmpSpecial with
755+ | `Lifted (Ceil (ret_fk , xFloat )) -> inv_exp (Float (FD. inv_ceil (FD. cast_to ret_fk c))) xFloat st
756+ | `Lifted (Floor (ret_fk , xFloat )) -> inv_exp (Float (FD. inv_floor (FD. cast_to ret_fk c))) xFloat st
757+ | `Lifted (Fabs (ret_fk , xFloat )) ->
758+ let inv = FD. inv_fabs (FD. cast_to ret_fk c) in
759+ if FD. is_bot inv then
760+ raise Analyses. Deadcode
761+ else
762+ inv_exp (Float inv) xFloat st
763763 | _ -> update_lval c x c' FD. pretty
764764 end
765765 | _ -> update_lval c x c' FD. pretty
@@ -821,31 +821,4 @@ struct
821821 FD. top_of fk
822822 in
823823 inv_exp (Float ftv) exp st
824-
825- let invariant ctx a gs st exp tv : D.t =
826- let refine0 = invariant ctx a gs st exp tv in
827- (* bodge for abs(...); To be removed once we have a clean solution *)
828- let refineAbs op absargexp valexp =
829- let flip op = match op with | Le -> Ge | Lt -> Gt | _ -> failwith " impossible" in
830- (* e.g. |arg| <= 40 *)
831- (* arg <= e (arg <= 40) *)
832- let le = BinOp (op, absargexp, valexp, intType) in
833- (* arg >= -e (arg >= -40) *)
834- let gt = BinOp (flip op, absargexp, UnOp (Neg , valexp, Cilfacade. typeOf valexp), intType) in
835- let one = invariant ctx (Analyses. ask_of_ctx ctx) ctx.global refine0 le tv in
836- invariant ctx (Analyses. ask_of_ctx ctx) ctx.global one gt tv
837- in
838- match exp with
839- | BinOp ((Lt |Le ) as op , CastE (t , Lval (Var v , NoOffset)), e ,_ ) when tv ->
840- begin match ctx.ask (Queries. TmpSpecial (v, Offset.Exp. of_cil NoOffset )) with
841- | `Lifted (Abs (ik , arg )) -> refineAbs op (CastE (t, arg)) e
842- | _ -> refine0
843- end
844- | BinOp ((Lt |Le ) as op , Lval (Var v , NoOffset), e , _ ) when tv ->
845- begin match ctx.ask (Queries. TmpSpecial (v, Offset.Exp. of_cil NoOffset )) with
846- | `Lifted (Abs (ik , arg )) -> refineAbs op arg e
847- | _ -> refine0
848- end
849- | _ -> refine0
850-
851824end
0 commit comments