diff --git a/.Makefile.lint b/.Makefile.lint
index b48bf3c53ff5260e2504cf1acfe877b4b0c18654..ab56229610dcc197dccd748b378f559eb49cf884 100644
--- a/.Makefile.lint
+++ b/.Makefile.lint
@@ -68,8 +68,6 @@ ML_LINT_KO+=src/kernel_services/analysis/stmts_graph.mli
 ML_LINT_KO+=src/kernel_services/analysis/undefined_sequence.ml
 ML_LINT_KO+=src/kernel_services/analysis/wto_statement.ml
 ML_LINT_KO+=src/kernel_services/analysis/wto_statement.mli
-ML_LINT_KO+=src/kernel_services/ast_data/alarms.ml
-ML_LINT_KO+=src/kernel_services/ast_data/alarms.mli
 ML_LINT_KO+=src/kernel_services/ast_data/annotations.ml
 ML_LINT_KO+=src/kernel_services/ast_data/annotations.mli
 ML_LINT_KO+=src/kernel_services/ast_data/ast.ml
diff --git a/src/kernel_services/ast_data/alarms.ml b/src/kernel_services/ast_data/alarms.ml
index eaa9455b742e798965fc88a2a3a954ae384b7378..261c438947f7ae2a7db33086e00afa7d6209b9d3 100644
--- a/src/kernel_services/ast_data/alarms.ml
+++ b/src/kernel_services/ast_data/alarms.ml
@@ -37,22 +37,22 @@ type alarm =
   | Division_by_zero of exp
   | Memory_access of lval * access_kind
   | Index_out_of_bound of
-      exp (* index *) 
-    * exp option (* None = lower bound is zero; Some up = upper bound *) 
+      exp (* index *)
+      * exp option (* None = lower bound is zero; Some up = upper bound *)
   | Invalid_shift of exp * int option (* strict upper bound, if any *)
   | Pointer_comparison of
-      exp option (* [None] when implicit comparison to 0 *) 
-    * exp
+      exp option (* [None] when implicit comparison to 0 *)
+      * exp
   | Differing_blocks of exp * exp
   | Overflow of
       overflow_kind
-    * exp
-    * Integer.t (* the bound *) 
-    * bound_kind
+      * exp
+      * Integer.t (* the bound *)
+      * bound_kind
   | Float_to_int of
       exp
-    * Integer.t (* the bound *) 
-    * bound_kind
+      * Integer.t (* the bound *)
+      * bound_kind
   | Not_separated of lval * lval
   | Overlap of lval * lval
   | Uninitialized of lval
@@ -174,26 +174,26 @@ module D =
                 else Lval.compare lv1 lv2
               ) 0 llv1 llv2
             | _ -> assert false
-          end              
-          | Dangling lv1, Dangling lv2 -> Lval.compare lv1 lv2
-          | Differing_blocks (e11, e12), Differing_blocks (e21, e22) ->
-            let n = Exp.compare e11 e21 in
-            if n = 0 then Exp.compare e12 e22 else n
-          | Function_pointer (e1, l1), Function_pointer (e2, l2) ->
-            let n = Exp.compare e1 e2 in
-            if n <> 0 then n
-            else Extlib.opt_compare (Extlib.list_compare Exp.compare) l1 l2
-          | Invalid_bool lv1, Invalid_bool lv2 -> Lval.compare lv1 lv2
-          | _, (Division_by_zero _ | Memory_access _ |
-                Index_out_of_bound _ | Invalid_shift _ | Pointer_comparison _ |
-                Overflow _ | Not_separated _ | Overlap _ | Uninitialized _ |
-                Dangling _ | Is_nan_or_infinite _ | Is_nan _ | Float_to_int _ |
-                Differing_blocks _ | Function_pointer _ |
-                Uninitialized_union _  | Invalid_bool _)
-            ->
-            let n = nb a1 - nb a2 in
-            assert (n <> 0);
-            n
+          end
+        | Dangling lv1, Dangling lv2 -> Lval.compare lv1 lv2
+        | Differing_blocks (e11, e12), Differing_blocks (e21, e22) ->
+          let n = Exp.compare e11 e21 in
+          if n = 0 then Exp.compare e12 e22 else n
+        | Function_pointer (e1, l1), Function_pointer (e2, l2) ->
+          let n = Exp.compare e1 e2 in
+          if n <> 0 then n
+          else Extlib.opt_compare (Extlib.list_compare Exp.compare) l1 l2
+        | Invalid_bool lv1, Invalid_bool lv2 -> Lval.compare lv1 lv2
+        | _, (Division_by_zero _ | Memory_access _ |
+              Index_out_of_bound _ | Invalid_shift _ | Pointer_comparison _ |
+              Overflow _ | Not_separated _ | Overlap _ | Uninitialized _ |
+              Dangling _ | Is_nan_or_infinite _ | Is_nan _ | Float_to_int _ |
+              Differing_blocks _ | Function_pointer _ |
+              Uninitialized_union _  | Invalid_bool _)
+          ->
+          let n = nb a1 - nb a2 in
+          assert (n <> 0);
+          n
 
       let equal = Datatype.from_compare
 
@@ -204,24 +204,24 @@ module D =
         | Is_nan (e, fk) ->
           Hashtbl.hash (nb a, Exp.hash e, fk)
         | Memory_access(lv, b) -> Hashtbl.hash (nb a, Lval.hash lv, b)
-        | Index_out_of_bound(e1, e2) -> 
+        | Index_out_of_bound(e1, e2) ->
           Hashtbl.hash
-            (nb a, 
-             Exp.hash e1, 
+            (nb a,
+             Exp.hash e1,
              match e2 with None -> 0 | Some e -> 17 + Exp.hash e)
         | Invalid_shift(e, n) -> Hashtbl.hash (nb a, Exp.hash e, n)
-        | Pointer_comparison(e1, e2) -> 
-          Hashtbl.hash 
-            (nb a, 
-             (match e1 with None -> 0 | Some e -> 17 + Exp.hash e), 
+        | Pointer_comparison(e1, e2) ->
+          Hashtbl.hash
+            (nb a,
+             (match e1 with None -> 0 | Some e -> 17 + Exp.hash e),
              Exp.hash e2)
-        | Differing_blocks (e1, e2) -> 
+        | Differing_blocks (e1, e2) ->
           Hashtbl.hash (nb a, Exp.hash e1, Exp.hash e2)
         | Overflow(s, e, n, b) ->
           Hashtbl.hash (s, nb a, Exp.hash e, Integer.hash n, b)
         | Float_to_int(e, n, b) ->
           Hashtbl.hash (nb a, Exp.hash e, Integer.hash n, b)
-        | Not_separated(lv1, lv2) | Overlap(lv1, lv2) -> 
+        | Not_separated(lv1, lv2) | Overlap(lv1, lv2) ->
           Hashtbl.hash (nb a, Lval.hash lv1, Lval.hash lv2)
         | Uninitialized lv -> Hashtbl.hash (nb a, Lval.hash lv)
         | Dangling lv -> Hashtbl.hash (nb a, Lval.hash lv)
@@ -235,7 +235,7 @@ module D =
       let varname = Datatype.undefined
 
       let pretty fmt = function
-        | Division_by_zero e -> 
+        | Division_by_zero e ->
           Format.fprintf fmt "Division_by_zero(@[%a@])" Printer.pp_exp e
         | Is_nan_or_infinite (e, fk) ->
           Format.fprintf fmt "Is_nan_or_infinite(@[(%a)%a@])"
@@ -244,14 +244,14 @@ module D =
           Format.fprintf fmt "Is_nan(@[(%a)%a@])"
             Printer.pp_fkind fk Printer.pp_exp e
         | Memory_access(lv, read) ->
-          Format.fprintf fmt "Memory_access(@[%a@],@ %s)" 
+          Format.fprintf fmt "Memory_access(@[%a@],@ %s)"
             Printer.pp_lval lv
             (match read with For_reading -> "read" | For_writing -> "write")
         | Index_out_of_bound(e1, e2) ->
-          Format.fprintf fmt "Index_out_of_bound(@[%a@]@ %s@ @[%a@])" 
+          Format.fprintf fmt "Index_out_of_bound(@[%a@]@ %s@ @[%a@])"
             Printer.pp_exp e1
             (match e2 with None -> ">=" | Some _ -> "<")
-            Printer.pp_exp 
+            Printer.pp_exp
             (match e2 with None -> Cil.zero e1.eloc | Some e -> e)
         | Invalid_shift(e, n) ->
           Format.fprintf fmt "Invalid_shift(@[%a@]@ %s)"
@@ -259,12 +259,12 @@ module D =
             (match n with None -> "" | Some n -> "<= " ^ string_of_int n)
         | Pointer_comparison(e1, e2) ->
           Format.fprintf fmt "Pointer_comparison(@[%a@],@ @[%a@])"
-            Printer.pp_exp 
+            Printer.pp_exp
             (match e1 with None -> Cil.zero e2.eloc | Some e -> e)
             Printer.pp_exp e2
         | Differing_blocks (e1, e2) ->
           Format.fprintf fmt "Differing_blocks(@[%a@],@ @[%a@])"
-            Printer.pp_exp e1 Printer.pp_exp e2          
+            Printer.pp_exp e1 Printer.pp_exp e2
         | Overflow(s, e, n, b) ->
           Format.fprintf fmt "%s(@[%a@]@ %s@ @[%a@])"
             (String.capitalize_ascii (string_of_overflow_kind s))
@@ -277,8 +277,8 @@ module D =
             (match b with Lower_bound -> ">" | Upper_bound -> "<")
             Datatype.Integer.pretty
             ((match b with
-            | Lower_bound -> Integer.sub
-            | Upper_bound -> Integer.add) n Integer.one)
+                | Lower_bound -> Integer.sub
+                | Upper_bound -> Integer.add) n Integer.one)
         | Not_separated(lv1, lv2) ->
           Format.fprintf fmt "Not_separated(@[%a@],@ @[%a@])"
             Lval.pretty lv1 Lval.pretty lv2
@@ -292,8 +292,8 @@ module D =
         | Function_pointer (e, _) ->
           Format.fprintf fmt "Function_pointer(@[%a@])" Exp.pretty e
         | Uninitialized_union llv ->
-          Format.fprintf fmt "Uninitialized_union(@[[%a]@])" 
-            (Format.pp_print_list ~pp_sep:(fun fmt () -> Format.fprintf fmt "; ") Lval.pretty) 
+          Format.fprintf fmt "Uninitialized_union(@[[%a]@])"
+            (Format.pp_print_list ~pp_sep:(fun fmt () -> Format.fprintf fmt "; ") Lval.pretty)
             llv
         | Invalid_bool lv ->
           Format.fprintf fmt "Invalid_bool(@[%a@])" Lval.pretty lv
@@ -301,7 +301,7 @@ module D =
       let internal_pretty_code = Datatype.undefined
       let copy = Datatype.undefined
       let mem_project = Datatype.never_any_project
-     end)
+    end)
 
 include D
 
@@ -320,12 +320,12 @@ module State =
     (D.Hashtbl.Make
        (Datatype.Quadruple
           (Code_annotation)(Kernel_function)(Stmt)(Datatype.Int)))
-    (struct 
-      let name = "Alarms.State" 
-      let dependencies = [ Ast.self; Rank.self ] 
+    (struct
+      let name = "Alarms.State"
+      let dependencies = [ Ast.self; Rank.self ]
       let kinds = [ Emitter.Alarm ]
       let size = 97
-     end)
+    end)
 
 let () =
   State.add_hook_on_remove
@@ -344,12 +344,12 @@ module Alarm_of_annot =
       let name = "Alarms.Alarm_of_annot"
       let dependencies = [ Ast.self; Rank.self ]
       let size = 97
-     end)
+    end)
 
 let self = State.self
 let () = Ast.add_monotonic_state self
 
-let emit_status emitter kf stmt annot status = 
+let emit_status emitter kf stmt annot status =
   let p = Property.ip_of_code_annot_single kf stmt annot in
   Property_status.emit emitter ~hyps:[] p ~distinct:true status
 
@@ -360,17 +360,17 @@ let emit_status emitter kf stmt annot status =
 let alarm_kf_stmt ?kf kinstr =
   match kinstr with
   | Kglobal -> begin
-    let kf = match kf with
-      | None -> fst (Globals.entry_point ())
-      | Some kf -> 
-        Kernel.fatal "inconsistency in alarm location" Kernel_function.pretty kf
-    in
-    try
-      let stmt = Kernel_function.find_first_stmt kf in
-      kf, stmt
-    with Kernel_function.No_Statement ->
-      (* TODO: this can actually happen *)
-      Kernel.fatal "[Alarm] main function has no code"
+      let kf = match kf with
+        | None -> fst (Globals.entry_point ())
+        | Some kf ->
+          Kernel.fatal "inconsistency in alarm location" Kernel_function.pretty kf
+      in
+      try
+        let stmt = Kernel_function.find_first_stmt kf in
+        kf, stmt
+      with Kernel_function.No_Statement ->
+        (* TODO: this can actually happen *)
+        Kernel.fatal "[Alarm] main function has no code"
     end
   | Kstmt stmt -> begin
       let kf = match kf with
@@ -433,24 +433,24 @@ let get_description = function
 (* Given a "topmost" location and another one supposed to be more precise,
    returns the best (hopefully not unknown) one. *)
 let best_loc ~loc loc' =
-   if Location.equal loc' Location.unknown then loc else loc'
+  if Location.equal loc' Location.unknown then loc else loc'
 
 let overflowed_expr_to_term ~loc e =
   let loc = best_loc ~loc e.eloc in
   match e.enode with
-  | UnOp(op, e, ty) -> 
+  | UnOp(op, e, ty) ->
     let t = Logic_utils.expr_to_term ~cast:true e in
     let ty = Logic_utils.typ_to_logic_type ty in
     Logic_const.term ~loc (TUnOp(op, t)) ty
-  | BinOp(op, e1, e2, ty) -> 
+  | BinOp(op, e1, e2, ty) ->
     let t1 = Logic_utils.expr_to_term ~cast:true e1 in
     let t2 = Logic_utils.expr_to_term ~cast:true e2 in
     let ty = Logic_utils.typ_to_logic_type ty in
     Logic_const.term ~loc (TBinOp(op, t1, t2)) ty
   | _ -> Logic_utils.expr_to_term ~cast:true e
 
-  (* Creates \is_finite((fkind)e) or \is_nan((fkind)e) according to
-     [predicate]. *)
+(* Creates \is_finite((fkind)e) or \is_nan((fkind)e) according to
+   [predicate]. *)
 let create_special_float_predicate ~loc e fkind predicate =
   let loc = best_loc ~loc e.eloc in
   let t = Logic_utils.expr_to_term ~cast:true e in
@@ -473,174 +473,188 @@ let create_special_float_predicate ~loc e fkind predicate =
   in
   Logic_const.unamed ~loc (Papp (pi, [], [ t ]))
 
-let create_predicate ?(loc=Location.unknown) alarm = 
+let create_predicate ?(loc=Location.unknown) alarm =
   let aux = function
-  | Division_by_zero e -> 
-    (* e != 0 *)
-    let loc = best_loc ~loc e.eloc in
-    let t = Logic_utils.expr_to_term ~cast:true e in
-    Logic_const.prel ~loc (Rneq, t, Cil.lzero ())
-
-  | Memory_access(lv, read) -> 
-    (* \valid(lv) or \valid_read(lv) according to read *)
-    let valid = match read with
-      | For_reading -> Logic_const.pvalid_read
-      | For_writing -> Logic_const.pvalid
-    in
-    let e = Cil.mkAddrOrStartOf ~loc lv in
-    let t = Logic_utils.expr_to_term ~cast:true e in
-    valid ~loc (Logic_const.here_label, t)
-
-  | Index_out_of_bound(e1, e2) ->
-    (* 0 <= e1 < e2, left part if None, right part if Some e *)
-    let loc = best_loc ~loc e1.eloc in
-    let t1 = Logic_utils.expr_to_term ~cast:true e1 in
-    (match e2 with
-    | None -> Logic_const.prel ~loc (Rle, Cil.lzero (), t1)
-    | Some e2 ->
+    | Division_by_zero e ->
+      (* e != 0 *)
+      let loc = best_loc ~loc e.eloc in
+      let t = Logic_utils.expr_to_term ~cast:true e in
+      Logic_const.prel ~loc (Rneq, t, Cil.lzero ())
+
+    | Memory_access(lv, read) ->
+      (* \valid(lv) or \valid_read(lv) according to read *)
+      let valid = match read with
+        | For_reading -> Logic_const.pvalid_read
+        | For_writing -> Logic_const.pvalid
+      in
+      let e = Cil.mkAddrOrStartOf ~loc lv in
+      let t = Logic_utils.expr_to_term ~cast:true e in
+      valid ~loc (Logic_const.here_label, t)
+
+    | Index_out_of_bound(e1, e2) ->
+      (* 0 <= e1 < e2, left part if None, right part if Some e *)
+      let loc = best_loc ~loc e1.eloc in
+      let t1 = Logic_utils.expr_to_term ~cast:true e1 in
+      (match e2 with
+       | None -> Logic_const.prel ~loc (Rle, Cil.lzero (), t1)
+       | Some e2 ->
+         let t2 = Logic_utils.expr_to_term ~cast:true e2 in
+         Logic_const.prel ~loc (Rlt, t1, t2))
+
+    | Invalid_shift(e, n) ->
+      (* 0 <= e < n *)
+      let loc = best_loc ~loc e.eloc in
+      let t = Logic_utils.expr_to_term ~cast:true e in
+      let low_cmp = Logic_const.prel ~loc (Rle, Cil.lzero (), t) in
+      (match n with
+       | None -> low_cmp
+       | Some n ->
+         let tn = Logic_const.tint ~loc (Integer.of_int n) in
+         let up_cmp = Logic_const.prel ~loc (Rlt, t, tn) in
+         Logic_const.pand ~loc (low_cmp, up_cmp))
+
+    | Pointer_comparison(e1, e2) ->
+      (* \pointer_comparable(e1, e2) *)
+      let loc = best_loc ~loc e2.eloc in
+      let t1 = match e1 with
+        | None -> begin
+            let typ = match Cil.unrollTypeDeep (Cil.typeOf e2) with
+              | TPtr (TFun _, _) -> TPtr (TFun(Cil.voidType, None, false, []), [])
+              | _ -> Cil.voidPtrType
+            in
+            let zero = Cil.lzero () in
+            Logic_const.term (TCastE (typ, zero)) (Ctype typ)
+          end
+        | Some e -> Logic_utils.expr_to_term ~cast:true e
+      in
       let t2 = Logic_utils.expr_to_term ~cast:true e2 in
-      Logic_const.prel ~loc (Rlt, t1, t2))
-
-  | Invalid_shift(e, n) -> 
-    (* 0 <= e < n *)
-    let loc = best_loc ~loc e.eloc in
-    let t = Logic_utils.expr_to_term ~cast:true e in
-    let low_cmp = Logic_const.prel ~loc (Rle, Cil.lzero (), t) in
-    (match n with
-    | None -> low_cmp
-    | Some n ->
-      let tn = Logic_const.tint ~loc (Integer.of_int n) in
-      let up_cmp = Logic_const.prel ~loc (Rlt, t, tn) in
-      Logic_const.pand ~loc (low_cmp, up_cmp))
-
-  | Pointer_comparison(e1, e2) ->
-    (* \pointer_comparable(e1, e2) *)
-    let loc = best_loc ~loc e2.eloc in
-    let t1 = match e1 with
-      | None -> begin
-          let typ = match Cil.unrollTypeDeep (Cil.typeOf e2) with
-            | TPtr (TFun _, _) -> TPtr (TFun(Cil.voidType, None, false, []), [])
-            | _ -> Cil.voidPtrType
-          in
-          let zero = Cil.lzero () in
-          Logic_const.term (TCastE (typ, zero)) (Ctype typ)
-        end
-      | Some e -> Logic_utils.expr_to_term ~cast:true e
-    in
-    let t2 = Logic_utils.expr_to_term ~cast:true e2 in
-    Logic_utils.pointer_comparable ~loc t1 t2
-
-  | Differing_blocks(e1, e2) ->
-    (* \base_addr(e1) == \base_addr(e2) *)
-    let loc = best_loc ~loc e1.eloc in
-    let t1 = Logic_utils.expr_to_term ~cast:true e1 in
-    let here = Logic_const.here_label in
-    let typ = Ctype Cil.charPtrType in
-    let t1 =
-      Logic_const.term ~loc:(best_loc loc e1.eloc) (Tbase_addr(here, t1)) typ
-    in
-    let t2 = Logic_utils.expr_to_term ~cast:true e2 in
-    let t2 =
-      Logic_const.term ~loc:(best_loc loc e2.eloc) (Tbase_addr(here, t2)) typ
-    in
-    Logic_const.prel ~loc (Req, t1, t2)
-
-  | Overflow(_, e, n, bound) -> 
-    (* n <= e or e <= n according to bound *)
-    let loc = best_loc ~loc e.eloc in
-    let t = overflowed_expr_to_term ~loc e in
-    let tn = Logic_const.tint ~loc n in
-    Logic_const.prel ~loc
-      (match bound with Lower_bound -> Rle, tn, t | Upper_bound -> Rle, t, tn)
-
-  | Float_to_int(e, n, bound) -> 
-    (* n < e or e < n according to bound *)
-    let loc = best_loc ~loc e.eloc in
-    let te = overflowed_expr_to_term ~loc e in
-    let t = Logic_const.tlogic_coerce ~loc te Lreal in
-    let n = 
-      (match bound with Lower_bound -> Integer.sub | Upper_bound -> Integer.add)
-        n Integer.one 
-    in
-    let tn = Logic_const.tlogic_coerce ~loc (Logic_const.tint ~loc n) Lreal in
-    Logic_const.prel ~loc
-      (match bound with Lower_bound -> Rlt, tn, t | Upper_bound -> Rlt, t, tn)
-
-  | Not_separated(lv1, lv2) -> 
-    (* \separated(lv1, lv2) *)
-    let e1 = Cil.mkAddrOf ~loc lv1 in
-    let t1 = Logic_utils.expr_to_term ~cast:true e1 in
-    let e2 = Cil.mkAddrOf ~loc lv2 in
-    let t2 = Logic_utils.expr_to_term ~cast:true e2 in
-    Logic_const.pseparated ~loc [ t1; t2 ]
+      Logic_utils.pointer_comparable ~loc t1 t2
+
+    | Differing_blocks(e1, e2) ->
+      (* \base_addr(e1) == \base_addr(e2) *)
+      let loc = best_loc ~loc e1.eloc in
+      let t1 = Logic_utils.expr_to_term ~cast:true e1 in
+      let here = Logic_const.here_label in
+      let typ = Ctype Cil.charPtrType in
+      let t1 =
+        Logic_const.term ~loc:(best_loc loc e1.eloc) (Tbase_addr(here, t1)) typ
+      in
+      let t2 = Logic_utils.expr_to_term ~cast:true e2 in
+      let t2 =
+        Logic_const.term ~loc:(best_loc loc e2.eloc) (Tbase_addr(here, t2)) typ
+      in
+      Logic_const.prel ~loc (Req, t1, t2)
+
+    | Overflow(kind, e, n, bound) ->
+      (* n <= e or e <= n according to bound *)
+      let loc = best_loc ~loc e.eloc in
+      let exp_type = Cil.typeOf e in
+      let t = match kind with
+        | Signed_downcast | Unsigned_downcast
+          when Cil.isUnsignedInteger exp_type ->
+          let t = overflowed_expr_to_term ~loc e in
+          (* Without this cast, the alarm is:
+             - Signed_downcast: unsound ->
+               uint x=0; int i=(x-1u); // 0u-1u < INT_MAX: OK
+             - Unsigned_downcast: too restrictive ->
+               uint x=UINT_MAX; uchar i=(x+1u); // UINT_MAX+1 < UCHAR_MAX : NOK
+          *)
+          Logic_utils.mk_cast exp_type t
+        | _ ->
+          overflowed_expr_to_term ~loc e
+      in
+      let tn = Logic_const.tint ~loc n in
+      Logic_const.prel ~loc
+        (match bound with Lower_bound -> Rle, tn, t | Upper_bound -> Rle, t, tn)
+
+    | Float_to_int(e, n, bound) ->
+      (* n < e or e < n according to bound *)
+      let loc = best_loc ~loc e.eloc in
+      let te = overflowed_expr_to_term ~loc e in
+      let t = Logic_const.tlogic_coerce ~loc te Lreal in
+      let n =
+        (match bound with Lower_bound -> Integer.sub | Upper_bound -> Integer.add)
+          n Integer.one
+      in
+      let tn = Logic_const.tlogic_coerce ~loc (Logic_const.tint ~loc n) Lreal in
+      Logic_const.prel ~loc
+        (match bound with Lower_bound -> Rlt, tn, t | Upper_bound -> Rlt, t, tn)
+
+    | Not_separated(lv1, lv2) ->
+      (* \separated(lv1, lv2) *)
+      let e1 = Cil.mkAddrOf ~loc lv1 in
+      let t1 = Logic_utils.expr_to_term ~cast:true e1 in
+      let e2 = Cil.mkAddrOf ~loc lv2 in
+      let t2 = Logic_utils.expr_to_term ~cast:true e2 in
+      Logic_const.pseparated ~loc [ t1; t2 ]
 
-  | Overlap(lv1, lv2) -> 
-    (* (lv1 == lv2) || \separated(lv1, lv2) *)
-    let e1 = Cil.mkAddrOf ~loc lv1 in
-    let t1 = Logic_utils.expr_to_term ~cast:true e1 in
-    let e2 = Cil.mkAddrOf ~loc lv2 in
-    let t2 = Logic_utils.expr_to_term ~cast:true e2 in
-    let eq = Logic_const.prel ~loc (Req, t1, t2) in
-    let sep = Logic_const.pseparated ~loc [ t1; t2 ] in
-    Logic_const.por ~loc (eq, sep)
-
-  | Uninitialized lv -> 
-    (* \initialized(lv) *)
-    let e = Cil.mkAddrOrStartOf ~loc lv in
-    let t = Logic_utils.expr_to_term ~cast:false e in
-    Logic_const.pinitialized ~loc (Logic_const.here_label, t)
-
-  | Dangling lv -> 
-    (* !\dangling(lv) *)
-    let e = Cil.mkAddrOrStartOf ~loc lv in
-    let t = Logic_utils.expr_to_term ~cast:false e in
-    Logic_const.(pnot ~loc (pdangling ~loc (Logic_const.here_label, t)))
-
-  | Is_nan_or_infinite (e, fkind) ->
-    create_special_float_predicate ~loc e fkind "\\is_finite"
-  | Is_nan (e, fkind) ->
-    let pred = create_special_float_predicate ~loc e fkind "\\is_NaN" in
-    Logic_const.pnot ~loc pred
-
-  | Function_pointer (e, args) ->
-    let loc = e.eloc in
-    let t = Cil.typeOf e in
-    let e =
-      match Cil.unrollTypeDeep t, args with
-      | TPtr (TFun (_, Some _, _, _), _), _
-      | TPtr (TFun _, _), None -> e
-      | TPtr (TFun (ret, None, var, attrs), _), Some args ->
-        let ltyps = List.map (fun arg -> "", Cil.typeOf arg, []) args in
-        let typ = TFun (ret, Some ltyps, var, attrs) in
-        Cil.mkCast e (TPtr (typ, []))
-      | t', _ ->
-        Kernel.fatal
-          "Trying to emit a Function_pointer alarm over expression %a \
-           that has unexpected type %a (unrolled as %a)"
-          Printer.pp_exp e Printer.pp_typ t Printer.pp_typ t'
-    in
-    let t = Logic_utils.expr_to_term ~cast:true e in
-    Logic_const.(pvalid_function ~loc t)
+    | Overlap(lv1, lv2) ->
+      (* (lv1 == lv2) || \separated(lv1, lv2) *)
+      let e1 = Cil.mkAddrOf ~loc lv1 in
+      let t1 = Logic_utils.expr_to_term ~cast:true e1 in
+      let e2 = Cil.mkAddrOf ~loc lv2 in
+      let t2 = Logic_utils.expr_to_term ~cast:true e2 in
+      let eq = Logic_const.prel ~loc (Req, t1, t2) in
+      let sep = Logic_const.pseparated ~loc [ t1; t2 ] in
+      Logic_const.por ~loc (eq, sep)
 
-  | Uninitialized_union llv ->
-    (* \initialized(lv_1) || ... || \initialized(lv_n) *)
-    let make_lval_predicate lv =
+    | Uninitialized lv ->
+      (* \initialized(lv) *)
       let e = Cil.mkAddrOrStartOf ~loc lv in
       let t = Logic_utils.expr_to_term ~cast:false e in
       Logic_const.pinitialized ~loc (Logic_const.here_label, t)
-    in
-    List.fold_left (fun acc lv ->
-        Logic_const.por ~loc (acc, make_lval_predicate lv)
-      ) 
-      (make_lval_predicate (List.hd llv))
-      (List.tl llv)
-
-  | Invalid_bool lv ->
-    let e = Cil.new_exp ~loc (Lval lv) in
-    let t = Logic_utils.expr_to_term ~cast:false e in
-    let zero = Logic_const.prel ~loc (Req, t, Cil.lzero ()) in
-    let one = Logic_const.prel ~loc (Req, t, Cil.lone ()) in
-    Logic_const.por ~loc (zero, one)
+
+    | Dangling lv ->
+      (* !\dangling(lv) *)
+      let e = Cil.mkAddrOrStartOf ~loc lv in
+      let t = Logic_utils.expr_to_term ~cast:false e in
+      Logic_const.(pnot ~loc (pdangling ~loc (Logic_const.here_label, t)))
+
+    | Is_nan_or_infinite (e, fkind) ->
+      create_special_float_predicate ~loc e fkind "\\is_finite"
+    | Is_nan (e, fkind) ->
+      let pred = create_special_float_predicate ~loc e fkind "\\is_NaN" in
+      Logic_const.pnot ~loc pred
+
+    | Function_pointer (e, args) ->
+      let loc = e.eloc in
+      let t = Cil.typeOf e in
+      let e =
+        match Cil.unrollTypeDeep t, args with
+        | TPtr (TFun (_, Some _, _, _), _), _
+        | TPtr (TFun _, _), None -> e
+        | TPtr (TFun (ret, None, var, attrs), _), Some args ->
+          let ltyps = List.map (fun arg -> "", Cil.typeOf arg, []) args in
+          let typ = TFun (ret, Some ltyps, var, attrs) in
+          Cil.mkCast e (TPtr (typ, []))
+        | t', _ ->
+          Kernel.fatal
+            "Trying to emit a Function_pointer alarm over expression %a \
+             that has unexpected type %a (unrolled as %a)"
+            Printer.pp_exp e Printer.pp_typ t Printer.pp_typ t'
+      in
+      let t = Logic_utils.expr_to_term ~cast:true e in
+      Logic_const.(pvalid_function ~loc t)
+
+    | Uninitialized_union llv ->
+      (* \initialized(lv_1) || ... || \initialized(lv_n) *)
+      let make_lval_predicate lv =
+        let e = Cil.mkAddrOrStartOf ~loc lv in
+        let t = Logic_utils.expr_to_term ~cast:false e in
+        Logic_const.pinitialized ~loc (Logic_const.here_label, t)
+      in
+      List.fold_left (fun acc lv ->
+          Logic_const.por ~loc (acc, make_lval_predicate lv)
+        )
+        (make_lval_predicate (List.hd llv))
+        (List.tl llv)
+
+    | Invalid_bool lv ->
+      let e = Cil.new_exp ~loc (Lval lv) in
+      let t = Logic_utils.expr_to_term ~cast:false e in
+      let zero = Logic_const.prel ~loc (Req, t, Cil.lzero ()) in
+      let one = Logic_const.prel ~loc (Req, t, Cil.lone ()) in
+      Logic_const.por ~loc (zero, one)
   in
   let p = aux alarm in
   assert (p.pred_name = []);
@@ -651,11 +665,11 @@ let find_alarm_in_emitters tbl alarm =
   try
     Usable_emitter.Hashtbl.iter
       (fun _ h ->
-        try
-          let triple = D.Hashtbl.find h alarm in
-          raise (Found triple)
-        with Not_found ->
-          ())
+         try
+           let triple = D.Hashtbl.find h alarm in
+           raise (Found triple)
+         with Not_found ->
+           ())
       tbl;
     None
   with Found x ->
@@ -666,7 +680,7 @@ let find_alarm_in_emitters tbl alarm =
     whether said code annotation is new, and the table in which the code annot
     is/should be inserted. *)
 let to_annot_aux kinstr ?(loc=Kinstr.loc kinstr) alarm =
-(*  Kernel.debug "registering alarm %a" D.pretty alarm;*)
+  (*  Kernel.debug "registering alarm %a" D.pretty alarm;*)
   let add alarm =
     let pred = create_predicate ~loc alarm in
     Logic_const.new_code_annotation (AAssert([], Assert, pred))
@@ -715,48 +729,48 @@ let register emitter ?kf kinstr ?loc ?status alarm =
 let iter f =
   State.iter
     (fun _ by_emitter ->
-      Usable_emitter.Hashtbl.iter
-        (fun e h ->
-          D.Hashtbl.iter
-            (fun alarm (annot, kf, stmt, rank) -> 
-              f (Usable_emitter.get e) kf stmt ~rank alarm annot) 
-            h)
-        by_emitter)
+       Usable_emitter.Hashtbl.iter
+         (fun e h ->
+            D.Hashtbl.iter
+              (fun alarm (annot, kf, stmt, rank) ->
+                 f (Usable_emitter.get e) kf stmt ~rank alarm annot)
+              h)
+         by_emitter)
 
 let fold f =
   State.fold
     (fun _ by_emitter acc ->
-      Usable_emitter.Hashtbl.fold
-        (fun e h acc ->
-          D.Hashtbl.fold
-            (fun alarm (annot, kf, stmt, rank) acc -> 
-              f (Usable_emitter.get e) kf stmt ~rank alarm annot acc) 
-            h
-            acc)
-        by_emitter
-        acc)
-
-let find annot = 
+       Usable_emitter.Hashtbl.fold
+         (fun e h acc ->
+            D.Hashtbl.fold
+              (fun alarm (annot, kf, stmt, rank) acc ->
+                 f (Usable_emitter.get e) kf stmt ~rank alarm annot acc)
+              h
+              acc)
+         by_emitter
+         acc)
+
+let find annot =
   try Some (Alarm_of_annot.find annot)
   with Not_found -> None
 
-let unsafe_remove ?filter ?kinstr e = 
+let unsafe_remove ?filter ?kinstr e =
   let usable_e = Emitter.get e in
-  let remove also_alarm by_emitter = 
+  let remove also_alarm by_emitter =
     try
       let tbl = Usable_emitter.Hashtbl.find by_emitter usable_e in
       let to_be_removed = D.Hashtbl.create 7 in
       let stmt_ref = ref Cil.dummyStmt in
-      let extend_del a (annot, _, stmt, _ as t) = 
+      let extend_del a (annot, _, stmt, _ as t) =
         D.Hashtbl.add to_be_removed a t;
         Alarm_of_annot.remove annot;
         stmt_ref := stmt
       in
       D.Hashtbl.iter
-        (fun alarm v -> 
-          match filter with
-          | Some f when not (f alarm) -> ()
-          | _ -> extend_del alarm v)
+        (fun alarm v ->
+           match filter with
+           | Some f when not (f alarm) -> ()
+           | _ -> extend_del alarm v)
         tbl;
       if also_alarm then begin
         let remove alarm _ = D.Hashtbl.remove tbl alarm in
@@ -765,20 +779,20 @@ let unsafe_remove ?filter ?kinstr e =
               [filtered_remove] *)
       State.apply_hooks_on_remove
         (Emitter.get e)
-        (Kstmt !stmt_ref) 
+        (Kstmt !stmt_ref)
         to_be_removed
     with Not_found ->
       ()
   in
-  let filtered_remove tbl = match filter with 
-    | None -> 
+  let filtered_remove tbl = match filter with
+    | None ->
       remove false tbl;
       Usable_emitter.Hashtbl.remove tbl usable_e
-    | Some _ -> 
+    | Some _ ->
       remove true tbl
   in
   match kinstr with
-  | None -> 
+  | None ->
     State.iter (fun _ by_emitter -> filtered_remove by_emitter)
   | Some ki ->
     try
@@ -790,18 +804,18 @@ let unsafe_remove ?filter ?kinstr e =
 let remove ?filter ?kinstr e =
   unsafe_remove ?filter ?kinstr e
 
-let () = 
+let () =
   Annotations.remove_alarm_ref :=
     (fun e stmt annot ->
-      try
-        let a = Alarm_of_annot.find annot in
-        (* [JS 2013/01/09] could be more efficient but seems we only consider
-           the alarms of one statement, it should be enough yet *)
-        let filter a' = a == a' in
-        let kinstr = Kstmt stmt in
-        remove ~filter ~kinstr (Emitter.Usable_emitter.get e)
-      with Not_found ->
-        ())
+       try
+         let a = Alarm_of_annot.find annot in
+         (* [JS 2013/01/09] could be more efficient but seems we only consider
+            the alarms of one statement, it should be enough yet *)
+         let filter a' = a == a' in
+         let kinstr = Kstmt stmt in
+         remove ~filter ~kinstr (Emitter.Usable_emitter.get e)
+       with Not_found ->
+         ())
 
 (*
 Local Variables:
diff --git a/src/kernel_services/ast_data/alarms.mli b/src/kernel_services/ast_data/alarms.mli
index c8a332f79f106f52fef155317c6004704ca2e210..daac448c4eacc9c226605795b76ec9c588113d3d 100644
--- a/src/kernel_services/ast_data/alarms.mli
+++ b/src/kernel_services/ast_data/alarms.mli
@@ -37,24 +37,24 @@ type alarm =
   | Division_by_zero of exp
   | Memory_access of lval * access_kind
   | Index_out_of_bound of
-      exp (** index *) 
-    * exp option (** None = lower bound is zero; Some up = upper bound *) 
+      exp (** index *)
+      * exp option (** None = lower bound is zero; Some up = upper bound *)
   | Invalid_shift of exp * int option (** strict upper bound, if any *)
-  | Pointer_comparison of 
-      exp option (** [None] when implicit comparison to NULL pointer *) 
-    * exp
+  | Pointer_comparison of
+      exp option (** [None] when implicit comparison to NULL pointer *)
+      * exp
   | Differing_blocks of exp * exp (** The two expressions (which evaluate to
-                     pointers) must point to the same allocated block *)
+                                      pointers) must point to the same allocated block *)
   | Overflow of
       overflow_kind
-    * exp
-    * Integer.t (** the bound *) 
-    * bound_kind
+      * exp
+      * Integer.t (** the bound *)
+      * bound_kind
   | Float_to_int of
       exp
-    * Integer.t (** the bound for the integer type. The actual alarm
-                    is [exp < bound+1] or [bound-1 < exp]. *) 
-    * bound_kind
+      * Integer.t (** the bound for the integer type. The actual alarm
+                      is [exp < bound+1] or [bound-1 < exp]. *)
+      * bound_kind
   | Not_separated of lval * lval  (** the two lvalues must be separated *)
   | Overlap of lval * lval (** overlapping read/write: the two lvalues must be
                                separated or equal *)
@@ -73,8 +73,8 @@ include Datatype.S_with_collections with type t = alarm
 
 val self: State.t
 
-val register: 
-  Emitter.t -> ?kf:kernel_function -> kinstr -> ?loc:location -> 
+val register:
+  Emitter.t -> ?kf:kernel_function -> kinstr -> ?loc:location ->
   ?status:Property_status.emitted_status -> alarm ->
   code_annotation * bool
 (** Register the given alarm on the given statement. By default, no status is
@@ -82,7 +82,7 @@ val register:
     must be the function enclosing this statement.
     @return true if the given alarm has never been emitted before on the
     same kinstr (without taking into consideration the status or
-    the emitter). 
+    the emitter).
 
     @modify Oxygen-20120901 remove labeled argument ~deps
     @modify Fluorine-20130401 add the optional arguments [kf], [loc] and
@@ -95,18 +95,18 @@ val to_annot: kinstr -> ?loc:location -> alarm -> code_annotation * bool
     The returned boolean indicates that the alarm has not been registered
     in the kernel yet. *)
 
-val iter: 
+val iter:
   (Emitter.t -> kernel_function -> stmt -> rank:int -> alarm -> code_annotation
-   -> unit) 
+   -> unit)
   -> unit
 (** Iterator over all alarms and the associated annotations at some program
     point.
     @since Fluorine-20130401 *)
 
-val fold: 
+val fold:
   (Emitter.t -> kernel_function -> stmt -> rank:int -> alarm -> code_annotation
    -> 'a
-   -> 'a) 
+   -> 'a)
   -> 'a
   -> 'a
 (** Folder over all alarms and the associated annotations at some program
@@ -121,11 +121,11 @@ val remove: ?filter:(alarm -> bool) -> ?kinstr:kinstr -> Emitter.t -> unit
 (** Remove the alarms and the associated annotations emitted by the given
     emitter. If [kinstr] is specified, remove only the ones associated with this
     kinstr. If [filter] is specified, remove only the alarms [a] such that
-    [filter a] is [true]. 
+    [filter a] is [true].
     @since Fluorine-20130401 *)
 
 val create_predicate: ?loc:location -> t -> predicate
-(** Generate the predicate corresponding to a given alarm. 
+(** Generate the predicate corresponding to a given alarm.
     @since Fluorine-20130401 *)
 
 val get_name: t -> string
diff --git a/tests/rte/oracle/downcast.0.res.oracle b/tests/rte/oracle/downcast.0.res.oracle
index e5947116b6bb904f0da499e286708d821ed2bd27..5963c8e9adf1d2b2f27d203e4b7974506da6c5e7 100644
--- a/tests/rte/oracle/downcast.0.res.oracle
+++ b/tests/rte/oracle/downcast.0.res.oracle
@@ -22,7 +22,7 @@ int main(void)
   /*@ assert rte: signed_overflow: (int)sx + (int)sy ≤ 2147483647; */
   uc = (unsigned char)((int)sx + (int)sy);
   uc = (unsigned char)x;
-  /*@ assert rte: signed_downcast: uy + uz ≤ 2147483647; */
+  /*@ assert rte: signed_downcast: (unsigned int)(uy + uz) ≤ 2147483647; */
   x = (int)(uy + uz);
   ux = uy + uz;
   s = (unsigned short)(uy + uz);
diff --git a/tests/rte/oracle/downcast.2.res.oracle b/tests/rte/oracle/downcast.2.res.oracle
index c6bce9ea5cadd82ceccd7458e06fa4e5bc74ef05..dd0102f2be08fce8cf04b6bae750fe7eb3c87cc7 100644
--- a/tests/rte/oracle/downcast.2.res.oracle
+++ b/tests/rte/oracle/downcast.2.res.oracle
@@ -26,10 +26,10 @@ int main(void)
   /*@ assert rte: unsigned_downcast: x ≤ 255; */
   /*@ assert rte: unsigned_downcast: 0 ≤ x; */
   uc = (unsigned char)x;
-  /*@ assert rte: signed_downcast: uy + uz ≤ 2147483647; */
+  /*@ assert rte: signed_downcast: (unsigned int)(uy + uz) ≤ 2147483647; */
   x = (int)(uy + uz);
   ux = uy + uz;
-  /*@ assert rte: unsigned_downcast: uy + uz ≤ 65535; */
+  /*@ assert rte: unsigned_downcast: (unsigned int)(uy + uz) ≤ 65535; */
   s = (unsigned short)(uy + uz);
   __retres = 0;
   return __retres;
diff --git a/tests/rte/oracle/minus.0.res.oracle b/tests/rte/oracle/minus.0.res.oracle
index 2944e5aa9893d3cc26abd3274eb351e87cf8e813..ea9f8124d527f4ea181094c622f5cee80f7cb128 100644
--- a/tests/rte/oracle/minus.0.res.oracle
+++ b/tests/rte/oracle/minus.0.res.oracle
@@ -28,7 +28,7 @@ int main(void)
   z = - x;
   /*@ assert rte: signed_overflow: -2147483647 ≤ (int)(-0x7fffffff) - 1; */
   z = - (-0x7fffffff - 1);
-  /*@ assert rte: signed_downcast: -ux ≤ 2147483647; */
+  /*@ assert rte: signed_downcast: (unsigned int)(-ux) ≤ 2147483647; */
   z = (int)(- ux);
   /*@ assert
       rte: signed_overflow:
diff --git a/tests/rte/oracle/minus.1.res.oracle b/tests/rte/oracle/minus.1.res.oracle
index e3e98049c15fd1f877d249d27809601ce2cd2f40..8e295b1e3cf2aa1bbc7375da339f4b0a5c76b37f 100644
--- a/tests/rte/oracle/minus.1.res.oracle
+++ b/tests/rte/oracle/minus.1.res.oracle
@@ -20,7 +20,7 @@ int main(void)
   /*@ assert rte: signed_overflow: (int)(-0x7fffffff) - 1 ≤ 2147483647; */
   /*@ assert rte: signed_overflow: -2147483647 ≤ (int)(-0x7fffffff) - 1; */
   z = - (-0x7fffffff - 1);
-  /*@ assert rte: signed_downcast: -ux ≤ 2147483647; */
+  /*@ assert rte: signed_downcast: (unsigned int)(-ux) ≤ 2147483647; */
   z = (int)(- ux);
   /*@ assert rte: signed_overflow: -2147483648 ≤ 65535 + 3; */
   /*@ assert rte: signed_overflow: 65535 + 3 ≤ 2147483647; */
@@ -43,12 +43,14 @@ int main(void)
   sz = (short)((int)((unsigned short)(65535 + 3)) + x);
   /*@ assert
       rte: signed_downcast:
-        (unsigned int)(-0x80000000) - (unsigned int)1 ≤ 2147483647;
+        (unsigned int)((unsigned int)(-0x80000000) - (unsigned int)1) ≤
+        2147483647;
   */
   z = (int)(-0x80000000 - (unsigned int)1);
   /*@ assert
       rte: signed_downcast:
-        (unsigned int)(-2147483648) - (unsigned int)1 ≤ 2147483647;
+        (unsigned int)((unsigned int)(-2147483648) - (unsigned int)1) ≤
+        2147483647;
   */
   z = (int)(-2147483648 - (unsigned int)1);
   /*@ assert rte: signed_overflow: -2147483647 ≤ 2147483647; */
diff --git a/tests/rte/oracle/mul.res.oracle b/tests/rte/oracle/mul.res.oracle
index cde812eaa97e4700ac8c8fcd530e961e13dee7a0..a30e7ac4626ad79052cf5e770bd190f0d12b184b 100644
--- a/tests/rte/oracle/mul.res.oracle
+++ b/tests/rte/oracle/mul.res.oracle
@@ -36,7 +36,8 @@ int main(void)
   z = x * 1;
   z = 1 * y;
   /*@ assert
-      rte: signed_downcast: (unsigned int)x * 0xffffffff ≤ 2147483647;
+      rte: signed_downcast:
+        (unsigned int)((unsigned int)x * 0xffffffff) ≤ 2147483647;
   */
   z = (int)((unsigned int)x * 0xffffffff);
   /*@ assert rte: signed_overflow: 0xffff * 0xffff ≤ 2147483647; */
diff --git a/tests/value/oracle/downcast.res.oracle b/tests/value/oracle/downcast.res.oracle
index 2876a38c2812c2a32ed5cb900d23463b97d23a60..7df2a56ff7b744242508b6342252dd42019d2a48 100644
--- a/tests/value/oracle/downcast.res.oracle
+++ b/tests/value/oracle/downcast.res.oracle
@@ -20,7 +20,7 @@
 [eva:alarm] tests/value/downcast.i:19: Warning: 
   signed downcast. assert (int)sx + (int)sy ≤ 127;
 [eva:alarm] tests/value/downcast.i:22: Warning: 
-  signed downcast. assert uy + uz ≤ 2147483647;
+  signed downcast. assert (unsigned int)(uy + uz) ≤ 2147483647;
 [eva] Recording results for main1
 [eva] Done for function main1
 [eva] computing for function main2_bitfield <- main.
@@ -445,7 +445,7 @@ void main1(void)
   sz = (signed char)((int)sx + (int)sy);
   uc = (unsigned char)((int)sx + (int)sy);
   uc = (unsigned char)x;
-  /*@ assert Eva: signed_downcast: uy + uz ≤ 2147483647; */
+  /*@ assert Eva: signed_downcast: (unsigned int)(uy + uz) ≤ 2147483647; */
   x = (int)(uy + uz);
   ux = uy + uz;
   s = (unsigned short)(uy + uz);
@@ -648,7 +648,7 @@ void main(void)
 [eva:alarm] tests/value/downcast.i:21: Warning: 
   unsigned downcast. assert x ≤ 255;
 [eva:alarm] tests/value/downcast.i:24: Warning: 
-  unsigned downcast. assert uy + uz ≤ 65535;
+  unsigned downcast. assert (unsigned int)(uy + uz) ≤ 65535;
 [eva] Recording results for main1
 [eva] Done for function main1
 [eva] computing for function main2_bitfield <- main.
@@ -1004,7 +1004,7 @@ void main1(void)
   uc = (unsigned char)x;
   x = (int)(uy + uz);
   ux = uy + uz;
-  /*@ assert Eva: unsigned_downcast: uy + uz ≤ 65535; */
+  /*@ assert Eva: unsigned_downcast: (unsigned int)(uy + uz) ≤ 65535; */
   s = (unsigned short)(uy + uz);
   return;
 }