diff --git a/src/kernel_services/ast_queries/cil.ml b/src/kernel_services/ast_queries/cil.ml
index 7eb80e74d5a03dbb1bf3bb1771ae9c88a7adc34e..e287cf0048d750ab14e40fc7920d047f348ebbcf 100644
--- a/src/kernel_services/ast_queries/cil.ml
+++ b/src/kernel_services/ast_queries/cil.ml
@@ -5290,8 +5290,10 @@ let constFoldVisitor (machdep: bool) = new constFoldVisitorClass machdep
 
 let rec constFoldTermNodeAtTop = function
   | TSizeOf typ as t ->
-    (try integer_lconstant (bytesSizeOf typ)
-     with SizeOfError _ -> t)
+    begin
+      try integer_lconstant (bytesSizeOf typ)
+      with SizeOfError _ -> t
+    end
   | TSizeOfStr str -> integer_lconstant (String.length str + 1)
   | TAlignOf typ as t ->
     begin
@@ -5304,14 +5306,68 @@ let rec constFoldTermNodeAtTop = function
   | TSizeOfE _ | TAlignOfE _ ->
     assert false (* sizeof/alignof of logic types are rejected
                     by typing anyway. *)
+  | TUnOp (op, ({ term_node = n1 } as t1)) ->
+    begin
+      let constFoldTermUnOp int_unop =
+        match constFoldTermNodeAtTop n1 with
+        | TConst (Integer (i, _)) -> TConst (Integer (int_unop i, None))
+        | n1 -> TUnOp (op, {t1 with term_node = n1})
+      in
+      match op with
+      | Neg -> constFoldTermUnOp Integer.neg
+      | BNot -> constFoldTermUnOp Integer.lognot
+      | LNot -> constFoldTermUnOp
+                  (fun i -> if Integer.is_zero i
+                    then Integer.one else Integer.zero)
+    end
+  | TBinOp (op, ({term_node = n1} as t1), ({term_node = n2} as t2)) ->
+    begin
+      let n1 = constFoldTermNodeAtTop n1 in
+      let n2 = constFoldTermNodeAtTop n2 in
+      let constFoldTermBinOp int_bop =
+        match n1, n2 with
+        | TConst (Integer (i1, _)), TConst (Integer (i2, _)) ->
+          TConst (Integer (int_bop i1 i2, None))
+        | n1, n2 ->
+          TBinOp (op, {t1 with term_node = n1}, {t2 with term_node = n2})
+
+      in
+      match op with
+      | PlusA -> constFoldTermBinOp Integer.add
+      | MinusA -> constFoldTermBinOp Integer.sub
+      | Mult -> constFoldTermBinOp Integer.mul
+      | Shiftlt -> constFoldTermBinOp Integer.shift_left
+      | Shiftrt -> (* right-shifting Lintegers is always arithmetic *)
+        constFoldTermBinOp Integer.shift_right
+      | BAnd -> constFoldTermBinOp Integer.logand
+      | BXor -> constFoldTermBinOp Integer.logxor
+      | BOr -> constFoldTermBinOp Integer.logor
+      | Lt | Gt | Le | Ge | Eq | Ne | LAnd | LOr ->
+        let bool_op = match op with
+          | Lt -> Integer.lt
+          | Gt -> Integer.gt
+          | Le -> Integer.le
+          | Ge -> Integer.ge
+          | Eq -> Integer.equal
+          | Ne -> (fun i1 i2 -> not (Integer.equal i1 i2))
+          | LAnd ->
+            (fun i1 i2 -> not (Integer.is_zero i1) && not (Integer.is_zero i2))
+          | LOr ->
+            (fun i1 i2 -> not (Integer.is_zero i1) || not (Integer.is_zero i2))
+          | _ -> assert false
+        in
+        constFoldTermBinOp
+          (fun i1 i2 -> if bool_op i1 i2 then Integer.one else Integer.zero)
+      | _ ->
+        TBinOp (op, {t1 with term_node = n1}, {t2 with term_node = n2})
+    end
   | t -> t
 
-let constFoldTerm machdep t =
+let constFoldTerm t =
   let visitor = object
     inherit nopCilVisitor
     method! vterm_node t =
-      if machdep then ChangeToPost (t,constFoldTermNodeAtTop)
-      else DoChildren
+      ChangeToPost (t, constFoldTermNodeAtTop)
   end
   in
   visitCilTerm visitor t
diff --git a/src/kernel_services/ast_queries/cil.mli b/src/kernel_services/ast_queries/cil.mli
index aed2f84c7513a397e2e64affce3de2af76c96ac6..ca938f4a42d4e4e7db53f65ac8393fe5f3facc5e 100644
--- a/src/kernel_services/ast_queries/cil.mli
+++ b/src/kernel_services/ast_queries/cil.mli
@@ -1079,10 +1079,9 @@ val constFoldToInt: ?machdep:bool -> exp -> Integer.t option
 val constFoldTermNodeAtTop:  term_node -> term_node
 
 (** Do constant folding on an term.
-    If the first argument is true then
-    will also compute compiler-dependent expressions such as [sizeof]
-    and [alignof]. *)
-val constFoldTerm: bool -> term -> term
+    @before Frama-C+Dev takes a boolean [machdep] to decide if we actually do
+            the fold or not. *)
+val constFoldTerm: term -> term
 
 (** Do constant folding on a {!Cil_types.offset}. If the second argument is true
     then will also compute compiler-dependent expressions such as [sizeof]. *)
diff --git a/src/plugins/aorai/aorai_utils.ml b/src/plugins/aorai/aorai_utils.ml
index 73ffd560c652f480073875c191ca29376bd6748a..d6c1c106a215b6873d4e92e6f5d29e4a63a84b43 100644
--- a/src/plugins/aorai/aorai_utils.ml
+++ b/src/plugins/aorai/aorai_utils.ml
@@ -263,8 +263,8 @@ let isCrossableAtInit tr func =
     end
   in
   let eval_rel_at_init rel t1 t2 =
-    let t1 = eval_term_at_init (Cil.constFoldTerm true t1) in
-    let t2 = eval_term_at_init (Cil.constFoldTerm true t2) in
+    let t1 = eval_term_at_init (Cil.constFoldTerm t1) in
+    let t2 = eval_term_at_init (Cil.constFoldTerm t2) in
     let comp =
       match rel with
       | Req -> ((=) 0)
diff --git a/src/plugins/eva/legacy/eval_terms.ml b/src/plugins/eva/legacy/eval_terms.ml
index 47b4dd0ae16239aa763f316bceb53747d7b6f635..b661c99d40603029704486f60a2649440de460ee 100644
--- a/src/plugins/eva/legacy/eval_terms.ml
+++ b/src/plugins/eva/legacy/eval_terms.ml
@@ -1198,7 +1198,7 @@ let rec eval_term ~alarm_mode env t =
       tcond ttrue tfalse
 
   | TSizeOf _ | TSizeOfE _ | TSizeOfStr _ | TAlignOf _ | TAlignOfE _ ->
-    let e = Cil.constFoldTerm true t in
+    let e = Cil.constFoldTerm t in
     let v = match e.term_node with
       | TConst (Integer (v, _)) -> Cvalue.V.inject_int v
       | _ -> V.top_int
diff --git a/src/plugins/wp/Cvalues.ml b/src/plugins/wp/Cvalues.ml
index 828bb2ab9a59650de96a6c913ed358ec51e5f60c..eb5550382a16e41c745b25763a32a690c7147d6b 100644
--- a/src/plugins/wp/Cvalues.ml
+++ b/src/plugins/wp/Cvalues.ml
@@ -65,7 +65,7 @@ and constant_exp e =
   | _ -> Warning.error "constant(%a)" Printer.pp_exp e
 
 and constant_term t =
-  let e = Cil.constFoldTerm true t in
+  let e = Cil.constFoldTerm t in
   match e.term_node with
   | TConst c -> logic_constant c
   | _ -> Warning.error "constant(%a)" Printer.pp_term t
diff --git a/tests/spec/const_fold_term.i b/tests/spec/const_fold_term.i
new file mode 100644
index 0000000000000000000000000000000000000000..dcabf3bd580cb2b7f73e8026240336341dd6388b
--- /dev/null
+++ b/tests/spec/const_fold_term.i
@@ -0,0 +1,22 @@
+/* run.config
+  MODULE: @PTEST_NAME@
+  STDOPT: -print
+*/
+
+void unop(int a) {
+  //@ assert -(21 + 21);
+  //@ assert ~21;
+  //@ assert -a;
+}
+
+void binop(int a) {
+  //@ assert 21 + 21 + a == 42;
+  //@ assert 84 - 42 == 42;
+  //@ assert 6 * 7 == 42;
+  //@ assert 21 << 1 == 42;
+  //@ assert 672 >> sizeof(int) == 42;
+  //@ assert (58 & 47) == 42;
+  //@ assert (34 | sizeof("frama-c")) == 42;
+  //@ assert (63 ^ 21) == 42;
+  //@ assert 168 / sizeof(a) == 42;
+}
diff --git a/tests/spec/const_fold_term.ml b/tests/spec/const_fold_term.ml
new file mode 100644
index 0000000000000000000000000000000000000000..fe52ad8ac04840bd99a60ada938da688e40078e5
--- /dev/null
+++ b/tests/spec/const_fold_term.ml
@@ -0,0 +1,51 @@
+open Cil_types
+
+let fold t =
+  match t.term_node with
+  | TSizeOf _ | TSizeOfStr _ | TSizeOfE _ |  TAlignOf _ | TAlignOfE _
+  | TUnOp _ | TBinOp _ ->
+    let t' = Cil.constFoldTerm t in
+    Format.printf "  %a folds to %a@." Cil_printer.pp_term t Cil_printer.pp_term t'
+  | _ -> ()
+
+class visitTerm prj = object(_)
+  inherit Visitor.frama_c_copy prj
+
+  method! vterm t =
+    fold t;
+    Cil.JustCopy
+
+end
+
+let test_terms () =
+  let open Cil_builder.Exp in
+  let loc = Cil_datatype.Location.unknown in
+  let e1 = lognot ((of_int 21) + (of_int 21)) in
+  let e2 = lognot ((of_int 21) - (of_int 21)) in
+  let e3 = lt zero (logand (of_int 42) (of_int 21)) in
+  let e4 = gt one (logor zero (of_int 21)) in
+  let e5 = ne zero (le zero (logand (of_int 42) (of_int 21))) in
+  let e6 = eq one (ge one (logor one zero)) in
+  let t1 = cil_term ~loc e1 in
+  let t2 = cil_term ~loc e2 in
+  let t3 = cil_term ~loc e3 in
+  let t4 = cil_term ~loc e4 in
+  let t5 = cil_term ~loc e5 in
+  let t6 = cil_term ~loc e6 in
+  Format.printf "Custom terms :@.";
+  fold t1;
+  fold t2;
+  fold t3;
+  fold t4;
+  fold t5;
+  fold t6
+
+let startup () =
+  test_terms ();
+  Format.printf "File terms :@.";
+  let prj = File.create_project_from_visitor "test_const_fold"
+      (fun prj -> new visitTerm prj)
+  in
+  Project.set_current prj
+
+let () = Boot.Main.extend startup
diff --git a/tests/spec/oracle/const_fold_term.res.oracle b/tests/spec/oracle/const_fold_term.res.oracle
new file mode 100644
index 0000000000000000000000000000000000000000..61d1b054b90db6295840d234120d6fe05db78d81
--- /dev/null
+++ b/tests/spec/oracle/const_fold_term.res.oracle
@@ -0,0 +1,21 @@
+[kernel] Parsing const_fold_term.i (no preprocessing)
+Custom terms :
+  !(21 + 21) folds to 0
+  !(21 - 21) folds to 1
+  0 < (42 ∧ 21) folds to 1
+  1 > (0 ∨ 21) folds to 0
+  0 ≢ (0 ≤ (42 ∧ 21)) folds to 1
+  1 ≡ (1 ≥ (1 ∨ 0)) folds to 1
+File terms :
+  -(21 + 21) folds to -42
+  ~21 folds to -22
+  -a folds to -a
+  (21 + 21) + a folds to 42 + a
+  84 - 42 folds to 42
+  6 * 7 folds to 42
+  21 << 1 folds to 42
+  672 >> sizeof(int) folds to 42
+  58 & 47 folds to 42
+  34 | sizeof("frama-c") folds to 42
+  63 ^ 21 folds to 42
+  168 / sizeof(a) folds to 168 / 4