From af4ad89054b851a3bed38977400c48f9b1c51b28 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Loi=CC=88c=20Correnson?= <loic.correnson@cea.fr> Date: Wed, 1 Apr 2020 10:19:24 +0200 Subject: [PATCH] [kernel] also coerce enum constants --- .../ast_queries/logic_utils.ml | 21 +++++++++---------- .../oracle/enum.res.oracle | 4 ++-- .../oracle/cast_enum_bts1546.0.res.oracle | 2 +- 3 files changed, 13 insertions(+), 14 deletions(-) diff --git a/src/kernel_services/ast_queries/logic_utils.ml b/src/kernel_services/ast_queries/logic_utils.ml index c08f9d6d6ae..9f0a5c558d9 100644 --- a/src/kernel_services/ast_queries/logic_utils.ml +++ b/src/kernel_services/ast_queries/logic_utils.ml @@ -227,13 +227,6 @@ let equal_ltype = Cil_datatype.Logic_type.equal let mk_cast ?loc ?(force=false) newt t = let newt = Cil.type_remove_attributes_for_logic_type newt in if equal_ltype (Ctype newt) t.term_type then t else - (* - let rec is_iconst e = match e.term_node with - | TCastE(ty,e) when Cil.isArithmeticOrPointerType ty -> is_iconst e - | TLogic_coerce(Linteger,e) -> is_iconst e - | TConst(Integer _) -> true - | _ -> false in - *) let rec unroll_cast e = match e.term_node with | TCastE(oldt,e) when (Cil.isPointerType newt && Cil.isPointerType oldt) @@ -248,8 +241,8 @@ let mk_cast ?loc ?(force=false) newt t = | _ -> e in let tres = if force then t else unroll_cast t in - let loc = match loc with None -> t.term_loc | Some loc -> loc in - Logic_const.term ~loc (TCastE (newt, tres)) (Ctype newt) + let loc = match loc with None -> t.term_loc | Some loc -> loc in + Logic_const.term ~loc (TCastE (newt, tres)) (Ctype newt) (* -------------------------------------------------------------------------- *) @@ -319,14 +312,20 @@ let numeric_coerce ltyp t = | TLogic_coerce(lt,e) when Cil.no_op_coerce lt e -> (* coercion hidden by the printer, but still present *) mk_coerce ltyp e - | TConst(Integer _) when ltyp = Linteger -> { t with term_type = Linteger } - | TConst(LReal _ ) when ltyp = Lreal -> { t with term_type = Lreal } + | TConst(LEnum _) | 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 } + | Linteger, TInt(ik,_), TConst(LEnum { eival }) -> + ( match Cil.constFoldToInt eival with + | Some i when Cil.fitsInInt ik i -> { e with term_type = Linteger } + | _ -> mk_coerce ltyp t ) | _ -> mk_coerce ltyp t end | _ -> mk_coerce ltyp t diff --git a/tests/constant_propagation/oracle/enum.res.oracle b/tests/constant_propagation/oracle/enum.res.oracle index d7c4e9f6ea0..cbd71cd5823 100644 --- a/tests/constant_propagation/oracle/enum.res.oracle +++ b/tests/constant_propagation/oracle/enum.res.oracle @@ -14,7 +14,7 @@ [eva] Recording results for f [eva] Done for function f [eva:alarm] tests/constant_propagation/enum.i:13: Warning: - signed overflow. assert (int)B + c ≤ 2147483647; + signed overflow. assert B + c ≤ 2147483647; [eva:alarm] tests/constant_propagation/enum.i:15: Warning: signed overflow. assert (int)(y + z) + t ≤ 2147483647; [eva:alarm] tests/constant_propagation/enum.i:15: Warning: @@ -43,7 +43,7 @@ int main(int c, unsigned int u) enum E x = A; int y = f(0U); int z = f(D); - /*@ assert Eva: signed_overflow: (int)B + c ≤ 2147483647; */ + /*@ assert Eva: signed_overflow: B + c ≤ 2147483647; */ int t = B + c; int v = (int)(2U + u); /*@ assert Eva: signed_overflow: (int)(y + z) + t ≤ 2147483647; */ diff --git a/tests/spec/oracle/cast_enum_bts1546.0.res.oracle b/tests/spec/oracle/cast_enum_bts1546.0.res.oracle index 859426aa635..8a5f937eecd 100644 --- a/tests/spec/oracle/cast_enum_bts1546.0.res.oracle +++ b/tests/spec/oracle/cast_enum_bts1546.0.res.oracle @@ -39,7 +39,7 @@ enum e f(enum e x) return __retres; } -/*@ ensures P: \result ≡ (unsigned int)E0; */ +/*@ ensures P: \result ≡ E0; */ enum e g(enum e x) { enum e __retres; -- GitLab