From 6a2cbd4b639cd20cdead0669b9f3c8ef7d753b0e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Loi=CC=88c=20Correnson?= <loic.correnson@cea.fr> Date: Tue, 31 Mar 2020 09:50:03 +0200 Subject: [PATCH] [kernel] cast & coerce simpifications --- src/kernel_services/ast_queries/cil.ml | 9 ++++- src/kernel_services/ast_queries/cil.mli | 3 ++ .../ast_queries/logic_utils.ml | 34 ++++++++----------- 3 files changed, 26 insertions(+), 20 deletions(-) diff --git a/src/kernel_services/ast_queries/cil.ml b/src/kernel_services/ast_queries/cil.ml index d9330b5ab30..a3de91f6122 100644 --- a/src/kernel_services/ast_queries/cil.ml +++ b/src/kernel_services/ast_queries/cil.ml @@ -3063,6 +3063,13 @@ let intKindForValue i (unsigned: bool) = else if fitsInInt ILongLong i then ILongLong else raise Not_representable +(* True is an double constant is finite for a kind *) +let isFiniteFloat fk v = + Floating_point.isfinite @@ + match fk with + | FFloat -> Floating_point.round_to_single_precision_float v + | _ -> v + (* Construct an integer constant with possible truncation if the kind is not specified *) let kinteger64 ~loc ?repr ?kind i = @@ -3631,7 +3638,7 @@ let typeOf_array_elem t = let no_op_coerce typ t = match typ with - | Lreal -> true + | Lreal -> isLogicRealOrFloatType t.term_type | Linteger -> isLogicIntegralType t.term_type | Ltype _ when Logic_const.is_boolean_type typ -> isLogicPureBooleanType t.term_type diff --git a/src/kernel_services/ast_queries/cil.mli b/src/kernel_services/ast_queries/cil.mli index c372bb6514c..9e47d0eedd8 100644 --- a/src/kernel_services/ast_queries/cil.mli +++ b/src/kernel_services/ast_queries/cil.mli @@ -2136,6 +2136,9 @@ val max_unsigned_number: int -> Integer.t (** True if the integer fits within the kind's range *) val fitsInInt: ikind -> Integer.t -> bool +(** True if the float is finite for the kind's range *) +val isFiniteFloat: fkind -> float -> bool + exception Not_representable (** raised by {!intKindForValue}. *) diff --git a/src/kernel_services/ast_queries/logic_utils.ml b/src/kernel_services/ast_queries/logic_utils.ml index 8a43475ab1c..c79a9d15400 100644 --- a/src/kernel_services/ast_queries/logic_utils.ml +++ b/src/kernel_services/ast_queries/logic_utils.ml @@ -307,29 +307,25 @@ let string_to_float_lconstant string = LReal { r_nearest = f.f_nearest; r_upper = f.f_upper; r_lower = f.f_lower; r_literal = string } +let mk_coerce ltyp t = + Logic_const.term ~loc:t.term_loc (TLogic_coerce(ltyp, t)) ltyp + let numeric_coerce ltyp t = - let coerce t = - Logic_const.term ~loc:t.term_loc (TLogic_coerce(ltyp, t)) ltyp - in let oldt = unroll_type t.term_type in if Cil_datatype.Logic_type.equal oldt ltyp then t else match t.term_node with - | TLogic_coerce(t,e) when Cil.no_op_coerce t e -> coerce e - | TConst(Integer(i,_)) -> - (match oldt, ltyp with - | Ctype (TInt(ikind,_)), Linteger when Cil.fitsInInt ikind i -> - { t with term_type = Linteger } - | _ -> coerce t) - | TCastE(typ, ({ term_node = TConst(Integer(i,_))} as t')) -> - (match unrollType typ with - | TInt (ikind,_) when Cil.fitsInInt ikind i -> - (match unroll_type t'.term_type with - | Linteger -> t' - | Ctype (TInt (ikind,_)) when Cil.fitsInInt ikind i -> - { t' with term_type = Linteger } - | _ -> coerce t') - | _ -> coerce t) - | _ -> coerce t + | TLogic_coerce(lt,e) when Cil.no_op_coerce lt e -> mk_coerce ltyp e + | TConst(Integer _) when ltyp = Linteger -> { t with term_type = Linteger } + | TConst(LReal _ ) when ltyp = Lreal -> { t with term_type = Lreal } + | TCastE(ty,e) -> + begin match ltyp, Cil.unrollType ty, e.term_node with + | Linteger, TInt(ik,_), TConst(Integer(v,_)) + when Cil.fitsInInt ik v -> { e with term_type = Linteger } + | Lreal, TFloat(fk,_), TConst(LReal r) + when Cil.isFiniteFloat fk r.r_nearest -> { e with term_type = Lreal } + | _ -> mk_coerce ltyp t + end + | _ -> mk_coerce ltyp t (* Don't forget to keep is_zero_comparable and scalar_term_to_predicate in sync. *) -- GitLab