Commit cf6265e7 authored by Julien Signoles's avatar Julien Signoles
Browse files

[typing] minor changes in typing of reals

parent d8902fc0
......@@ -60,9 +60,12 @@ let rec interv_of_typ_with_real ty is_real = match Cil.unrollType ty with
| TEnum(enuminfo, _) ->
interv_of_typ_with_real (TInt (enuminfo.ekind, [])) is_real
| TFloat _ ->
(* TODO RATIONAL: examine TODO below. In particular this case is equivalent
* to the next case when [Real.is_t ty]. *)
(* TODO: Do not systematically consider floats as reals for efficiency *)
Ival.bottom, true
| _ when Real.is_t ty ->
(* TODO RATIONAL: why bottom and not top? Why not raising Is_a_real? *)
Ival.bottom, true
| _ ->
raise Not_a_number
......@@ -71,6 +74,7 @@ let interv_of_logic_typ = function
| Ctype ty -> interv_of_typ_with_real ty false
| Linteger -> Ival.inject_range None None, false
| Lreal -> Ival.bottom, true
(* TODO RATIONAL: why bottom and not top? Why not raising Is_a_real? *)
| Ltype _ -> Error.not_yet "user-defined logic type"
| Lvar _ -> Error.not_yet "type variable"
| Larrow _ -> Error.not_yet "functional type"
......@@ -385,9 +389,12 @@ and infer_term_host thost is_real =
match v.lv_type with
| Linteger ->
Ival.inject_range None None, false
| Ctype (TFloat _) -> (* TODO: handle in MR !226 *)
| Ctype (TFloat _) ->
(* TODO RATIONAL: examine below. That is MR !226! *)
(* TODO: handle in MR !226 *)
raise Not_an_integer
| Lreal ->
(* TODO RATIONAL: why bottom and not top? Why not raising Is_a_real? *)
Ival.bottom, true
| Ctype _ ->
(* TODO RATIONAL: check if [false] is the correct value *)
......
......@@ -905,11 +905,11 @@ let term_to_exp typ t =
(* infer a context from the given [typ] whenever possible *)
let ctx_of_typ ty =
if Gmp.Z.is_t ty then Typing.gmpz
else if Real.is_t ty then Typing.libr
else if Real.is_t ty then Typing.real
else
match ty with
| TInt(ik, _) -> Typing.ikind ik
| TFloat _ -> Typing.libr
| TFloat _ -> Typing.real
| _ -> Typing.nan
in
let ctx = Extlib.opt_map ctx_of_typ typ in
......
......@@ -45,7 +45,7 @@ type number_ty =
let c_int = C_type IInt
let ikind ik = C_type ik
let gmpz = Gmpz
let libr = Real
let real = Real
let nan = Nan
module D =
......@@ -53,7 +53,7 @@ module D =
(struct
type t = number_ty
let name = "E_ACSL.New_typing.t"
let reprs = [ Gmpz; c_int ]
let reprs = [ Gmpz; Real; Nan; c_int ]
include Datatype.Undefined
(* TODO RATIONAL: re-implement this datatype *)
......@@ -208,7 +208,7 @@ let ty_of_interv ?ctx i =
| Some Real -> Real)
with Cil.Not_representable ->
match ctx with
| Some (Real) -> Real
| Some Real -> Real
| None | Some _ -> Gmpz
(* compute a new {!computed_info} by coercing the given type [ty] to the given
......@@ -238,6 +238,7 @@ let offset_ty t =
| ty -> ty
with
| Interval.Is_a_real ->
(* TODO RATIONAL: shouldn't it be 'assert false' because of typing? *)
C_type ILongLong
| Interval.Not_a_number ->
Options.fatal "expected an integral type for %a" Printer.pp_term t
......@@ -287,7 +288,7 @@ let rec type_term ~use_gmp_opt ?(arith_operand=false) ?ctx t =
match t.term_node with
| TConst (LReal _) ->
(* TODO: real: irrationals raise not_yet *)
dup libr
dup real
| TConst (Integer _ | LChr _ | LEnum _)
| TSizeOf _
| TSizeOfStr _
......@@ -307,7 +308,7 @@ let rec type_term ~use_gmp_opt ?(arith_operand=false) ?ctx t =
ty_of_interv ?ctx i
with
| Interval.Not_a_number -> nan
| Interval.Is_a_real -> libr
| Interval.Is_a_real -> real
in
type_term_lval tlv;
dup ty
......@@ -350,14 +351,15 @@ let rec type_term ~use_gmp_opt ?(arith_operand=false) ?ctx t =
| Interval.Not_a_number ->
assert false (* only Is_a_real could be raised *)
| Interval.Is_a_real ->
libr, libr
real, real
in
ignore (type_term ~use_gmp_opt:true ~arith_operand:true ~ctx t');
(match unop with
| LNot -> c_int, ctx_res (* converted into [t == 0] in case of GMP *)
| Neg | BNot -> dup ctx_res)
| TBinOp((PlusA | MinusA | Mult | Div | Mod | Shiftlt | Shiftrt), t1, t2) ->
| TBinOp ((PlusA | MinusA | Mult | Div | Mod | Shiftlt | Shiftrt), t1, t2)
->
let ctx_res, ctx =
try
let i = Interval.infer t in
......@@ -366,14 +368,14 @@ let rec type_term ~use_gmp_opt ?(arith_operand=false) ?ctx t =
compute_ctx ?ctx (Ival.join i (Ival.join i1 i2))
with
| Interval.Is_a_real ->
dup libr
dup real
| Interval.Not_a_number ->
assert false (* only Is_a_real could be raised *)
in
(* it is enough to explicitly coerce when required one operand to [ctx]
(through [arith_operand]) in order to force the type of the operation.
Heuristic: coerce the operand which is not a lval in order to lower
the number of explicit casts *)
(through [arith_operand]) in order to force the type of the
operation. Heuristic: coerce the operand which is not a lval in
order to lower the number of explicit casts *)
let rec cast_first t1 t2 = match t1.term_node with
| TLval _ -> false
| TLogic_coerce(_, t) -> cast_first t t2
......@@ -394,7 +396,7 @@ let rec type_term ~use_gmp_opt ?(arith_operand=false) ?ctx t =
mk_ctx ~use_gmp_opt:true (ty_of_interv ?ctx (Ival.join i1 i2))
with
| Interval.Is_a_real ->
libr
real
| Interval.Not_a_number ->
nan
in
......@@ -434,7 +436,7 @@ let rec type_term ~use_gmp_opt ?(arith_operand=false) ?ctx t =
ty_of_interv ?ctx i
with
| Interval.Not_a_number -> nan
| Interval.Is_a_real -> libr
| Interval.Is_a_real -> real
in
ignore (type_term ~use_gmp_opt:true ~ctx t');
dup ctx
......@@ -511,7 +513,8 @@ let rec type_term ~use_gmp_opt ?(arith_operand=false) ?ctx t =
match lty with
| Linteger ->
let i = Interval.infer t in
if Options.Gmp_only.get () then dup Gmpz else dup (ty_of_interv i)
if Options.Gmp_only.get () then dup Gmpz
else dup (ty_of_interv i)
| Ctype TInt(ik, _ ) ->
dup (C_type ik)
| Ctype TFloat _ -> (* TODO: handle in MR !226 *)
......@@ -559,7 +562,9 @@ let rec type_term ~use_gmp_opt ?(arith_operand=false) ?ctx t =
| Ttypeof _
| Ttype _
| Tempty_set -> dup nan
with Interval.Is_a_real ->
(* TODO RATIONAL: I do not like such a try with *)
Error.not_yet "reals: typing: term using unsupported construct"
in
Memo.memo
......@@ -617,7 +622,7 @@ let rec type_predicate p =
mk_ctx ~use_gmp_opt:true (ty_of_interv ~ctx:c_int i)
with
| Interval.Not_a_number -> nan
| Interval.Is_a_real -> libr
| Interval.Is_a_real -> real
in
ignore (type_term ~use_gmp_opt:true ~ctx t1);
ignore (type_term ~use_gmp_opt:true ~ctx t2);
......
......@@ -65,7 +65,7 @@ module Datatype: Datatype.S_with_collections with type t = number_ty
val c_int: number_ty
val ikind: ikind -> number_ty
val gmpz: number_ty
val libr: number_ty
val real: number_ty
val nan: number_ty
(** {3 Useful operations over {!number_ty}} *)
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment