Refactor Sil.binop into separate Binop module

Summary: Move Sil.binop type and operations into separate Binop module.

Reviewed By: dulmarod

Differential Revision: D3548082

fbshipit-source-id: 356bee3
master
Josh Berdine 8 years ago committed by Facebook Github Bot 7
parent 2154c2c483
commit aba67b4a2a

@ -0,0 +1,212 @@
/*
* vim: set ft=rust:
* vim: set ft=reason:
*
* Copyright (c) 2009 - 2013 Monoidics ltd.
* Copyright (c) 2013 - present Facebook, Inc.
* All rights reserved.
*
* This source code is licensed under the BSD style license found in the
* LICENSE file in the root directory of this source tree. An additional grant
* of patent rights can be found in the PATENTS file in the same directory.
*/
open! Utils;
/** The Smallfoot Intermediate Language: Binary Operators */
let module L = Logging;
let module F = Format;
/** Binary operations */
type t =
| PlusA /** arithmetic + */
| PlusPI /** pointer + integer */
| MinusA /** arithmetic - */
| MinusPI /** pointer - integer */
| MinusPP /** pointer - pointer */
| Mult /** * */
| Div /** / */
| Mod /** % */
| Shiftlt /** shift left */
| Shiftrt /** shift right */
| Lt /** < (arithmetic comparison) */
| Gt /** > (arithmetic comparison) */
| Le /** <= (arithmetic comparison) */
| Ge /** >= (arithmetic comparison) */
| Eq /** == (arithmetic comparison) */
| Ne /** != (arithmetic comparison) */
| BAnd /** bitwise and */
| BXor /** exclusive-or */
| BOr /** inclusive-or */
| LAnd /** logical and. Does not always evaluate both operands. */
| LOr /** logical or. Does not always evaluate both operands. */
| PtrFld /** field offset via pointer to field: takes the address of a
Csu.t and a Cptr_to_fld constant to form an Lfield expression (see prop.ml) */;
let compare o1 o2 =>
switch (o1, o2) {
| (PlusA, PlusA) => 0
| (PlusA, _) => (-1)
| (_, PlusA) => 1
| (PlusPI, PlusPI) => 0
| (PlusPI, _) => (-1)
| (_, PlusPI) => 1
| (MinusA, MinusA) => 0
| (MinusA, _) => (-1)
| (_, MinusA) => 1
| (MinusPI, MinusPI) => 0
| (MinusPI, _) => (-1)
| (_, MinusPI) => 1
| (MinusPP, MinusPP) => 0
| (MinusPP, _) => (-1)
| (_, MinusPP) => 1
| (Mult, Mult) => 0
| (Mult, _) => (-1)
| (_, Mult) => 1
| (Div, Div) => 0
| (Div, _) => (-1)
| (_, Div) => 1
| (Mod, Mod) => 0
| (Mod, _) => (-1)
| (_, Mod) => 1
| (Shiftlt, Shiftlt) => 0
| (Shiftlt, _) => (-1)
| (_, Shiftlt) => 1
| (Shiftrt, Shiftrt) => 0
| (Shiftrt, _) => (-1)
| (_, Shiftrt) => 1
| (Lt, Lt) => 0
| (Lt, _) => (-1)
| (_, Lt) => 1
| (Gt, Gt) => 0
| (Gt, _) => (-1)
| (_, Gt) => 1
| (Le, Le) => 0
| (Le, _) => (-1)
| (_, Le) => 1
| (Ge, Ge) => 0
| (Ge, _) => (-1)
| (_, Ge) => 1
| (Eq, Eq) => 0
| (Eq, _) => (-1)
| (_, Eq) => 1
| (Ne, Ne) => 0
| (Ne, _) => (-1)
| (_, Ne) => 1
| (BAnd, BAnd) => 0
| (BAnd, _) => (-1)
| (_, BAnd) => 1
| (BXor, BXor) => 0
| (BXor, _) => (-1)
| (_, BXor) => 1
| (BOr, BOr) => 0
| (BOr, _) => (-1)
| (_, BOr) => 1
| (LAnd, LAnd) => 0
| (LAnd, _) => (-1)
| (_, LAnd) => 1
| (LOr, LOr) => 0
| (LOr, _) => (-1)
| (_, LOr) => 1
| (PtrFld, PtrFld) => 0
};
let equal o1 o2 => compare o1 o2 == 0;
/** This function returns true if the operation is injective
wrt. each argument: op(e,-) and op(-, e) is injective for all e.
The return value false means "don't know". */
let injective =
fun
| PlusA
| PlusPI
| MinusA
| MinusPI
| MinusPP => true
| _ => false;
/** This function returns true if the operation can be inverted. */
let invertible =
fun
| PlusA
| PlusPI
| MinusA
| MinusPI => true
| _ => false;
/** This function inverts an invertible injective binary operator.
If the [binop] operation is not invertible, the function raises Assert_failure. */
let invert bop =>
switch bop {
| PlusA => MinusA
| PlusPI => MinusPI
| MinusA => PlusA
| MinusPI => PlusPI
| _ => assert false
};
/** This function returns true if 0 is the right unit of [binop].
The return value false means "don't know". */
let is_zero_runit =
fun
| PlusA
| PlusPI
| MinusA
| MinusPI
| MinusPP => true
| _ => false;
let text =
fun
| PlusA => "+"
| PlusPI => "+"
| MinusA
| MinusPP => "-"
| MinusPI => "-"
| Mult => "*"
| Div => "/"
| Mod => "%"
| Shiftlt => "<<"
| Shiftrt => ">>"
| Lt => "<"
| Gt => ">"
| Le => "<="
| Ge => ">="
| Eq => "=="
| Ne => "!="
| BAnd => "&"
| BXor => "^"
| BOr => "|"
| LAnd => "&&"
| LOr => "||"
| PtrFld => "_ptrfld_";
/** Pretty print a binary operator. */
let str pe binop =>
switch pe.pe_kind {
| PP_HTML =>
switch binop {
| Ge => " &gt;= "
| Le => " &lt;= "
| Gt => " &gt; "
| Lt => " &lt; "
| Shiftlt => " &lt;&lt; "
| Shiftrt => " &gt;&gt; "
| _ => text binop
}
| PP_LATEX =>
switch binop {
| Ge => " \\geq "
| Le => " \\leq "
| _ => text binop
}
| _ => text binop
};

@ -0,0 +1,75 @@
/*
* vim: set ft=rust:
* vim: set ft=reason:
*
* Copyright (c) 2009 - 2013 Monoidics ltd.
* Copyright (c) 2013 - present Facebook, Inc.
* All rights reserved.
*
* This source code is licensed under the BSD style license found in the
* LICENSE file in the root directory of this source tree. An additional grant
* of patent rights can be found in the PATENTS file in the same directory.
*/
open! Utils;
/** The Smallfoot Intermediate Language: Binary Operators */
let module L = Logging;
let module F = Format;
/** Binary operations */
type t =
| PlusA /** arithmetic + */
| PlusPI /** pointer + integer */
| MinusA /** arithmetic - */
| MinusPI /** pointer - integer */
| MinusPP /** pointer - pointer */
| Mult /** * */
| Div /** / */
| Mod /** % */
| Shiftlt /** shift left */
| Shiftrt /** shift right */
| Lt /** < (arithmetic comparison) */
| Gt /** > (arithmetic comparison) */
| Le /** <= (arithmetic comparison) */
| Ge /** >= (arithmetic comparison) */
| Eq /** == (arithmetic comparison) */
| Ne /** != (arithmetic comparison) */
| BAnd /** bitwise and */
| BXor /** exclusive-or */
| BOr /** inclusive-or */
| LAnd /** logical and. Does not always evaluate both operands. */
| LOr /** logical or. Does not always evaluate both operands. */
| PtrFld /** field offset via pointer to field: takes the address of a
Csu.t and a Cptr_to_fld constant to form an Lfield expression (see prop.ml) */;
let equal: t => t => bool;
let compare: t => t => int;
/** This function returns true if the operation is injective
wrt. each argument: op(e,-) and op(-, e) is injective for all e.
The return value false means "don't know". */
let injective: t => bool;
/** This function returns true if the operation can be inverted. */
let invertible: t => bool;
/** This function inverts an invertible injective binary operator.
If the [binop] operation is not invertible, the function raises Assert_failure. */
let invert: t => t;
/** This function returns true if 0 is the right unit of [binop].
The return value false means "don't know". */
let is_zero_runit: t => bool;
/** String representation of a binary operator. */
let str: printenv => t => string;

@ -36,33 +36,6 @@ let get_sentinel_func_attribute_value attr_list =>
| [] => None
};
/** Binary operations */
type binop =
| PlusA /** arithmetic + */
| PlusPI /** pointer + integer */
| MinusA /** arithmetic - */
| MinusPI /** pointer - integer */
| MinusPP /** pointer - pointer */
| Mult /** * */
| Div /** / */
| Mod /** % */
| Shiftlt /** shift left */
| Shiftrt /** shift right */
| Lt /** < (arithmetic comparison) */
| Gt /** > (arithmetic comparison) */
| Le /** <= (arithmetic comparison) */
| Ge /** > (arithmetic comparison) */
| Eq /** == (arithmetic comparison) */
| Ne /** != (arithmetic comparison) */
| BAnd /** bitwise and */
| BXor /** exclusive-or */
| BOr /** inclusive-or */
| LAnd /** logical and. Does not always evaluate both operands. */
| LOr /** logical or. Does not always evaluate both operands. */
| PtrFld /** field offset via pointer to field: takes the address of a
Csu.t and a Cptr_to_fld constant to form an Lfield expression (see prop.ml) */;
type mem_kind =
| Mmalloc /** memory allocated with malloc */
| Mnew /** memory allocated with new */
@ -411,7 +384,7 @@ type taint_info = {taint_source: Procname.t, taint_kind: taint_kind};
/** expression representing the result of decompilation */
type dexp =
| Darray of dexp dexp
| Dbinop of binop dexp dexp
| Dbinop of Binop.t dexp dexp
| Dconst of Const.t
| Dsizeof of Typ.t (option dexp) Subtype.t
| Dderef of dexp
@ -472,7 +445,7 @@ and exp =
/** Unary operator with type of the result if known */
| UnOp of Unop.t exp (option Typ.t)
/** Binary operator */
| BinOp of binop exp exp
| BinOp of Binop.t exp exp
/** Exception */
| Exn of exp
/** Anonymous function */
@ -707,127 +680,12 @@ let exp_is_this =
| Lvar pvar => Pvar.is_this pvar
| _ => false;
let binop_compare o1 o2 =>
switch (o1, o2) {
| (PlusA, PlusA) => 0
| (PlusA, _) => (-1)
| (_, PlusA) => 1
| (PlusPI, PlusPI) => 0
| (PlusPI, _) => (-1)
| (_, PlusPI) => 1
| (MinusA, MinusA) => 0
| (MinusA, _) => (-1)
| (_, MinusA) => 1
| (MinusPI, MinusPI) => 0
| (MinusPI, _) => (-1)
| (_, MinusPI) => 1
| (MinusPP, MinusPP) => 0
| (MinusPP, _) => (-1)
| (_, MinusPP) => 1
| (Mult, Mult) => 0
| (Mult, _) => (-1)
| (_, Mult) => 1
| (Div, Div) => 0
| (Div, _) => (-1)
| (_, Div) => 1
| (Mod, Mod) => 0
| (Mod, _) => (-1)
| (_, Mod) => 1
| (Shiftlt, Shiftlt) => 0
| (Shiftlt, _) => (-1)
| (_, Shiftlt) => 1
| (Shiftrt, Shiftrt) => 0
| (Shiftrt, _) => (-1)
| (_, Shiftrt) => 1
| (Lt, Lt) => 0
| (Lt, _) => (-1)
| (_, Lt) => 1
| (Gt, Gt) => 0
| (Gt, _) => (-1)
| (_, Gt) => 1
| (Le, Le) => 0
| (Le, _) => (-1)
| (_, Le) => 1
| (Ge, Ge) => 0
| (Ge, _) => (-1)
| (_, Ge) => 1
| (Eq, Eq) => 0
| (Eq, _) => (-1)
| (_, Eq) => 1
| (Ne, Ne) => 0
| (Ne, _) => (-1)
| (_, Ne) => 1
| (BAnd, BAnd) => 0
| (BAnd, _) => (-1)
| (_, BAnd) => 1
| (BXor, BXor) => 0
| (BXor, _) => (-1)
| (_, BXor) => 1
| (BOr, BOr) => 0
| (BOr, _) => (-1)
| (_, BOr) => 1
| (LAnd, LAnd) => 0
| (LAnd, _) => (-1)
| (_, LAnd) => 1
| (LOr, LOr) => 0
| (LOr, _) => (-1)
| (_, LOr) => 1
| (PtrFld, PtrFld) => 0
};
let binop_equal o1 o2 => binop_compare o1 o2 == 0;
/** This function returns true if the operation is injective
wrt. each argument: op(e,-) and op(-, e) is injective for all e.
The return value false means "don't know". */
let binop_injective =
fun
| PlusA
| PlusPI
| MinusA
| MinusPI
| MinusPP => true
| _ => false;
/** This function returns true if the operation can be inverted. */
let binop_invertible =
fun
| PlusA
| PlusPI
| MinusA
| MinusPI => true
| _ => false;
/** This function inverts an injective binary operator
with respect to the first argument. It returns an expression [e'] such that
BinOp([binop], [e'], [exp1]) = [exp2]. If the [binop] operation is not invertible,
the function raises an exception by calling "assert false". */
let binop_invert bop e1 e2 => {
let inverted_bop =
switch bop {
| PlusA => MinusA
| PlusPI => MinusPI
| MinusA => PlusA
| MinusPI => PlusPI
| _ => assert false
};
BinOp inverted_bop e2 e1
};
/** This function returns true if 0 is the right unit of [binop].
The return value false means "don't know". */
let binop_is_zero_runit =
fun
| PlusA
| PlusPI
| MinusA
| MinusPI
| MinusPP => true
| _ => false;
let binop_invert bop e1 e2 => BinOp (Binop.invert bop) e2 e1;
let path_pos_compare (pn1, nid1) (pn2, nid2) => {
let n = Procname.compare pn1 pn2;
@ -1056,7 +914,7 @@ let rec exp_compare (e1: exp) (e2: exp) :int =>
| (UnOp _, _) => (-1)
| (_, UnOp _) => 1
| (BinOp o1 e1 f1, BinOp o2 e2 f2) =>
let n = binop_compare o1 o2;
let n = Binop.compare o1 o2;
if (n != 0) {
n
} else {
@ -1463,54 +1321,6 @@ let pp_seq_diff pp pe0 f =>
doit
};
let text_binop =
fun
| PlusA => "+"
| PlusPI => "+"
| MinusA
| MinusPP => "-"
| MinusPI => "-"
| Mult => "*"
| Div => "/"
| Mod => "%"
| Shiftlt => "<<"
| Shiftrt => ">>"
| Lt => "<"
| Gt => ">"
| Le => "<="
| Ge => ">="
| Eq => "=="
| Ne => "!="
| BAnd => "&"
| BXor => "^"
| BOr => "|"
| LAnd => "&&"
| LOr => "||"
| PtrFld => "_ptrfld_";
/** Pretty print a binary operator. */
let str_binop pe binop =>
switch pe.pe_kind {
| PP_HTML =>
switch binop {
| Ge => " &gt;= "
| Le => " &lt;= "
| Gt => " &gt; "
| Lt => " &lt; "
| Shiftlt => " &lt;&lt; "
| Shiftrt => " &gt;&gt; "
| _ => text_binop binop
}
| PP_LATEX =>
switch binop {
| Ge => " \\geq "
| Le => " \\leq "
| _ => text_binop binop
}
| _ => text_binop binop
};
let java () => !Config.curr_language == Config.Java;
let eradicate_java () => Config.eradicate && java ();
@ -1520,7 +1330,7 @@ let eradicate_java () => Config.eradicate && java ();
let rec dexp_to_string =
fun
| Darray de1 de2 => dexp_to_string de1 ^ "[" ^ dexp_to_string de2 ^ "]"
| Dbinop op de1 de2 => "(" ^ dexp_to_string de1 ^ str_binop pe_text op ^ dexp_to_string de2 ^ ")"
| Dbinop op de1 de2 => "(" ^ dexp_to_string de1 ^ Binop.str pe_text op ^ dexp_to_string de2 ^ ")"
| Dconst (Cfun pn) => Procname.to_simplified_string pn
| Dconst c => Const.to_string c
| Dderef de => "*" ^ dexp_to_string de
@ -1660,11 +1470,11 @@ let attribute_to_string pe =>
""
};
name ^
str_binop pe Lt ^
Binop.str pe Lt ^
Procname.to_string ra.ra_pname ^
":" ^
string_of_int ra.ra_loc.Location.line ^
str_binop pe Gt ^
Binop.str pe Gt ^
str_vpath
}
| Aautorelease => "AUTORELEASE"
@ -1675,13 +1485,13 @@ let attribute_to_string pe =>
| DAaddr_stack_var => "ADDR_STACK"
| DAminusone => "MINUS1"
};
"DANGL" ^ str_binop pe Lt ^ dks ^ str_binop pe Gt
"DANGL" ^ Binop.str pe Lt ^ dks ^ Binop.str pe Gt
}
| Aundef pn _ loc _ =>
"UND" ^
str_binop pe Lt ^
Binop.str pe Lt ^
Procname.to_string pn ^
str_binop pe Gt ^
Binop.str pe Gt ^
":" ^
string_of_int loc.Location.line
| Ataint {taint_source} => "TAINTED[" ^ Procname.to_string taint_source ^ "]"
@ -1692,7 +1502,7 @@ let attribute_to_string pe =>
| Aobjc_null v fs =>
"OBJC_NULL[" ^
String.concat "." [Pvar.to_string v, ...IList.map Ident.fieldname_to_string fs] ^ "]"
| Aretval pn _ => "RET" ^ str_binop pe Lt ^ Procname.to_string pn ^ str_binop pe Gt
| Aretval pn _ => "RET" ^ Binop.str pe Lt ^ Procname.to_string pn ^ Binop.str pe Gt
| Aobserver => "OBSERVER"
| Aunsubscribed_observer => "UNSUBSCRIBED_OBSERVER";
@ -1713,16 +1523,16 @@ let rec _pp_exp pe0 pp_t f e0 => {
} else {
let pp_exp = _pp_exp pe pp_t;
let print_binop_stm_output e1 op e2 =>
switch op {
switch (op: Binop.t) {
| Eq
| Ne
| PlusA
| Mult => F.fprintf f "(%a %s %a)" pp_exp e2 (str_binop pe op) pp_exp e1
| Lt => F.fprintf f "(%a %s %a)" pp_exp e2 (str_binop pe Gt) pp_exp e1
| Gt => F.fprintf f "(%a %s %a)" pp_exp e2 (str_binop pe Lt) pp_exp e1
| Le => F.fprintf f "(%a %s %a)" pp_exp e2 (str_binop pe Ge) pp_exp e1
| Ge => F.fprintf f "(%a %s %a)" pp_exp e2 (str_binop pe Le) pp_exp e1
| _ => F.fprintf f "(%a %s %a)" pp_exp e1 (str_binop pe op) pp_exp e2
| Mult => F.fprintf f "(%a %s %a)" pp_exp e2 (Binop.str pe op) pp_exp e1
| Lt => F.fprintf f "(%a %s %a)" pp_exp e2 (Binop.str pe Gt) pp_exp e1
| Gt => F.fprintf f "(%a %s %a)" pp_exp e2 (Binop.str pe Lt) pp_exp e1
| Le => F.fprintf f "(%a %s %a)" pp_exp e2 (Binop.str pe Ge) pp_exp e1
| Ge => F.fprintf f "(%a %s %a)" pp_exp e2 (Binop.str pe Le) pp_exp e1
| _ => F.fprintf f "(%a %s %a)" pp_exp e1 (Binop.str pe op) pp_exp e2
};
switch e {
| Var id => (Ident.pp pe) f id
@ -1730,7 +1540,7 @@ let rec _pp_exp pe0 pp_t f e0 => {
| Cast typ e => F.fprintf f "(%a)%a" pp_t typ pp_exp e
| UnOp op e _ => F.fprintf f "%s%a" (Unop.str op) pp_exp e
| BinOp op (Const c) e2 when Config.smt_output => print_binop_stm_output (Const c) op e2
| BinOp op e1 e2 => F.fprintf f "(%a %s %a)" pp_exp e1 (str_binop pe op) pp_exp e2
| BinOp op e1 e2 => F.fprintf f "(%a %s %a)" pp_exp e1 (Binop.str pe op) pp_exp e2
| Exn e => F.fprintf f "EXN %a" pp_exp e
| Closure {name, captured_vars} =>
let id_exps = IList.map (fun (id_exp, _, _) => id_exp) captured_vars;
@ -2282,7 +2092,7 @@ let pp_inst pe f inst => {
if (pe.pe_kind === PP_HTML) {
F.fprintf f " %a%s%a" Io_infer.Html.pp_start_color Orange str Io_infer.Html.pp_end_color ()
} else {
F.fprintf f "%s%s%s" (str_binop pe Lt) str (str_binop pe Gt)
F.fprintf f "%s%s%s" (Binop.str pe Lt) str (Binop.str pe Gt)
}
};
@ -3650,7 +3460,7 @@ let rec exp_compare_structural e1 e2 exp_map => {
)
}
| (BinOp o1 e1 f1, BinOp o2 e2 f2) =>
let n = binop_compare o1 o2;
let n = Binop.compare o1 o2;
if (n != 0) {
(n, exp_map)
} else {

@ -25,33 +25,6 @@ type func_attribute = | FA_sentinel of int int;
/** Visibility modifiers. */
type access = | Default | Public | Private | Protected;
/** Binary operations */
type binop =
| PlusA /** arithmetic + */
| PlusPI /** pointer + integer */
| MinusA /** arithmetic - */
| MinusPI /** pointer - integer */
| MinusPP /** pointer - pointer */
| Mult /** * */
| Div /** / */
| Mod /** % */
| Shiftlt /** shift left */
| Shiftrt /** shift right */
| Lt /** < (arithmetic comparison) */
| Gt /** > (arithmetic comparison) */
| Le /** <= (arithmetic comparison) */
| Ge /** >= (arithmetic comparison) */
| Eq /** == (arithmetic comparison) */
| Ne /** != (arithmetic comparison) */
| BAnd /** bitwise and */
| BXor /** exclusive-or */
| BOr /** inclusive-or */
| LAnd /** logical and. Does not always evaluate both operands. */
| LOr /** logical or. Does not always evaluate both operands. */
| PtrFld /** field offset via pointer to field: takes the address of a
Csu.t and a Cptr_to_fld constant to form an Lfield expression (see prop.ml) */;
type mem_kind =
| Mmalloc /** memory allocated with malloc */
| Mnew /** memory allocated with new */
@ -138,7 +111,7 @@ type taint_info = {taint_source: Procname.t, taint_kind: taint_kind};
/** expression representing the result of decompilation */
type dexp =
| Darray of dexp dexp
| Dbinop of binop dexp dexp
| Dbinop of Binop.t dexp dexp
| Dconst of Const.t
| Dsizeof of Typ.t (option dexp) Subtype.t
| Dderef of dexp
@ -199,7 +172,7 @@ and exp =
/** Unary operator with type of the result if known */
| UnOp of Unop.t exp (option Typ.t)
/** Binary operator */
| BinOp of binop exp exp
| BinOp of Binop.t exp exp
/** Exception */
| Exn of exp
/** Anonymous function */
@ -482,29 +455,12 @@ let block_pvar: Pvar.t;
/** Check if a pvar is a local pointing to a block in objc */
let is_block_pvar: Pvar.t => bool;
let binop_equal: binop => binop => bool;
/** This function returns true if the operation is injective
wrt. each argument: op(e,-) and op(-, e) is injective for all e.
The return value false means "don't know". */
let binop_injective: binop => bool;
/** This function returns true if the operation can be inverted. */
let binop_invertible: binop => bool;
/** This function inverts an injective binary operator
with respect to the first argument. It returns an expression [e'] such that
BinOp([binop], [e'], [exp1]) = [exp2]. If the [binop] operation is not invertible,
the function raises an exception by calling "assert false". */
let binop_invert: binop => exp => exp => exp;
/** This function returns true if 0 is the right unit of [binop].
The return value false means "don't know". */
let binop_is_zero_runit: binop => bool;
let binop_invert: Binop.t => exp => exp => exp;
/** return true if [dexp] contains a temporary pvar */
@ -612,10 +568,6 @@ let color_pre_wrapper: printenv => F.formatter => 'a => (printenv, bool);
let color_post_wrapper: bool => printenv => F.formatter => unit;
/** String representation of a binary operator. */
let str_binop: printenv => binop => string;
/** name of the allocation function for the given memory kind */
let mem_alloc_pname: mem_kind => Procname.t;

@ -778,10 +778,10 @@ let abstract_pure_part p ~(from_abstract_footprint: bool) =
match a with
| Sil.Aneq (Sil.Var _, _) -> a:: pi
(* we only use Lt and Le because Gt and Ge are inserted in terms of Lt and Le. *)
| Sil.Aeq (Sil.Const (Const.Cint i), Sil.BinOp (Sil.Lt, _, _))
| Sil.Aeq (Sil.BinOp (Sil.Lt, _, _), Sil.Const (Const.Cint i))
| Sil.Aeq (Sil.Const (Const.Cint i), Sil.BinOp (Sil.Le, _, _))
| Sil.Aeq (Sil.BinOp (Sil.Le, _, _), Sil.Const (Const.Cint i)) when IntLit.isone i ->
| Sil.Aeq (Sil.Const (Const.Cint i), Sil.BinOp (Binop.Lt, _, _))
| Sil.Aeq (Sil.BinOp (Binop.Lt, _, _), Sil.Const (Const.Cint i))
| Sil.Aeq (Sil.Const (Const.Cint i), Sil.BinOp (Binop.Le, _, _))
| Sil.Aeq (Sil.BinOp (Binop.Le, _, _), Sil.Const (Const.Cint i)) when IntLit.isone i ->
a :: pi
| Sil.Aeq (Sil.Var name, e) when not (Ident.is_primed name) ->
(match e with

@ -350,7 +350,7 @@ let generic_strexp_abstract
(** Return [true] if there's a pointer to the index *)
let index_is_pointed_to (p: Prop.normal Prop.t) (path: StrexpMatch.path) (index: Sil.exp) : bool =
let indices =
let index_plus_one = Sil.BinOp(Sil.PlusA, index, Sil.exp_one) in
let index_plus_one = Sil.BinOp(Binop.PlusA, index, Sil.exp_one) in
[index; index_plus_one] in
let add_index_to_paths =
let elist_path = StrexpMatch.path_to_exps path in
@ -387,8 +387,8 @@ let blur_array_index
let sigma' = StrexpMatch.replace_index false matched index fresh_index in
Prop.replace_sigma sigma' p2 in
let p4 =
let index_next = Sil.BinOp(Sil.PlusA, index, Sil.exp_one) in
let fresh_index_next = Sil.BinOp (Sil.PlusA, fresh_index, Sil.exp_one) in
let index_next = Sil.BinOp(Binop.PlusA, index, Sil.exp_one) in
let fresh_index_next = Sil.BinOp (Binop.PlusA, fresh_index, Sil.exp_one) in
let map = [(index, fresh_index); (index_next, fresh_index_next)] in
prop_replace_path_index p3 path map in
Prop.normalize p4

@ -184,9 +184,9 @@ end = struct
let rec pi_iter do_le do_lt do_neq pi =
let do_atom a = match a with
| Sil.Aeq (Sil.BinOp (Sil.Le, e1, e2), Sil.Const (Const.Cint i)) when IntLit.isone i ->
| Sil.Aeq (Sil.BinOp (Binop.Le, e1, e2), Sil.Const (Const.Cint i)) when IntLit.isone i ->
do_le e1 e2
| Sil.Aeq (Sil.BinOp (Sil.Lt, e1, e2), Sil.Const (Const.Cint i)) when IntLit.isone i ->
| Sil.Aeq (Sil.BinOp (Binop.Lt, e1, e2), Sil.Const (Const.Cint i)) when IntLit.isone i ->
do_lt e1 e2
| Sil.Aeq _ -> ()
| Sil.Aneq (e1, e2) ->
@ -220,12 +220,12 @@ end = struct
| Sil.Var id, Sil.Const (Const.Cint n) ->
let rng = IdMap.find id ev in
add_top rng id n
| Sil.BinOp (Sil.MinusA, Sil.Var id1, Sil.Var id2), Sil.Const (Const.Cint n) ->
| Sil.BinOp (Binop.MinusA, Sil.Var id1, Sil.Var id2), Sil.Const (Const.Cint n) ->
let rng1 = IdMap.find id1 ev in
let rng2 = IdMap.find id2 ev in
update_top rng1 id1 (rng2.top +++ (Some n));
update_bottom rng2 id2 (rng1.bottom --- (Some n))
| Sil.BinOp (Sil.PlusA, Sil.Var id1, Sil.Var id2), Sil.Const (Const.Cint n) ->
| Sil.BinOp (Binop.PlusA, Sil.Var id1, Sil.Var id2), Sil.Const (Const.Cint n) ->
let rng1 = IdMap.find id1 ev in
let rng2 = IdMap.find id2 ev in
update_top rng1 id1 (Some n --- rng2.bottom);
@ -235,7 +235,7 @@ end = struct
| Sil.Const (Const.Cint n), Sil.Var id ->
let rng = IdMap.find id ev in
add_bottom rng id (n ++ IntLit.one)
| Sil.Const (Const.Cint n), Sil.BinOp (Sil.PlusA, Sil.Var id1, Sil.Var id2) ->
| Sil.Const (Const.Cint n), Sil.BinOp (Binop.PlusA, Sil.Var id1, Sil.Var id2) ->
let rng1 = IdMap.find id1 ev in
let rng2 = IdMap.find id2 ev in
update_bottom rng1 id1 (Some (n ++ IntLit.one) --- rng2.top);
@ -254,7 +254,7 @@ end = struct
do_neq (Sil.exp_int n1) e2
| None, Some n2 ->
do_neq e1 (Sil.exp_int n2))
| Sil.Var id1, Sil.BinOp(Sil.PlusA, Sil.Var id2, Sil.Const (Const.Cint n)) ->
| Sil.Var id1, Sil.BinOp(Binop.PlusA, Sil.Var id2, Sil.Const (Const.Cint n)) ->
(match solved ev id1, solved ev id2 with
| None, None -> ()
| Some _, Some _ -> ()
@ -298,10 +298,10 @@ let create_idmap sigma : idmap =
| Sil.Const _, _ -> ()
| Sil.Var id, _ ->
extend_idmap id { typ = typ; alloc = false } idmap
| Sil.BinOp (Sil.PlusA, e1, e2), _ ->
| Sil.BinOp (Binop.PlusA, e1, e2), _ ->
do_exp e1 typ;
do_exp e2 typ
| Sil.BinOp (Sil.PlusPI, e1, e2), _ ->
| Sil.BinOp (Binop.PlusPI, e1, e2), _ ->
do_exp e1 typ;
do_exp e2 (Typ.Tint Typ.IULong)
| Sil.Lfield (e1, _, _), _ ->

@ -462,8 +462,8 @@ end = struct
e
let get_induced_atom acc strict_lower upper e =
let ineq_lower = Prop.mk_inequality (Sil.BinOp(Sil.Lt, strict_lower, e)) in
let ineq_upper = Prop.mk_inequality (Sil.BinOp(Sil.Le, e, upper)) in
let ineq_lower = Prop.mk_inequality (Sil.BinOp(Binop.Lt, strict_lower, e)) in
let ineq_upper = Prop.mk_inequality (Sil.BinOp(Binop.Le, e, upper)) in
ineq_lower:: ineq_upper:: acc
let minus2_to_2 = IList.map IntLit.of_int [-2; -1; 0; 1; 2]
@ -476,7 +476,7 @@ end = struct
| Sil.Const (Const.Cint n1), Sil.Const (Const.Cint n1') -> IntLit.eq (n1 ++ n) n1'
| _ -> false in
let add_and_gen_eq e e' n =
let e_plus_n = Sil.BinOp(Sil.PlusA, e, Sil.exp_int n) in
let e_plus_n = Sil.BinOp(Binop.PlusA, e, Sil.exp_int n) in
Prop.mk_eq e_plus_n e' in
let rec f_eqs_entry ((e1, e2, e) as entry) eqs_acc t_seen = function
| [] -> eqs_acc, t_seen
@ -572,7 +572,7 @@ end = struct
match e with
| Sil.Const _ -> []
| Sil.Lvar _ | Sil.Var _
| Sil.BinOp (Sil.PlusA, Sil.Var _, _) ->
| Sil.BinOp (Binop.PlusA, Sil.Var _, _) ->
let is_same_e (e1, e2, _) = Sil.exp_equal e (select side e1 e2) in
let assoc = IList.filter is_same_e !tbl in
IList.map (fun (e1, e2, _) -> select side_op e1 e2) assoc
@ -591,15 +591,15 @@ end = struct
let lookup_side_induced' side e =
let res = ref [] in
let f v = match v, side with
| (Sil.BinOp (Sil.PlusA, e1', Sil.Const (Const.Cint i)), e2, e'), Lhs
| (Sil.BinOp (Binop.PlusA, e1', Sil.Const (Const.Cint i)), e2, e'), Lhs
when Sil.exp_equal e e1' ->
let c' = Sil.exp_int (IntLit.neg i) in
let v' = (e1', Sil.BinOp(Sil.PlusA, e2, c'), Sil.BinOp (Sil.PlusA, e', c')) in
let v' = (e1', Sil.BinOp(Binop.PlusA, e2, c'), Sil.BinOp (Binop.PlusA, e', c')) in
res := v'::!res
| (e1, Sil.BinOp (Sil.PlusA, e2', Sil.Const (Const.Cint i)), e'), Rhs
| (e1, Sil.BinOp (Binop.PlusA, e2', Sil.Const (Const.Cint i)), e'), Rhs
when Sil.exp_equal e e2' ->
let c' = Sil.exp_int (IntLit.neg i) in
let v' = (Sil.BinOp(Sil.PlusA, e1, c'), e2', Sil.BinOp (Sil.PlusA, e', c')) in
let v' = (Sil.BinOp(Binop.PlusA, e1, c'), e2', Sil.BinOp (Binop.PlusA, e', c')) in
res := v'::!res
| _ -> () in
begin
@ -722,16 +722,16 @@ end = struct
when (exp_contains_only_normal_ids e' && not (Ident.is_normal id)) ->
build_other_atoms (fun e0 -> Prop.mk_eq e0 e') side e
| Sil.Aeq(Sil.BinOp(Sil.Le, e, e'), Sil.Const (Const.Cint i))
| Sil.Aeq(Sil.Const (Const.Cint i), Sil.BinOp(Sil.Le, e, e'))
| Sil.Aeq(Sil.BinOp(Binop.Le, e, e'), Sil.Const (Const.Cint i))
| Sil.Aeq(Sil.Const (Const.Cint i), Sil.BinOp(Binop.Le, e, e'))
when IntLit.isone i && (exp_contains_only_normal_ids e') ->
let construct e0 = Prop.mk_inequality (Sil.BinOp(Sil.Le, e0, e')) in
let construct e0 = Prop.mk_inequality (Sil.BinOp(Binop.Le, e0, e')) in
build_other_atoms construct side e
| Sil.Aeq(Sil.BinOp(Sil.Lt, e', e), Sil.Const (Const.Cint i))
| Sil.Aeq(Sil.Const (Const.Cint i), Sil.BinOp(Sil.Lt, e', e))
| Sil.Aeq(Sil.BinOp(Binop.Lt, e', e), Sil.Const (Const.Cint i))
| Sil.Aeq(Sil.Const (Const.Cint i), Sil.BinOp(Binop.Lt, e', e))
when IntLit.isone i && (exp_contains_only_normal_ids e') ->
let construct e0 = Prop.mk_inequality (Sil.BinOp(Sil.Lt, e', e0)) in
let construct e0 = Prop.mk_inequality (Sil.BinOp(Binop.Lt, e', e0)) in
build_other_atoms construct side e
| _ -> None
@ -917,20 +917,20 @@ let rec exp_partial_join (e1: Sil.exp) (e2: Sil.exp) : Sil.exp =
if Ident.is_normal id then (L.d_strln "failure reason 21"; raise IList.Fail)
else Rename.extend e1 e2 Rename.ExtFresh
| Sil.BinOp(Sil.PlusA, Sil.Var id1, Sil.Const _), Sil.Var id2
| Sil.Var id1, Sil.BinOp(Sil.PlusA, Sil.Var id2, Sil.Const _)
| Sil.BinOp(Binop.PlusA, Sil.Var id1, Sil.Const _), Sil.Var id2
| Sil.Var id1, Sil.BinOp(Binop.PlusA, Sil.Var id2, Sil.Const _)
when ident_same_kind_primed_footprint id1 id2 ->
Rename.extend e1 e2 Rename.ExtFresh
| Sil.BinOp(Sil.PlusA, Sil.Var id1, Sil.Const (Const.Cint c1)), Sil.Const (Const.Cint c2)
| Sil.BinOp(Binop.PlusA, Sil.Var id1, Sil.Const (Const.Cint c1)), Sil.Const (Const.Cint c2)
when can_rename id1 ->
let c2' = c2 -- c1 in
let e_res = Rename.extend (Sil.Var id1) (Sil.exp_int c2') Rename.ExtFresh in
Sil.BinOp(Sil.PlusA, e_res, Sil.exp_int c1)
| Sil.Const (Const.Cint c1), Sil.BinOp(Sil.PlusA, Sil.Var id2, Sil.Const (Const.Cint c2))
Sil.BinOp(Binop.PlusA, e_res, Sil.exp_int c1)
| Sil.Const (Const.Cint c1), Sil.BinOp(Binop.PlusA, Sil.Var id2, Sil.Const (Const.Cint c2))
when can_rename id2 ->
let c1' = c1 -- c2 in
let e_res = Rename.extend (Sil.exp_int c1') (Sil.Var id2) Rename.ExtFresh in
Sil.BinOp(Sil.PlusA, e_res, Sil.exp_int c2)
Sil.BinOp(Binop.PlusA, e_res, Sil.exp_int c2)
| Sil.Cast(t1, e1), Sil.Cast(t2, e2) ->
if not (Typ.equal t1 t2) then (L.d_strln "failure reason 22"; raise IList.Fail)
else
@ -939,14 +939,14 @@ let rec exp_partial_join (e1: Sil.exp) (e2: Sil.exp) : Sil.exp =
| Sil.UnOp(unop1, e1, topt1), Sil.UnOp(unop2, e2, _) ->
if not (Unop.equal unop1 unop2) then (L.d_strln "failure reason 23"; raise IList.Fail)
else Sil.UnOp (unop1, exp_partial_join e1 e2, topt1) (* should be topt1 = topt2 *)
| Sil.BinOp(Sil.PlusPI, e1, e1'), Sil.BinOp(Sil.PlusPI, e2, e2') ->
| Sil.BinOp(Binop.PlusPI, e1, e1'), Sil.BinOp(Binop.PlusPI, e2, e2') ->
let e1'' = exp_partial_join e1 e2 in
let e2'' = match e1', e2' with
| Sil.Const _, Sil.Const _ -> exp_partial_join e1' e2'
| _ -> FreshVarExp.get_fresh_exp e1 e2 in
Sil.BinOp(Sil.PlusPI, e1'', e2'')
Sil.BinOp(Binop.PlusPI, e1'', e2'')
| Sil.BinOp(binop1, e1, e1'), Sil.BinOp(binop2, e2, e2') ->
if not (Sil.binop_equal binop1 binop2) then (L.d_strln "failure reason 24"; raise IList.Fail)
if not (Binop.equal binop1 binop2) then (L.d_strln "failure reason 24"; raise IList.Fail)
else
let e1'' = exp_partial_join e1 e2 in
let e2'' = exp_partial_join e1' e2' in
@ -969,11 +969,11 @@ let rec exp_partial_join (e1: Sil.exp) (e2: Sil.exp) : Sil.exp =
raise IList.Fail
and length_partial_join len1 len2 = match len1, len2 with
| Sil.BinOp(Sil.PlusA, e1, Sil.Const c1), Sil.BinOp(Sil.PlusA, e2, Sil.Const c2) ->
| Sil.BinOp(Binop.PlusA, e1, Sil.Const c1), Sil.BinOp(Binop.PlusA, e2, Sil.Const c2) ->
let e' = exp_partial_join e1 e2 in
let c' = exp_partial_join (Sil.Const c1) (Sil.Const c2) in
Sil.BinOp (Sil.PlusA, e', c')
| Sil.BinOp(Sil.PlusA, _, _), Sil.BinOp(Sil.PlusA, _, _) ->
Sil.BinOp (Binop.PlusA, e', c')
| Sil.BinOp(Binop.PlusA, _, _), Sil.BinOp(Binop.PlusA, _, _) ->
Rename.extend len1 len2 Rename.ExtFresh
| Sil.Var id1, Sil.Var id2 when Ident.equal id1 id2 ->
len1
@ -1021,7 +1021,7 @@ let rec exp_partial_meet (e1: Sil.exp) (e2: Sil.exp) : Sil.exp =
if not (Unop.equal unop1 unop2) then (L.d_strln "failure reason 31"; raise IList.Fail)
else Sil.UnOp (unop1, exp_partial_meet e1 e2, topt1) (* should be topt1 = topt2 *)
| Sil.BinOp(binop1, e1, e1'), Sil.BinOp(binop2, e2, e2') ->
if not (Sil.binop_equal binop1 binop2) then (L.d_strln "failure reason 32"; raise IList.Fail)
if not (Binop.equal binop1 binop2) then (L.d_strln "failure reason 32"; raise IList.Fail)
else
let e1'' = exp_partial_meet e1 e2 in
let e2'' = exp_partial_meet e1' e2' in
@ -1595,11 +1595,11 @@ let pi_partial_join mode
if IntLit.leq n first_try then
if IntLit.leq n second_try then second_try else first_try
else widening_top in
let a' = Prop.mk_inequality (Sil.BinOp(Sil.Le, e, Sil.exp_int bound)) in
let a' = Prop.mk_inequality (Sil.BinOp(Binop.Le, e, Sil.exp_int bound)) in
Some a'
| Some (e, _), [] ->
let bound = widening_top in
let a' = Prop.mk_inequality (Sil.BinOp(Sil.Le, e, Sil.exp_int bound)) in
let a' = Prop.mk_inequality (Sil.BinOp(Binop.Le, e, Sil.exp_int bound)) in
Some a'
| _ ->
begin
@ -1608,7 +1608,7 @@ let pi_partial_join mode
| Some (n, e) ->
let bound =
if IntLit.leq IntLit.minus_one n then IntLit.minus_one else widening_bottom in
let a' = Prop.mk_inequality (Sil.BinOp(Sil.Lt, Sil.exp_int bound, e)) in
let a' = Prop.mk_inequality (Sil.BinOp(Binop.Lt, Sil.exp_int bound, e)) in
Some a'
end in
let is_stronger_le e n a =

@ -279,10 +279,10 @@ and _exp_lv_dexp (_seen : Sil.ExpSet.t) node e : Sil.dexp option =
| Sil.Const c ->
if verbose then (L.d_str "exp_lv_dexp: constant "; Sil.d_exp e; L.d_ln ());
Some (Sil.Dderef (Sil.Dconst c))
| Sil.BinOp(Sil.PlusPI, e1, e2) ->
| Sil.BinOp(Binop.PlusPI, e1, e2) ->
if verbose then (L.d_str "exp_lv_dexp: (e1 +PI e2) "; Sil.d_exp e; L.d_ln ());
(match _exp_lv_dexp seen node e1, _exp_rv_dexp seen node e2 with
| Some de1, Some de2 -> Some (Sil.Dbinop(Sil.PlusPI, de1, de2))
| Some de1, Some de2 -> Some (Sil.Dbinop(Binop.PlusPI, de1, de2))
| _ -> None)
| Sil.Var id when Ident.is_normal id ->
if verbose then (L.d_str "exp_lv_dexp: normal var "; Sil.d_exp e; L.d_ln ());
@ -754,7 +754,7 @@ let explain_dexp_access prop dexp is_nullable =
| None -> None
| Some (Sil.Eexp (e, _)) -> find_ptsto e
| Some _ -> None)
| (Sil.Dbinop(Sil.PlusPI, Sil.Dpvar _, Sil.Dconst _) as de) ->
| (Sil.Dbinop(Binop.PlusPI, Sil.Dpvar _, Sil.Dconst _) as de) ->
if verbose then (L.d_strln ("lookup: case )pvar + constant) " ^ Sil.dexp_to_string de));
None
| Sil.Dfcall (Sil.Dconst c, _, loc, _) ->
@ -801,7 +801,7 @@ let explain_dexp_access prop dexp is_nullable =
let explain_dereference_access outermost_array is_nullable _de_opt prop =
let de_opt =
let rec remove_outermost_array_access = function (* remove outermost array access from [de] *)
| Sil.Dbinop(Sil.PlusPI, de1, _) -> (* remove pointer arithmetic before array access *)
| Sil.Dbinop(Binop.PlusPI, de1, _) -> (* remove pointer arithmetic before array access *)
remove_outermost_array_access de1
| Sil.Darray(Sil.Dderef de1, _) -> (* array access is a deref already: remove both *)
de1
@ -895,7 +895,7 @@ let _explain_access
| Sil.Lvar _ ->
if verbose then (L.d_str "find_outermost_dereference: Lvar "; Sil.d_exp e; L.d_ln ());
exp_lv_dexp node e
| Sil.BinOp(Sil.PlusPI, Sil.Lvar _, _) ->
| Sil.BinOp(Binop.PlusPI, Sil.Lvar _, _) ->
if verbose
then
(L.d_str "find_outermost_dereference: Lvar+index ";
@ -904,7 +904,7 @@ let _explain_access
| Sil.Cast (_, e') ->
if verbose then (L.d_str "find_outermost_dereference: cast "; Sil.d_exp e; L.d_ln ());
find_outermost_dereference node e'
| Sil.BinOp(Sil.PtrFld, _, e') ->
| Sil.BinOp(Binop.PtrFld, _, e') ->
if verbose then (L.d_str "find_outermost_dereference: PtrFld "; Sil.d_exp e; L.d_ln ());
find_outermost_dereference node e'
| _ ->
@ -918,7 +918,7 @@ let _explain_access
if verbose then (L.d_str "explain_dereference Sil.Set "; Sil.d_exp e; L.d_ln ());
Some e
| Some Sil.Letderef (_, e, _, _) ->
if verbose then (L.d_str "explain_dereference Sil.Leteref "; Sil.d_exp e; L.d_ln ());
if verbose then (L.d_str "explain_dereference Binop.Leteref "; Sil.d_exp e; L.d_ln ());
Some e
| Some Sil.Call (_, Sil.Const (Const.Cfun fn), [(e, _)], _, _)
when Procname.to_string fn = "free" ->

@ -62,7 +62,7 @@ let rec exp_match e1 sub vars e2 : (Sil.subst * Ident.t list) option =
exp_match e1' sub vars e2'
| Sil.UnOp _, _ | _, Sil.UnOp _ ->
None (* Naive *)
| Sil.BinOp(b1, e1', e1''), Sil.BinOp(b2, e2', e2'') when Sil.binop_equal b1 b2 ->
| Sil.BinOp(b1, e1', e1''), Sil.BinOp(b2, e2', e2'') when Binop.equal b1 b2 ->
(match exp_match e1' sub vars e2' with
| None -> None
| Some (sub', vars') -> exp_match e1'' sub' vars' e2'')

@ -179,7 +179,7 @@ let create_type tenv n_lexp typ prop =
let prop''= Prop.normalize prop'' in
prop''
| None -> prop in
let sil_is_null = Sil.BinOp (Sil.Eq, n_lexp, Sil.exp_zero) in
let sil_is_null = Sil.BinOp (Binop.Eq, n_lexp, Sil.exp_zero) in
let sil_is_nonnull = Sil.UnOp (Unop.LNot, sil_is_null, None) in
let null_case = Propset.to_proplist (prune ~positive:true sil_is_null prop) in
let non_null_case = Propset.to_proplist (prune ~positive:true sil_is_nonnull prop_type) in
@ -504,7 +504,7 @@ let execute___objc_retain_impl
| [(lexp, _)] ->
let prop = return_result lexp prop_ ret_ids in
execute___objc_counter_update
~mask_errors (Sil.PlusA) (IntLit.one)
~mask_errors (Binop.PlusA) (IntLit.one)
{ builtin_args with Builtin.prop_ = prop; args = args'; }
| _ -> raise (Exceptions.Wrong_argument_number __POS__)
@ -524,7 +524,7 @@ let execute___objc_release_impl
: Builtin.ret_typ =
let mask_errors, args' = get_suppress_npe_flag args in
execute___objc_counter_update
~mask_errors Sil.MinusA IntLit.one
~mask_errors Binop.MinusA IntLit.one
{ builtin_args with Builtin.args = args'; }
let execute___objc_release builtin_args

@ -502,40 +502,40 @@ let sym_eval abs e =
| e1' ->
if abs then Sil.exp_get_undefined false else Sil.UnOp (Unop.BNot, e1', topt)
end
| Sil.BinOp (Sil.Le, e1, e2) ->
| Sil.BinOp (Binop.Le, e1, e2) ->
begin
match eval e1, eval e2 with
| Sil.Const (Const.Cint n), Sil.Const (Const.Cint m) ->
Sil.exp_bool (IntLit.leq n m)
| Sil.Const (Const.Cfloat v), Sil.Const (Const.Cfloat w) ->
Sil.exp_bool (v <= w)
| Sil.BinOp (Sil.PlusA, e3, Sil.Const (Const.Cint n)), Sil.Const (Const.Cint m) ->
Sil.BinOp (Sil.Le, e3, Sil.exp_int (m -- n))
| Sil.BinOp (Binop.PlusA, e3, Sil.Const (Const.Cint n)), Sil.Const (Const.Cint m) ->
Sil.BinOp (Binop.Le, e3, Sil.exp_int (m -- n))
| e1', e2' ->
Sil.exp_le e1' e2'
end
| Sil.BinOp (Sil.Lt, e1, e2) ->
| Sil.BinOp (Binop.Lt, e1, e2) ->
begin
match eval e1, eval e2 with
| Sil.Const (Const.Cint n), Sil.Const (Const.Cint m) ->
Sil.exp_bool (IntLit.lt n m)
| Sil.Const (Const.Cfloat v), Sil.Const (Const.Cfloat w) ->
Sil.exp_bool (v < w)
| Sil.Const (Const.Cint n), Sil.BinOp (Sil.MinusA, f1, f2) ->
| Sil.Const (Const.Cint n), Sil.BinOp (Binop.MinusA, f1, f2) ->
Sil.BinOp
(Sil.Le, Sil.BinOp (Sil.MinusA, f2, f1), Sil.exp_int (IntLit.minus_one -- n))
| Sil.BinOp(Sil.MinusA, f1 , f2), Sil.Const(Const.Cint n) ->
Sil.exp_le (Sil.BinOp(Sil.MinusA, f1 , f2)) (Sil.exp_int (n -- IntLit.one))
| Sil.BinOp (Sil.PlusA, e3, Sil.Const (Const.Cint n)), Sil.Const (Const.Cint m) ->
Sil.BinOp (Sil.Lt, e3, Sil.exp_int (m -- n))
(Binop.Le, Sil.BinOp (Binop.MinusA, f2, f1), Sil.exp_int (IntLit.minus_one -- n))
| Sil.BinOp(Binop.MinusA, f1 , f2), Sil.Const(Const.Cint n) ->
Sil.exp_le (Sil.BinOp(Binop.MinusA, f1 , f2)) (Sil.exp_int (n -- IntLit.one))
| Sil.BinOp (Binop.PlusA, e3, Sil.Const (Const.Cint n)), Sil.Const (Const.Cint m) ->
Sil.BinOp (Binop.Lt, e3, Sil.exp_int (m -- n))
| e1', e2' ->
Sil.exp_lt e1' e2'
end
| Sil.BinOp (Sil.Ge, e1, e2) ->
| Sil.BinOp (Binop.Ge, e1, e2) ->
eval (Sil.exp_le e2 e1)
| Sil.BinOp (Sil.Gt, e1, e2) ->
| Sil.BinOp (Binop.Gt, e1, e2) ->
eval (Sil.exp_lt e2 e1)
| Sil.BinOp (Sil.Eq, e1, e2) ->
| Sil.BinOp (Binop.Eq, e1, e2) ->
begin
match eval e1, eval e2 with
| Sil.Const (Const.Cint n), Sil.Const (Const.Cint m) ->
@ -545,7 +545,7 @@ let sym_eval abs e =
| e1', e2' ->
Sil.exp_eq e1' e2'
end
| Sil.BinOp (Sil.Ne, e1, e2) ->
| Sil.BinOp (Binop.Ne, e1, e2) ->
begin
match eval e1, eval e2 with
| Sil.Const (Const.Cint n), Sil.Const (Const.Cint m) ->
@ -555,7 +555,7 @@ let sym_eval abs e =
| e1', e2' ->
Sil.exp_ne e1' e2'
end
| Sil.BinOp (Sil.LAnd, e1, e2) ->
| Sil.BinOp (Binop.LAnd, e1, e2) ->
let e1' = eval e1 in
let e2' = eval e2 in
begin match e1', e2' with
@ -568,9 +568,9 @@ let sym_eval abs e =
| _, Sil.Const (Const.Cint _) ->
e1'
| _ ->
Sil.BinOp (Sil.LAnd, e1', e2')
Sil.BinOp (Binop.LAnd, e1', e2')
end
| Sil.BinOp (Sil.LOr, e1, e2) ->
| Sil.BinOp (Binop.LOr, e1, e2) ->
let e1' = eval e1 in
let e2' = eval e2 in
begin
@ -584,22 +584,22 @@ let sym_eval abs e =
| _, Sil.Const (Const.Cint _) ->
e2'
| _ ->
Sil.BinOp (Sil.LOr, e1', e2')
Sil.BinOp (Binop.LOr, e1', e2')
end
| Sil.BinOp(Sil.PlusPI, Sil.Lindex (ep, e1), e2) -> (* array access with pointer arithmetic *)
let e' = Sil.BinOp (Sil.PlusA, e1, e2) in
| Sil.BinOp(Binop.PlusPI, Sil.Lindex (ep, e1), e2) -> (* array access with pointer arithmetic *)
let e' = Sil.BinOp (Binop.PlusA, e1, e2) in
eval (Sil.Lindex (ep, e'))
| Sil.BinOp (Sil.PlusPI, (Sil.BinOp (Sil.PlusPI, e11, e12)), e2) ->
| Sil.BinOp (Binop.PlusPI, (Sil.BinOp (Binop.PlusPI, e11, e12)), e2) ->
(* take care of pattern ((ptr + off1) + off2) *)
(* progress: convert inner +I to +A *)
let e2' = Sil.BinOp (Sil.PlusA, e12, e2) in
eval (Sil.BinOp (Sil.PlusPI, e11, e2'))
| Sil.BinOp (Sil.PlusA as oplus, e1, e2)
| Sil.BinOp (Sil.PlusPI as oplus, e1, e2) ->
let e2' = Sil.BinOp (Binop.PlusA, e12, e2) in
eval (Sil.BinOp (Binop.PlusPI, e11, e2'))
| Sil.BinOp (Binop.PlusA as oplus, e1, e2)
| Sil.BinOp (Binop.PlusPI as oplus, e1, e2) ->
let e1' = eval e1 in
let e2' = eval e2 in
let isPlusA = oplus = Sil.PlusA in
let ominus = if isPlusA then Sil.MinusA else Sil.MinusPI in
let isPlusA = oplus = Binop.PlusA in
let ominus = if isPlusA then Binop.MinusA else Binop.MinusPI in
let (+++) x y = match x, y with
| _, Sil.Const (Const.Cint i) when IntLit.iszero i -> x
| Sil.Const (Const.Cint i), Sil.Const (Const.Cint j) ->
@ -617,7 +617,7 @@ let sym_eval abs e =
match e1', e2' with
(* pattern for arrays and extensible structs:
sizeof(struct s {... t[l]}) + k * sizeof(t)) = sizeof(struct s {... t[l + k]}) *)
| Sil.Sizeof (typ, len1_opt, st), Sil.BinOp (Sil.Mult, len2, Sil.Sizeof (elt, None, _))
| Sil.Sizeof (typ, len1_opt, st), Sil.BinOp (Binop.Mult, len2, Sil.Sizeof (elt, None, _))
when isPlusA && (extensible_array_element_typ_equal elt typ) ->
let len = match len1_opt with Some len1 -> len1 +++ len2 | None -> len2 in
Sil.Sizeof (typ, Some len, st)
@ -632,15 +632,15 @@ let sym_eval abs e =
| Sil.UnOp(Unop.Neg, f1, _), f2
| f2, Sil.UnOp(Unop.Neg, f1, _) ->
Sil.BinOp (ominus, f2, f1)
| Sil.BinOp (Sil.PlusA, e, Sil.Const (Const.Cint n1)), Sil.Const (Const.Cint n2)
| Sil.BinOp (Sil.PlusPI, e, Sil.Const (Const.Cint n1)), Sil.Const (Const.Cint n2)
| Sil.Const (Const.Cint n2), Sil.BinOp (Sil.PlusA, e, Sil.Const (Const.Cint n1))
| Sil.Const (Const.Cint n2), Sil.BinOp (Sil.PlusPI, e, Sil.Const (Const.Cint n1)) ->
| Sil.BinOp (Binop.PlusA, e, Sil.Const (Const.Cint n1)), Sil.Const (Const.Cint n2)
| Sil.BinOp (Binop.PlusPI, e, Sil.Const (Const.Cint n1)), Sil.Const (Const.Cint n2)
| Sil.Const (Const.Cint n2), Sil.BinOp (Binop.PlusA, e, Sil.Const (Const.Cint n1))
| Sil.Const (Const.Cint n2), Sil.BinOp (Binop.PlusPI, e, Sil.Const (Const.Cint n1)) ->
e +++ (Sil.exp_int (n1 ++ n2))
| Sil.BinOp (Sil.MinusA, Sil.Const (Const.Cint n1), e), Sil.Const (Const.Cint n2)
| Sil.Const (Const.Cint n2), Sil.BinOp (Sil.MinusA, Sil.Const (Const.Cint n1), e) ->
| Sil.BinOp (Binop.MinusA, Sil.Const (Const.Cint n1), e), Sil.Const (Const.Cint n2)
| Sil.Const (Const.Cint n2), Sil.BinOp (Binop.MinusA, Sil.Const (Const.Cint n1), e) ->
Sil.exp_int (n1 ++ n2) --- e
| Sil.BinOp (Sil.MinusA, e1, e2), e3 -> (* (e1-e2)+e3 --> e1 + (e3-e2) *)
| Sil.BinOp (Binop.MinusA, e1, e2), e3 -> (* (e1-e2)+e3 --> e1 + (e3-e2) *)
(* progress: brings + to the outside *)
eval (e1 +++ (e3 --- e2))
| _, Sil.Const _ ->
@ -654,12 +654,12 @@ let sym_eval abs e =
if abs && not isPlusA then e1' +++ (Sil.exp_get_undefined false)
else e1' +++ e2'
end
| Sil.BinOp (Sil.MinusA as ominus, e1, e2)
| Sil.BinOp (Sil.MinusPI as ominus, e1, e2) ->
| Sil.BinOp (Binop.MinusA as ominus, e1, e2)
| Sil.BinOp (Binop.MinusPI as ominus, e1, e2) ->
let e1' = eval e1 in
let e2' = eval e2 in
let isMinusA = ominus = Sil.MinusA in
let oplus = if isMinusA then Sil.PlusA else Sil.PlusPI in
let isMinusA = ominus = Binop.MinusA in
let oplus = if isMinusA then Binop.PlusA else Binop.PlusPI in
let (+++) x y = Sil.BinOp (oplus, x, y) in
let (---) x y = Sil.BinOp (ominus, x, y) in
if Sil.exp_equal e1' e2' then Sil.exp_zero
@ -684,10 +684,10 @@ let sym_eval abs e =
| _, _ ->
if abs then Sil.exp_get_undefined false else e1' --- e2'
end
| Sil.BinOp (Sil.MinusPP, e1, e2) ->
| Sil.BinOp (Binop.MinusPP, e1, e2) ->
if abs then Sil.exp_get_undefined false
else Sil.BinOp (Sil.MinusPP, eval e1, eval e2)
| Sil.BinOp (Sil.Mult, e1, e2) ->
else Sil.BinOp (Binop.MinusPP, eval e1, eval e2)
| Sil.BinOp (Binop.Mult, e1, e2) ->
let e1' = eval e1 in
let e2' = eval e2 in
begin
@ -709,14 +709,14 @@ let sym_eval abs e =
| Sil.Const (Const.Cfloat v), Sil.Const (Const.Cfloat w) ->
Sil.exp_float (v *. w)
| Sil.Var _, Sil.Var _ ->
Sil.BinOp(Sil.Mult, e1', e2')
Sil.BinOp(Binop.Mult, e1', e2')
| _, Sil.Sizeof _
| Sil.Sizeof _, _ ->
Sil.BinOp(Sil.Mult, e1', e2')
Sil.BinOp(Binop.Mult, e1', e2')
| _, _ ->
if abs then Sil.exp_get_undefined false else Sil.BinOp(Sil.Mult, e1', e2')
if abs then Sil.exp_get_undefined false else Sil.BinOp(Binop.Mult, e1', e2')
end
| Sil.BinOp (Sil.Div, e1, e2) ->
| Sil.BinOp (Binop.Div, e1, e2) ->
let e1' = eval e1 in
let e2' = eval e2 in
begin
@ -740,9 +740,9 @@ let sym_eval abs e =
when Typ.equal elt elt2 ->
Sil.Const (Const.Cint len)
| _ ->
if abs then Sil.exp_get_undefined false else Sil.BinOp (Sil.Div, e1', e2')
if abs then Sil.exp_get_undefined false else Sil.BinOp (Binop.Div, e1', e2')
end
| Sil.BinOp (Sil.Mod, e1, e2) ->
| Sil.BinOp (Binop.Mod, e1, e2) ->
let e1' = eval e1 in
let e2' = eval e2 in
begin
@ -756,13 +756,13 @@ let sym_eval abs e =
| Sil.Const (Const.Cint n), Sil.Const (Const.Cint m) ->
Sil.exp_int (IntLit.rem n m)
| _ ->
if abs then Sil.exp_get_undefined false else Sil.BinOp (Sil.Mod, e1', e2')
if abs then Sil.exp_get_undefined false else Sil.BinOp (Binop.Mod, e1', e2')
end
| Sil.BinOp (Sil.Shiftlt, e1, e2) ->
if abs then Sil.exp_get_undefined false else Sil.BinOp (Sil.Shiftlt, eval e1, eval e2)
| Sil.BinOp (Sil.Shiftrt, e1, e2) ->
if abs then Sil.exp_get_undefined false else Sil.BinOp (Sil.Shiftrt, eval e1, eval e2)
| Sil.BinOp (Sil.BAnd, e1, e2) ->
| Sil.BinOp (Binop.Shiftlt, e1, e2) ->
if abs then Sil.exp_get_undefined false else Sil.BinOp (Binop.Shiftlt, eval e1, eval e2)
| Sil.BinOp (Binop.Shiftrt, e1, e2) ->
if abs then Sil.exp_get_undefined false else Sil.BinOp (Binop.Shiftrt, eval e1, eval e2)
| Sil.BinOp (Binop.BAnd, e1, e2) ->
let e1' = eval e1 in
let e2' = eval e2 in
begin match e1', e2' with
@ -773,9 +773,9 @@ let sym_eval abs e =
| Sil.Const (Const.Cint i1), Sil.Const(Const.Cint i2) ->
Sil.exp_int (IntLit.logand i1 i2)
| _ ->
if abs then Sil.exp_get_undefined false else Sil.BinOp (Sil.BAnd, e1', e2')
if abs then Sil.exp_get_undefined false else Sil.BinOp (Binop.BAnd, e1', e2')
end
| Sil.BinOp (Sil.BOr, e1, e2) ->
| Sil.BinOp (Binop.BOr, e1, e2) ->
let e1' = eval e1 in
let e2' = eval e2 in
begin match e1', e2' with
@ -786,9 +786,9 @@ let sym_eval abs e =
| Sil.Const (Const.Cint i1), Sil.Const(Const.Cint i2) ->
Sil.exp_int (IntLit.logor i1 i2)
| _ ->
if abs then Sil.exp_get_undefined false else Sil.BinOp (Sil.BOr, e1', e2')
if abs then Sil.exp_get_undefined false else Sil.BinOp (Binop.BOr, e1', e2')
end
| Sil.BinOp (Sil.BXor, e1, e2) ->
| Sil.BinOp (Binop.BXor, e1, e2) ->
let e1' = eval e1 in
let e2' = eval e2 in
begin match e1', e2' with
@ -799,9 +799,9 @@ let sym_eval abs e =
| Sil.Const (Const.Cint i1), Sil.Const(Const.Cint i2) ->
Sil.exp_int (IntLit.logxor i1 i2)
| _ ->
if abs then Sil.exp_get_undefined false else Sil.BinOp (Sil.BXor, e1', e2')
if abs then Sil.exp_get_undefined false else Sil.BinOp (Binop.BXor, e1', e2')
end
| Sil.BinOp (Sil.PtrFld, e1, e2) ->
| Sil.BinOp (Binop.PtrFld, e1, e2) ->
let e1' = eval e1 in
let e2' = eval e2 in
begin
@ -810,7 +810,7 @@ let sym_eval abs e =
eval (Sil.Lfield(e1', fn, typ))
| Sil.Const (Const.Cint i) when IntLit.iszero i ->
Sil.exp_zero (* cause a NULL dereference *)
| _ -> Sil.BinOp (Sil.PtrFld, e1', e2')
| _ -> Sil.BinOp (Binop.PtrFld, e1', e2')
end
| Sil.Exn _ ->
e
@ -822,9 +822,9 @@ let sym_eval abs e =
| Sil.Lindex(Sil.Lvar pv, e2) when false
(* removed: it interferes with re-arrangement and error messages *)
-> (* &x[n] --> &x + n *)
eval (Sil.BinOp (Sil.PlusPI, Sil.Lvar pv, e2))
| Sil.Lindex (Sil.BinOp(Sil.PlusPI, ep, e1), e2) -> (* array access with pointer arithmetic *)
let e' = Sil.BinOp (Sil.PlusA, e1, e2) in
eval (Sil.BinOp (Binop.PlusPI, Sil.Lvar pv, e2))
| Sil.Lindex (Sil.BinOp(Binop.PlusPI, ep, e1), e2) -> (* array access with pointer arithmetic *)
let e' = Sil.BinOp (Binop.PlusA, e1, e2) in
eval (Sil.Lindex (ep, e'))
| Sil.Lindex (e1, e2) ->
let e1' = eval e1 in
@ -850,20 +850,20 @@ let exp_normalize_noabs sub exp =
(** Return [true] if the atom is an inequality *)
let atom_is_inequality = function
| Sil.Aeq (Sil.BinOp (Sil.Le, _, _), Sil.Const (Const.Cint i)) when IntLit.isone i -> true
| Sil.Aeq (Sil.BinOp (Sil.Lt, _, _), Sil.Const (Const.Cint i)) when IntLit.isone i -> true
| Sil.Aeq (Sil.BinOp (Binop.Le, _, _), Sil.Const (Const.Cint i)) when IntLit.isone i -> true
| Sil.Aeq (Sil.BinOp (Binop.Lt, _, _), Sil.Const (Const.Cint i)) when IntLit.isone i -> true
| _ -> false
(** If the atom is [e<=n] return [e,n] *)
let atom_exp_le_const = function
| Sil.Aeq(Sil.BinOp (Sil.Le, e1, Sil.Const (Const.Cint n)), Sil.Const (Const.Cint i))
| Sil.Aeq(Sil.BinOp (Binop.Le, e1, Sil.Const (Const.Cint n)), Sil.Const (Const.Cint i))
when IntLit.isone i ->
Some (e1, n)
| _ -> None
(** If the atom is [n<e] return [n,e] *)
let atom_const_lt_exp = function
| Sil.Aeq(Sil.BinOp (Sil.Lt, Sil.Const (Const.Cint n), e1), Sil.Const (Const.Cint i))
| Sil.Aeq(Sil.BinOp (Binop.Lt, Sil.Const (Const.Cint n), e1), Sil.Const (Const.Cint i))
when IntLit.isone i ->
Some (n, e1)
| _ -> None
@ -871,56 +871,56 @@ let atom_const_lt_exp = function
(** Turn an inequality expression into an atom *)
let mk_inequality e =
match e with
| Sil.BinOp (Sil.Le, base, Sil.Const (Const.Cint n)) ->
| Sil.BinOp (Binop.Le, base, Sil.Const (Const.Cint n)) ->
(* base <= n case *)
let nbase = exp_normalize_noabs Sil.sub_empty base in
(match nbase with
| Sil.BinOp(Sil.PlusA, base', Sil.Const (Const.Cint n')) ->
| Sil.BinOp(Binop.PlusA, base', Sil.Const (Const.Cint n')) ->
let new_offset = Sil.exp_int (n -- n') in
let new_e = Sil.BinOp (Sil.Le, base', new_offset) in
let new_e = Sil.BinOp (Binop.Le, base', new_offset) in
Sil.Aeq (new_e, Sil.exp_one)
| Sil.BinOp(Sil.PlusA, Sil.Const (Const.Cint n'), base') ->
| Sil.BinOp(Binop.PlusA, Sil.Const (Const.Cint n'), base') ->
let new_offset = Sil.exp_int (n -- n') in
let new_e = Sil.BinOp (Sil.Le, base', new_offset) in
let new_e = Sil.BinOp (Binop.Le, base', new_offset) in
Sil.Aeq (new_e, Sil.exp_one)
| Sil.BinOp(Sil.MinusA, base', Sil.Const (Const.Cint n')) ->
| Sil.BinOp(Binop.MinusA, base', Sil.Const (Const.Cint n')) ->
let new_offset = Sil.exp_int (n ++ n') in
let new_e = Sil.BinOp (Sil.Le, base', new_offset) in
let new_e = Sil.BinOp (Binop.Le, base', new_offset) in
Sil.Aeq (new_e, Sil.exp_one)
| Sil.BinOp(Sil.MinusA, Sil.Const (Const.Cint n'), base') ->
| Sil.BinOp(Binop.MinusA, Sil.Const (Const.Cint n'), base') ->
let new_offset = Sil.exp_int (n' -- n -- IntLit.one) in
let new_e = Sil.BinOp (Sil.Lt, new_offset, base') in
let new_e = Sil.BinOp (Binop.Lt, new_offset, base') in
Sil.Aeq (new_e, Sil.exp_one)
| Sil.UnOp(Unop.Neg, new_base, _) ->
(* In this case, base = -new_base. Construct -n-1 < new_base. *)
let new_offset = Sil.exp_int (IntLit.zero -- n -- IntLit.one) in
let new_e = Sil.BinOp (Sil.Lt, new_offset, new_base) in
let new_e = Sil.BinOp (Binop.Lt, new_offset, new_base) in
Sil.Aeq (new_e, Sil.exp_one)
| _ -> Sil.Aeq (e, Sil.exp_one))
| Sil.BinOp (Sil.Lt, Sil.Const (Const.Cint n), base) ->
| Sil.BinOp (Binop.Lt, Sil.Const (Const.Cint n), base) ->
(* n < base case *)
let nbase = exp_normalize_noabs Sil.sub_empty base in
(match nbase with
| Sil.BinOp(Sil.PlusA, base', Sil.Const (Const.Cint n')) ->
| Sil.BinOp(Binop.PlusA, base', Sil.Const (Const.Cint n')) ->
let new_offset = Sil.exp_int (n -- n') in
let new_e = Sil.BinOp (Sil.Lt, new_offset, base') in
let new_e = Sil.BinOp (Binop.Lt, new_offset, base') in
Sil.Aeq (new_e, Sil.exp_one)
| Sil.BinOp(Sil.PlusA, Sil.Const (Const.Cint n'), base') ->
| Sil.BinOp(Binop.PlusA, Sil.Const (Const.Cint n'), base') ->
let new_offset = Sil.exp_int (n -- n') in
let new_e = Sil.BinOp (Sil.Lt, new_offset, base') in
let new_e = Sil.BinOp (Binop.Lt, new_offset, base') in
Sil.Aeq (new_e, Sil.exp_one)
| Sil.BinOp(Sil.MinusA, base', Sil.Const (Const.Cint n')) ->
| Sil.BinOp(Binop.MinusA, base', Sil.Const (Const.Cint n')) ->
let new_offset = Sil.exp_int (n ++ n') in
let new_e = Sil.BinOp (Sil.Lt, new_offset, base') in
let new_e = Sil.BinOp (Binop.Lt, new_offset, base') in
Sil.Aeq (new_e, Sil.exp_one)
| Sil.BinOp(Sil.MinusA, Sil.Const (Const.Cint n'), base') ->
| Sil.BinOp(Binop.MinusA, Sil.Const (Const.Cint n'), base') ->
let new_offset = Sil.exp_int (n' -- n -- IntLit.one) in
let new_e = Sil.BinOp (Sil.Le, base', new_offset) in
let new_e = Sil.BinOp (Binop.Le, base', new_offset) in
Sil.Aeq (new_e, Sil.exp_one)
| Sil.UnOp(Unop.Neg, new_base, _) ->
(* In this case, base = -new_base. Construct new_base <= -n-1 *)
let new_offset = Sil.exp_int (IntLit.zero -- n -- IntLit.one) in
let new_e = Sil.BinOp (Sil.Le, new_base, new_offset) in
let new_e = Sil.BinOp (Binop.Le, new_base, new_offset) in
Sil.Aeq (new_e, Sil.exp_one)
| _ -> Sil.Aeq (e, Sil.exp_one))
| _ -> Sil.Aeq (e, Sil.exp_one)
@ -932,13 +932,13 @@ let inequality_normalize a =
(** representing inequality [sum(pos) - sum(neg) + off <= 0] *)
let rec exp_to_posnegoff e = match e with
| Sil.Const (Const.Cint n) -> [],[], n
| Sil.BinOp(Sil.PlusA, e1, e2) | Sil.BinOp(Sil.PlusPI, e1, e2) ->
| Sil.BinOp(Binop.PlusA, e1, e2) | Sil.BinOp(Binop.PlusPI, e1, e2) ->
let pos1, neg1, n1 = exp_to_posnegoff e1 in
let pos2, neg2, n2 = exp_to_posnegoff e2 in
(pos1@pos2, neg1@neg2, n1 ++ n2)
| Sil.BinOp(Sil.MinusA, e1, e2)
| Sil.BinOp(Sil.MinusPI, e1, e2)
| Sil.BinOp(Sil.MinusPP, e1, e2) ->
| Sil.BinOp(Binop.MinusA, e1, e2)
| Sil.BinOp(Binop.MinusPI, e1, e2)
| Sil.BinOp(Binop.MinusPP, e1, e2) ->
let pos1, neg1, n1 = exp_to_posnegoff e1 in
let pos2, neg2, n2 = exp_to_posnegoff e2 in
(pos1@neg2, neg1@pos2, n1 -- n2)
@ -963,25 +963,25 @@ let inequality_normalize a =
let rec exp_list_to_sum = function
| [] -> assert false
| [e] -> e
| e:: el -> Sil.BinOp(Sil.PlusA, e, exp_list_to_sum el) in
| e:: el -> Sil.BinOp(Binop.PlusA, e, exp_list_to_sum el) in
let norm_from_exp e =
match normalize_posnegoff (exp_to_posnegoff e) with
| [],[], n -> Sil.BinOp(Sil.Le, Sil.exp_int n, Sil.exp_zero)
| [], neg, n -> Sil.BinOp(Sil.Lt, Sil.exp_int (n -- IntLit.one), exp_list_to_sum neg)
| pos, [], n -> Sil.BinOp(Sil.Le, exp_list_to_sum pos, Sil.exp_int (IntLit.zero -- n))
| [],[], n -> Sil.BinOp(Binop.Le, Sil.exp_int n, Sil.exp_zero)
| [], neg, n -> Sil.BinOp(Binop.Lt, Sil.exp_int (n -- IntLit.one), exp_list_to_sum neg)
| pos, [], n -> Sil.BinOp(Binop.Le, exp_list_to_sum pos, Sil.exp_int (IntLit.zero -- n))
| pos, neg, n ->
let lhs_e = Sil.BinOp(Sil.MinusA, exp_list_to_sum pos, exp_list_to_sum neg) in
Sil.BinOp(Sil.Le, lhs_e, Sil.exp_int (IntLit.zero -- n)) in
let lhs_e = Sil.BinOp(Binop.MinusA, exp_list_to_sum pos, exp_list_to_sum neg) in
Sil.BinOp(Binop.Le, lhs_e, Sil.exp_int (IntLit.zero -- n)) in
let ineq = match a with
| Sil.Aeq (ineq, Sil.Const (Const.Cint i)) when IntLit.isone i ->
ineq
| _ -> assert false in
match ineq with
| Sil.BinOp(Sil.Le, e1, e2) ->
let e = Sil.BinOp(Sil.MinusA, e1, e2) in
| Sil.BinOp(Binop.Le, e1, e2) ->
let e = Sil.BinOp(Binop.MinusA, e1, e2) in
mk_inequality (norm_from_exp e)
| Sil.BinOp(Sil.Lt, e1, e2) ->
let e = Sil.BinOp(Sil.MinusA, Sil.BinOp(Sil.MinusA, e1, e2), Sil.exp_minus_one) in
| Sil.BinOp(Binop.Lt, e1, e2) ->
let e = Sil.BinOp(Binop.MinusA, Sil.BinOp(Binop.MinusA, e1, e2), Sil.exp_minus_one) in
mk_inequality (norm_from_exp e)
| _ -> a
@ -993,15 +993,15 @@ let exp_reorder e1 e2 = if Sil.exp_compare e1 e2 <= 0 then (e1, e2) else (e2, e1
let atom_normalize sub a0 =
let a = Sil.atom_sub sub a0 in
let rec normalize_eq eq = match eq with
| Sil.BinOp(Sil.PlusA, e1, Sil.Const (Const.Cint n1)), Sil.Const (Const.Cint n2)
| Sil.BinOp(Binop.PlusA, e1, Sil.Const (Const.Cint n1)), Sil.Const (Const.Cint n2)
(* e1+n1==n2 ---> e1==n2-n1 *)
| Sil.BinOp(Sil.PlusPI, e1, Sil.Const (Const.Cint n1)), Sil.Const (Const.Cint n2) ->
| Sil.BinOp(Binop.PlusPI, e1, Sil.Const (Const.Cint n1)), Sil.Const (Const.Cint n2) ->
(e1, Sil.exp_int (n2 -- n1))
| Sil.BinOp(Sil.MinusA, e1, Sil.Const (Const.Cint n1)), Sil.Const (Const.Cint n2)
| Sil.BinOp(Binop.MinusA, e1, Sil.Const (Const.Cint n1)), Sil.Const (Const.Cint n2)
(* e1-n1==n2 ---> e1==n1+n2 *)
| Sil.BinOp(Sil.MinusPI, e1, Sil.Const (Const.Cint n1)), Sil.Const (Const.Cint n2) ->
| Sil.BinOp(Binop.MinusPI, e1, Sil.Const (Const.Cint n1)), Sil.Const (Const.Cint n2) ->
(e1, Sil.exp_int (n1 ++ n2))
| Sil.BinOp(Sil.MinusA, Sil.Const (Const.Cint n1), e1), Sil.Const (Const.Cint n2) ->
| Sil.BinOp(Binop.MinusA, Sil.Const (Const.Cint n1), e1), Sil.Const (Const.Cint n2) ->
(* n1-e1 == n2 -> e1==n1-n2 *)
(e1, Sil.exp_int (n1 -- n2))
| Sil.Lfield (e1', fld1, _), Sil.Lfield (e2', fld2, _) ->
@ -1040,9 +1040,9 @@ let atom_normalize sub a0 =
(** Negate an atom *)
let atom_negate = function
| Sil.Aeq (Sil.BinOp (Sil.Le, e1, e2), Sil.Const (Const.Cint i)) when IntLit.isone i ->
| Sil.Aeq (Sil.BinOp (Binop.Le, e1, e2), Sil.Const (Const.Cint i)) when IntLit.isone i ->
mk_inequality (Sil.exp_lt e2 e1)
| Sil.Aeq (Sil.BinOp (Sil.Lt, e1, e2), Sil.Const (Const.Cint i)) when IntLit.isone i ->
| Sil.Aeq (Sil.BinOp (Binop.Lt, e1, e2), Sil.Const (Const.Cint i)) when IntLit.isone i ->
mk_inequality (Sil.exp_le e2 e1)
| Sil.Aeq (e1, e2) -> Sil.Aneq (e1, e2)
| Sil.Aneq (e1, e2) -> Sil.Aeq (e1, e2)
@ -1166,18 +1166,18 @@ let rec hpred_normalize sub hpred =
into a strexp of the given type *)
let hpred' = mk_ptsto_exp None Fld_init (root, size, None) inst in
replace_hpred hpred'
| ( Sil.Earray (Sil.BinOp (Sil.Mult, Sil.Sizeof (t, None, st1), x), esel, inst)
| Sil.Earray (Sil.BinOp (Sil.Mult, x, Sil.Sizeof (t, None, st1)), esel, inst)),
| ( Sil.Earray (Sil.BinOp (Binop.Mult, Sil.Sizeof (t, None, st1), x), esel, inst)
| Sil.Earray (Sil.BinOp (Binop.Mult, x, Sil.Sizeof (t, None, st1)), esel, inst)),
Sil.Sizeof (Typ.Tarray (elt, _) as arr, _, _)
when Typ.equal t elt ->
let len = Some x in
let hpred' = mk_ptsto_exp None Fld_init (root, Sil.Sizeof (arr, len, st1), None) inst in
replace_hpred (replace_array_contents hpred' esel)
| ( Sil.Earray (Sil.BinOp (Sil.Mult, Sil.Sizeof (t, Some len, st1), x), esel, inst)
| Sil.Earray (Sil.BinOp (Sil.Mult, x, Sil.Sizeof (t, Some len, st1)), esel, inst)),
| ( Sil.Earray (Sil.BinOp (Binop.Mult, Sil.Sizeof (t, Some len, st1), x), esel, inst)
| Sil.Earray (Sil.BinOp (Binop.Mult, x, Sil.Sizeof (t, Some len, st1)), esel, inst)),
Sil.Sizeof (Typ.Tarray (elt, _) as arr, _, _)
when Typ.equal t elt ->
let len = Some (Sil.BinOp(Sil.Mult, x, len)) in
let len = Some (Sil.BinOp(Binop.Mult, x, len)) in
let hpred' = mk_ptsto_exp None Fld_init (root, Sil.Sizeof (arr, len, st1), None) inst in
replace_hpred (replace_array_contents hpred' esel)
| _ -> Sil.Hpointsto (normalized_root, normalized_cnt, normalized_te)
@ -1245,11 +1245,11 @@ let pi_tighten_ineq pi =
let ineq_list' =
let le_ineq_list =
IList.map
(fun (e, n) -> mk_inequality (Sil.BinOp(Sil.Le, e, Sil.exp_int n)))
(fun (e, n) -> mk_inequality (Sil.BinOp(Binop.Le, e, Sil.exp_int n)))
le_list_tightened in
let lt_ineq_list =
IList.map
(fun (n, e) -> mk_inequality (Sil.BinOp(Sil.Lt, Sil.exp_int n, e)))
(fun (n, e) -> mk_inequality (Sil.BinOp(Binop.Lt, Sil.exp_int n, e)))
lt_list_tightened in
le_ineq_list @ lt_ineq_list in
let nonineq_list' =
@ -1269,14 +1269,16 @@ let pi_tighten_ineq pi =
(** remove duplicate atoms and redundant inequalities from a sorted pi *)
let rec pi_sorted_remove_redundant = function
| (Sil.Aeq(Sil.BinOp (Sil.Le, e1, Sil.Const (Const.Cint n1)), Sil.Const (Const.Cint i1)) as a1) ::
Sil.Aeq(Sil.BinOp (Sil.Le, e2, Sil.Const (Const.Cint n2)), Sil.Const (Const.Cint i2)) :: rest
| (Sil.Aeq (Sil.BinOp (Binop.Le, e1, Sil.Const (Const.Cint n1)),
Sil.Const (Const.Cint i1)) as a1) ::
Sil.Aeq (Sil.BinOp (Binop.Le, e2, Sil.Const (Const.Cint n2)),
Sil.Const (Const.Cint i2)) :: rest
when IntLit.isone i1 && IntLit.isone i2 && Sil.exp_equal e1 e2 && IntLit.lt n1 n2 ->
(* second inequality redundant *)
pi_sorted_remove_redundant (a1 :: rest)
| Sil.Aeq(Sil.BinOp (Sil.Lt, Sil.Const (Const.Cint n1), e1), Sil.Const (Const.Cint i1)) ::
(Sil.Aeq(Sil.BinOp (Sil.Lt, Sil.Const (Const.Cint n2), e2), Sil.Const (Const.Cint i2)) as a2) ::
rest
| Sil.Aeq (Sil.BinOp (Binop.Lt, Sil.Const (Const.Cint n1), e1), Sil.Const (Const.Cint i1)) ::
(Sil.Aeq (Sil.BinOp (Binop.Lt, Sil.Const (Const.Cint n2), e2), Sil.Const (Const.Cint i2)) as a2)
:: rest
when IntLit.isone i1 && IntLit.isone i2 && Sil.exp_equal e1 e2 && IntLit.lt n1 n2 ->
(* first inequality redundant *)
pi_sorted_remove_redundant (a2 :: rest)
@ -1305,16 +1307,16 @@ let pi_normalize sub sigma pi0 =
let syntactically_different = function
| Sil.BinOp(op1, e1, Sil.Const(c1)), Sil.BinOp(op2, e2, Sil.Const(c2))
when Sil.exp_equal e1 e2 ->
Sil.binop_equal op1 op2 && Sil.binop_injective op1 && not (Const.equal c1 c2)
Binop.equal op1 op2 && Binop.injective op1 && not (Const.equal c1 c2)
| e1, Sil.BinOp(op2, e2, Sil.Const(c2))
when Sil.exp_equal e1 e2 ->
Sil.binop_injective op2 &&
Sil.binop_is_zero_runit op2 &&
Binop.injective op2 &&
Binop.is_zero_runit op2 &&
not (Const.equal (Const.Cint IntLit.zero) c2)
| Sil.BinOp(op1, e1, Sil.Const(c1)), e2
when Sil.exp_equal e1 e2 ->
Sil.binop_injective op1 &&
Sil.binop_is_zero_runit op1 &&
Binop.injective op1 &&
Binop.is_zero_runit op1 &&
not (Const.equal (Const.Cint IntLit.zero) c1)
| _ -> false in
let filter_useful_atom =
@ -1398,7 +1400,7 @@ let exp_collapse_consecutive_indices_prop typ exp =
let rec exp_remove e0 =
match e0 with
| Sil.Lindex(Sil.Lindex(base, e1), e2) ->
let e0' = Sil.Lindex(base, Sil.BinOp(Sil.PlusA, e1, e2)) in
let e0' = Sil.Lindex(base, Sil.BinOp(Binop.PlusA, e1, e2)) in
exp_remove e0'
| _ -> e0 in
begin
@ -1673,19 +1675,19 @@ let sigma_intro_nonemptylseg e1 e2 sigma =
let normalize_and_strengthen_atom (p : normal t) (a : Sil.atom) : Sil.atom =
let a' = atom_normalize p.sub a in
match a' with
| Sil.Aeq (Sil.BinOp (Sil.Le, Sil.Var id, Sil.Const (Const.Cint n)), Sil.Const (Const.Cint i))
| Sil.Aeq (Sil.BinOp (Binop.Le, Sil.Var id, Sil.Const (Const.Cint n)), Sil.Const (Const.Cint i))
when IntLit.isone i ->
let lower = Sil.exp_int (n -- IntLit.one) in
let a_lower = Sil.Aeq (Sil.BinOp (Sil.Lt, lower, Sil.Var id), Sil.exp_one) in
let a_lower = Sil.Aeq (Sil.BinOp (Binop.Lt, lower, Sil.Var id), Sil.exp_one) in
if not (IList.mem Sil.atom_equal a_lower p.pi) then a'
else Sil.Aeq (Sil.Var id, Sil.exp_int n)
| Sil.Aeq (Sil.BinOp (Sil.Lt, Sil.Const (Const.Cint n), Sil.Var id), Sil.Const (Const.Cint i))
| Sil.Aeq (Sil.BinOp (Binop.Lt, Sil.Const (Const.Cint n), Sil.Var id), Sil.Const (Const.Cint i))
when IntLit.isone i ->
let upper = Sil.exp_int (n ++ IntLit.one) in
let a_upper = Sil.Aeq (Sil.BinOp (Sil.Le, Sil.Var id, upper), Sil.exp_one) in
let a_upper = Sil.Aeq (Sil.BinOp (Binop.Le, Sil.Var id, upper), Sil.exp_one) in
if not (IList.mem Sil.atom_equal a_upper p.pi) then a'
else Sil.Aeq (Sil.Var id, upper)
| Sil.Aeq (Sil.BinOp (Sil.Ne, e1, e2), Sil.Const (Const.Cint i)) when IntLit.isone i ->
| Sil.Aeq (Sil.BinOp (Binop.Ne, e1, e2), Sil.Const (Const.Cint i)) when IntLit.isone i ->
Sil.Aneq (e1, e2)
| _ -> a'
@ -1980,7 +1982,7 @@ let find_arithmetic_problem proc_node_session prop exp =
uminus_unsigned := (e, typ) :: !uminus_unsigned
| Sil.UnOp(_, e, _) -> walk e
| Sil.BinOp(op, e1, e2) ->
if op = Sil.Div || op = Sil.Mod then exps_divided := e2 :: !exps_divided;
if op = Binop.Div || op = Binop.Mod then exps_divided := e2 :: !exps_divided;
walk e1; walk e2
| Sil.Exn _ -> ()
| Sil.Closure _ -> ()
@ -2187,14 +2189,14 @@ let compute_reindexing fav_add get_id_offset list =
let id, offset = match get_id_offset x with None -> assert false | Some io -> io in
let base_new = Sil.Var (Ident.create_fresh Ident.kprimed) in
let offset_new = Sil.exp_int (IntLit.neg offset) in
let exp_new = Sil.BinOp(Sil.PlusA, base_new, offset_new) in
let exp_new = Sil.BinOp(Binop.PlusA, base_new, offset_new) in
(id, exp_new) in
let reindexing = IList.map transform list_passed in
Sil.sub_of_list reindexing
let compute_reindexing_from_indices indices =
let get_id_offset = function
| Sil.BinOp (Sil.PlusA, Sil.Var id, Sil.Const(Const.Cint offset)) ->
| Sil.BinOp (Binop.PlusA, Sil.Var id, Sil.Const(Const.Cint offset)) ->
if Ident.is_primed id then Some (id, offset) else None
| _ -> None in
let fav_add = Sil.exp_fav_add in
@ -2221,8 +2223,8 @@ let prop_rename_array_indices prop =
let indices = sigma_get_array_indices prop.sigma in
let not_same_base_lt_offsets e1 e2 =
match e1, e2 with
| Sil.BinOp(Sil.PlusA, e1', Sil.Const (Const.Cint n1')),
Sil.BinOp(Sil.PlusA, e2', Sil.Const (Const.Cint n2')) ->
| Sil.BinOp(Binop.PlusA, e1', Sil.Const (Const.Cint n1')),
Sil.BinOp(Binop.PlusA, e2', Sil.Const (Const.Cint n2')) ->
not (Sil.exp_equal e1' e2' && IntLit.lt n1' n2')
| _ -> true in
let rec select_minimal_indices indices_seen = function
@ -2779,11 +2781,11 @@ let trans_land_lor op ((idl1, stml1), e1) ((idl2, stml2), e2) loc =
let id = Ident.create_fresh Ident.knormal in
let prune_instr1, prune_res1, prune_instr2, prune_res2 =
let cond1, cond2, res = match op with
| Sil.LAnd -> e1, Sil.UnOp(Unop.LNot, e1, None), IntLit.zero
| Sil.LOr -> Sil.UnOp(Unop.LNot, e1, None), e1, IntLit.one
| Binop.LAnd -> e1, Sil.UnOp(Unop.LNot, e1, None), IntLit.zero
| Binop.LOr -> Sil.UnOp(Unop.LNot, e1, None), e1, IntLit.one
| _ -> assert false in
let cond_res1 = Sil.BinOp(Sil.Eq, Sil.Var id, e2) in
let cond_res2 = Sil.BinOp(Sil.Eq, Sil.Var id, Sil.exp_int res) in
let cond_res1 = Sil.BinOp(Binop.Eq, Sil.Var id, e2) in
let cond_res2 = Sil.BinOp(Binop.Eq, Sil.Var id, Sil.exp_int res) in
let mk_prune cond =
(* don't report always true/false *)
Sil.Prune (cond, loc, true, Sil.Ik_land_lor) in
@ -2841,7 +2843,7 @@ let trans_if_then_else ((idl1, stml1), e1) ((idl2, stml2), e2) ((idl3, stml3), e
let mk_prune_res e =
let mk_prune cond = Sil.Prune (cond, loc, true, Sil.Ik_land_lor)
(* don't report always true/false *) in
mk_prune (Sil.BinOp(Sil.Eq, Sil.Var id, e)) in
mk_prune (Sil.BinOp(Binop.Eq, Sil.Var id, e)) in
let prune1 = Sil.Prune (e1, loc, true, Sil.Ik_bexp) in
let prune1not = Sil.Prune (e1not, loc, false, Sil.Ik_bexp) in
let stml' =

@ -378,7 +378,7 @@ val prop_expand : normal t -> normal t list
(** translate a logical and/or operation
taking care of the non-strict semantics for side effects *)
val trans_land_lor :
Sil.binop -> (Ident.t list * Sil.instr list) * Sil.exp ->
Binop.t -> (Ident.t list * Sil.instr list) * Sil.exp ->
(Ident.t list * Sil.instr list) * Sil.exp -> Location.t ->
(Ident.t list * Sil.instr list) * Sil.exp

@ -72,14 +72,15 @@ end = struct
let equal entry1 entry2 = compare entry1 entry2 = 0
let to_leq (e1, e2, n) =
Sil.BinOp(Sil.MinusA, e1, e2), Sil.exp_int n
Sil.BinOp(Binop.MinusA, e1, e2), Sil.exp_int n
let to_lt (e1, e2, n) =
Sil.exp_int (IntLit.zero -- n -- IntLit.one), Sil.BinOp(Sil.MinusA, e2, e1)
Sil.exp_int (IntLit.zero -- n -- IntLit.one), Sil.BinOp(Binop.MinusA, e2, e1)
let to_triple entry = entry
let from_leq acc (e1, e2) =
match e1, e2 with
| Sil.BinOp(Sil.MinusA, (Sil.Var id11 as e11), (Sil.Var id12 as e12)), Sil.Const (Const.Cint n)
| Sil.BinOp (Binop.MinusA, (Sil.Var id11 as e11), (Sil.Var id12 as e12)),
Sil.Const (Const.Cint n)
when not (Ident.equal id11 id12) ->
(match IntLit.to_signed n with
| None -> acc (* ignore: constraint algorithm only terminates on signed integers *)
@ -88,7 +89,8 @@ end = struct
| _ -> acc
let from_lt acc (e1, e2) =
match e1, e2 with
| Sil.Const (Const.Cint n), Sil.BinOp(Sil.MinusA, (Sil.Var id21 as e21), (Sil.Var id22 as e22))
| Sil.Const (Const.Cint n),
Sil.BinOp (Binop.MinusA, (Sil.Var id21 as e21), (Sil.Var id22 as e22))
when not (Ident.equal id21 id22) ->
(match IntLit.to_signed n with
| None -> acc (* ignore: constraint algorithm only terminates on signed integers *)
@ -357,9 +359,9 @@ end = struct
let process_atom = function
| Sil.Aneq (e1, e2) -> (* != *)
neqs := (e1, e2) :: !neqs
| Sil.Aeq (Sil.BinOp (Sil.Le, e1, e2), Sil.Const (Const.Cint i)) when IntLit.isone i ->
| Sil.Aeq (Sil.BinOp (Binop.Le, e1, e2), Sil.Const (Const.Cint i)) when IntLit.isone i ->
leqs := (e1, e2) :: !leqs (* <= *)
| Sil.Aeq (Sil.BinOp (Sil.Lt, e1, e2), Sil.Const (Const.Cint i)) when IntLit.isone i ->
| Sil.Aeq (Sil.BinOp (Binop.Lt, e1, e2), Sil.Const (Const.Cint i)) when IntLit.isone i ->
lts := (e1, e2) :: !lts (* < *)
| Sil.Aeq _ -> () in
IList.iter process_atom pi;
@ -415,7 +417,7 @@ end = struct
(* L.d_str "check_le "; Sil.d_exp e1; L.d_str " "; Sil.d_exp e2; L.d_ln (); *)
match e1, e2 with
| Sil.Const (Const.Cint n1), Sil.Const (Const.Cint n2) -> IntLit.leq n1 n2
| Sil.BinOp (Sil.MinusA, Sil.Sizeof (t1, None, _), Sil.Sizeof (t2, None, _)),
| Sil.BinOp (Binop.MinusA, Sil.Sizeof (t1, None, _), Sil.Sizeof (t2, None, _)),
Sil.Const(Const.Cint n2)
when IntLit.isminusone n2 && type_size_comparable t1 t2 ->
(* [ sizeof(t1) - sizeof(t2) <= -1 ] *)
@ -502,15 +504,15 @@ end = struct
Format.fprintf fmt "%a %a %a" (pp_seq pp_leq) leqs (pp_seq pp_lt) lts (pp_seq pp_neq) neqs
let d_leqs { leqs = leqs; lts = lts; neqs = neqs } =
let elist = IList.map (fun (e1, e2) -> Sil.BinOp(Sil.Le, e1, e2)) leqs in
let elist = IList.map (fun (e1, e2) -> Sil.BinOp(Binop.Le, e1, e2)) leqs in
Sil.d_exp_list elist
let d_lts { leqs = leqs; lts = lts; neqs = neqs } =
let elist = IList.map (fun (e1, e2) -> Sil.BinOp(Sil.Lt, e1, e2)) lts in
let elist = IList.map (fun (e1, e2) -> Sil.BinOp(Binop.Lt, e1, e2)) lts in
Sil.d_exp_list elist
let d_neqs { leqs = leqs; lts = lts; neqs = neqs } =
let elist = IList.map (fun (e1, e2) -> Sil.BinOp(Sil.Ne, e1, e2)) lts in
let elist = IList.map (fun (e1, e2) -> Sil.BinOp(Binop.Ne, e1, e2)) lts in
Sil.d_exp_list elist
*)
end
@ -524,8 +526,8 @@ let check_equal prop e1 e2 =
Sil.exp_equal n_e1 n_e2 in
let check_equal_const () =
match n_e1, n_e2 with
| Sil.BinOp (Sil.PlusA, e1, Sil.Const (Const.Cint d)), e2
| e2, Sil.BinOp (Sil.PlusA, e1, Sil.Const (Const.Cint d)) ->
| Sil.BinOp (Binop.PlusA, e1, Sil.Const (Const.Cint d)), e2
| e2, Sil.BinOp (Binop.PlusA, e1, Sil.Const (Const.Cint d)) ->
if Sil.exp_equal e1 e2 then IntLit.iszero d
else false
| Sil.Const c1, Sil.Lindex(Sil.Const c2, Sil.Const (Const.Cint i)) when IntLit.iszero i ->
@ -565,9 +567,9 @@ let is_root prop base_exp exp =
let get_bounds prop _e =
let e_norm = Prop.exp_normalize_prop prop _e in
let e_root, off = match e_norm with
| Sil.BinOp (Sil.PlusA, e, Sil.Const (Const.Cint n1)) ->
| Sil.BinOp (Binop.PlusA, e, Sil.Const (Const.Cint n1)) ->
e, IntLit.neg n1
| Sil.BinOp (Sil.MinusA, e, Sil.Const (Const.Cint n1)) ->
| Sil.BinOp (Binop.MinusA, e, Sil.Const (Const.Cint n1)) ->
e, n1
| _ ->
e_norm, IntLit.zero in
@ -592,12 +594,12 @@ let check_disequal prop e1 e2 =
if IntLit.iszero d
then not (Const.equal c1 c2) (* offset=0 is no offset *)
else Const.equal c1 c2 (* same base, different offsets *)
| Sil.BinOp (Sil.PlusA, e1, Sil.Const (Const.Cint d1)),
Sil.BinOp (Sil.PlusA, e2, Sil.Const (Const.Cint d2)) ->
| Sil.BinOp (Binop.PlusA, e1, Sil.Const (Const.Cint d1)),
Sil.BinOp (Binop.PlusA, e2, Sil.Const (Const.Cint d2)) ->
if Sil.exp_equal e1 e2 then IntLit.neq d1 d2
else false
| Sil.BinOp (Sil.PlusA, e1, Sil.Const (Const.Cint d)), e2
| e2, Sil.BinOp (Sil.PlusA, e1, Sil.Const (Const.Cint d)) ->
| Sil.BinOp (Binop.PlusA, e1, Sil.Const (Const.Cint d)), e2
| e2, Sil.BinOp (Binop.PlusA, e1, Sil.Const (Const.Cint d)) ->
if Sil.exp_equal e1 e2 then not (IntLit.iszero d)
else false
| Sil.Lindex(Sil.Const c1, Sil.Const (Const.Cint d)), Sil.Const c2 ->
@ -675,7 +677,7 @@ let check_disequal prop e1 e2 =
let check_le_normalized prop e1 e2 =
(* L.d_str "check_le_normalized "; Sil.d_exp e1; L.d_str " "; Sil.d_exp e2; L.d_ln (); *)
let eL, eR, off = match e1, e2 with
| Sil.BinOp(Sil.MinusA, f1, f2), Sil.Const (Const.Cint n) ->
| Sil.BinOp(Binop.MinusA, f1, f2), Sil.Const (Const.Cint n) ->
if Sil.exp_equal f1 f2
then Sil.exp_zero, Sil.exp_zero, n
else f1, f2, n
@ -732,16 +734,16 @@ let check_atom prop a0 =
close_out outc;
end;
match a with
| Sil.Aeq (Sil.BinOp (Sil.Le, e1, e2), Sil.Const (Const.Cint i))
| Sil.Aeq (Sil.BinOp (Binop.Le, e1, e2), Sil.Const (Const.Cint i))
when IntLit.isone i -> check_le_normalized prop e1 e2
| Sil.Aeq (Sil.BinOp (Sil.Lt, e1, e2), Sil.Const (Const.Cint i))
| Sil.Aeq (Sil.BinOp (Binop.Lt, e1, e2), Sil.Const (Const.Cint i))
when IntLit.isone i -> check_lt_normalized prop e1 e2
| Sil.Aeq (e1, e2) -> check_equal prop e1 e2
| Sil.Aneq (e1, e2) -> check_disequal prop e1 e2
(** Check [prop |- e1<=e2]. Result [false] means "don't know". *)
let check_le prop e1 e2 =
let e1_le_e2 = Sil.BinOp (Sil.Le, e1, e2) in
let e1_le_e2 = Sil.BinOp (Binop.Le, e1, e2) in
check_atom prop (Prop.mk_inequality e1_le_e2)
(** Check whether [prop |- allocated(e)]. *)
@ -1144,9 +1146,10 @@ let exp_imply calc_missing subs e1_in e2_in : subst2 =
(fst subs, sub2')
else
raise (IMPL_EXC ("expressions not equal", subs, (EXC_FALSE_EXPS (e1, e2))))
| e1, Sil.BinOp (Sil.PlusA, Sil.Var v2, e2)
| e1, Sil.BinOp (Sil.PlusA, e2, Sil.Var v2) when Ident.is_primed v2 || Ident.is_footprint v2 ->
let e' = Sil.BinOp (Sil.MinusA, e1, e2) in
| e1, Sil.BinOp (Binop.PlusA, Sil.Var v2, e2)
| e1, Sil.BinOp (Binop.PlusA, e2, Sil.Var v2)
when Ident.is_primed v2 || Ident.is_footprint v2 ->
let e' = Sil.BinOp (Binop.MinusA, e1, e2) in
do_imply subs (Prop.exp_normalize_noabs Sil.sub_empty e') (Sil.Var v2)
| Sil.Var _, e2 ->
if calc_missing then
@ -1164,16 +1167,16 @@ let exp_imply calc_missing subs e1_in e2_in : subst2 =
| Sil.Const c1, Sil.Const c2 ->
if (Const.equal c1 c2) then subs
else raise (IMPL_EXC ("constants not equal", subs, (EXC_FALSE_EXPS (e1, e2))))
| Sil.Const (Const.Cint _), Sil.BinOp (Sil.PlusPI, _, _) ->
| Sil.Const (Const.Cint _), Sil.BinOp (Binop.PlusPI, _, _) ->
raise (IMPL_EXC ("pointer+index cannot evaluate to a constant", subs, (EXC_FALSE_EXPS (e1, e2))))
| Sil.Const (Const.Cint n1), Sil.BinOp (Sil.PlusA, f1, Sil.Const (Const.Cint n2)) ->
| Sil.Const (Const.Cint n1), Sil.BinOp (Binop.PlusA, f1, Sil.Const (Const.Cint n2)) ->
do_imply subs (Sil.exp_int (n1 -- n2)) f1
| Sil.BinOp(op1, e1, f1), Sil.BinOp(op2, e2, f2) when op1 == op2 ->
do_imply (do_imply subs e1 e2) f1 f2
| Sil.BinOp (Sil.PlusA, Sil.Var v1, e1), e2 ->
do_imply subs (Sil.Var v1) (Sil.BinOp (Sil.MinusA, e2, e1))
| Sil.BinOp (Sil.PlusPI, Sil.Lvar pv1, e1), e2 ->
do_imply subs (Sil.Lvar pv1) (Sil.BinOp (Sil.MinusA, e2, e1))
| Sil.BinOp (Binop.PlusA, Sil.Var v1, e1), e2 ->
do_imply subs (Sil.Var v1) (Sil.BinOp (Binop.MinusA, e2, e1))
| Sil.BinOp (Binop.PlusPI, Sil.Lvar pv1, e1), e2 ->
do_imply subs (Sil.Lvar pv1) (Sil.BinOp (Binop.MinusA, e2, e1))
| e1, Sil.Const _ ->
raise (IMPL_EXC ("lhs not constant", subs, (EXC_FALSE_EXPS (e1, e2))))
| Sil.Lfield(e1, fd1, _), Sil.Lfield(e2, fd2, _) when fd1 == fd2 ->
@ -1221,9 +1224,9 @@ let path_to_id path =
let array_len_imply calc_missing subs len1 len2 indices2 =
match len1, len2 with
| _, Sil.Var _
| _, Sil.BinOp (Sil.PlusA, Sil.Var _, _)
| _, Sil.BinOp (Sil.PlusA, _, Sil.Var _)
| Sil.BinOp (Sil.Mult, _, _), _ ->
| _, Sil.BinOp (Binop.PlusA, Sil.Var _, _)
| _, Sil.BinOp (Binop.PlusA, _, Sil.Var _)
| Sil.BinOp (Binop.Mult, _, _), _ ->
(try exp_imply calc_missing subs len1 len2 with
| IMPL_EXC (s, subs', x) ->
raise (IMPL_EXC ("array len:" ^ s, subs', x)))
@ -1403,7 +1406,7 @@ let hpred_has_primed_lhs sub hpred =
find_primed e
| Sil.Lindex (e, _) ->
find_primed e
| Sil.BinOp (Sil.PlusPI, e1, _) ->
| Sil.BinOp (Binop.PlusPI, e1, _) ->
find_primed e1
| _ ->
Sil.fav_exists (Sil.exp_fav e) Ident.is_primed in
@ -1459,8 +1462,8 @@ let expand_hpred_pointer calc_index_frame hpred : bool * bool * Sil.hpred =
| _ -> Sil.exp_get_undefined false in
let hpred' = Sil.Hpointsto (e, Sil.Earray (len, [(ind, se)], Sil.inst_none), t') in
expand true true hpred'
| Sil.Hpointsto (Sil.BinOp (Sil.PlusPI, e1, e2), Sil.Earray (len, esel, inst), t) ->
let shift_exp e = Sil.BinOp (Sil.PlusA, e, e2) in
| Sil.Hpointsto (Sil.BinOp (Binop.PlusPI, e1, e2), Sil.Earray (len, esel, inst), t) ->
let shift_exp e = Sil.BinOp (Binop.PlusA, e, e2) in
let len' = shift_exp len in
let esel' = IList.map (fun (e, se) -> (shift_exp e, se)) esel in
let hpred' = Sil.Hpointsto (e1, Sil.Earray (len', esel', inst), t) in
@ -2117,7 +2120,7 @@ let check_array_bounds (sub1, sub2) prop =
if (not Config.bound_error_allowed_in_procedure_call) then
raise (IMPL_EXC ("bounds check", (sub1, sub2), EXC_FALSE)) in
let fail_if_le e' e'' =
let lt_ineq = Prop.mk_inequality (Sil.BinOp(Sil.Le, e', e'')) in
let lt_ineq = Prop.mk_inequality (Sil.BinOp(Binop.Le, e', e'')) in
if check_atom prop lt_ineq then check_failed lt_ineq in
let check_bound = function
| ProverState.BClen_imply (len1_, len2_, _indices2) ->
@ -2126,7 +2129,7 @@ let check_array_bounds (sub1, sub2) prop =
(* L.d_strln_color Orange "check_bound ";
Sil.d_exp len1; L.d_str " "; Sil.d_exp len2; L.d_ln(); *)
let indices_to_check = match len2 with
| _ -> [Sil.BinOp(Sil.PlusA, len2, Sil.exp_minus_one)] (* only check len *) in
| _ -> [Sil.BinOp(Binop.PlusA, len2, Sil.exp_minus_one)] (* only check len *) in
IList.iter (fail_if_le len1) indices_to_check
| ProverState.BCfrom_pre _atom ->
let atom_neg = Prop.atom_negate (Sil.atom_sub sub2 _atom) in
@ -2256,7 +2259,7 @@ let find_minimum_pure_cover cases =
(*
(** Check [prop |- e1<e2]. Result [false] means "don't know". *)
let check_lt prop e1 e2 =
let e1_lt_e2 = Sil.BinOp (Sil.Lt, e1, e2) in
let e1_lt_e2 = Sil.BinOp (Binop.Lt, e1, e2) in
check_atom prop (Prop.mk_inequality e1_lt_e2)
let filter_ptsto_lhs sub e0 = function

@ -37,13 +37,13 @@ let check_bad_index pname p len index loc =
| Sil.Const _ -> true
| _ -> false in
let index_provably_out_of_bound () =
let index_too_large = Prop.mk_inequality (Sil.BinOp (Sil.Le, len, index)) in
let index_negative = Prop.mk_inequality (Sil.BinOp (Sil.Le, index, Sil.exp_minus_one)) in
let index_too_large = Prop.mk_inequality (Sil.BinOp (Binop.Le, len, index)) in
let index_negative = Prop.mk_inequality (Sil.BinOp (Binop.Le, index, Sil.exp_minus_one)) in
(Prover.check_atom p index_too_large) || (Prover.check_atom p index_negative) in
let index_provably_in_bound () =
let len_minus_one = Sil.BinOp(Sil.PlusA, len, Sil.exp_minus_one) in
let index_not_too_large = Prop.mk_inequality (Sil.BinOp(Sil.Le, index, len_minus_one)) in
let index_nonnegative = Prop.mk_inequality (Sil.BinOp(Sil.Le, Sil.exp_zero, index)) in
let len_minus_one = Sil.BinOp(Binop.PlusA, len, Sil.exp_minus_one) in
let index_not_too_large = Prop.mk_inequality (Sil.BinOp(Binop.Le, index, len_minus_one)) in
let index_nonnegative = Prop.mk_inequality (Sil.BinOp(Binop.Le, Sil.exp_zero, index)) in
Prover.check_zero index || (* index 0 always in bound, even when we know nothing about len *)
((Prover.check_atom p index_not_too_large) && (Prover.check_atom p index_nonnegative)) in
let index_has_bounds () =
@ -1202,7 +1202,7 @@ let check_dereference_error pdesc (prop : Prop.normal Prop.t) lexp loc =
| Some att -> Some att
| None -> (* try to remove an offset if any, and find the attribute there *)
let root_no_offset = match root with
| Sil.BinOp((Sil.PlusPI | Sil.PlusA | Sil.MinusPI | Sil.MinusA), base, _) -> base
| Sil.BinOp((Binop.PlusPI | Binop.PlusA | Binop.MinusPI | Binop.MinusA), base, _) -> base
| _ -> root in
get_relevant_attributes root_no_offset in
if Prover.check_zero (Sil.root_of_lexp root) || is_deref_of_nullable then
@ -1315,7 +1315,7 @@ let rearrange ?(report_deref_errors=true) pdesc tenv lexp typ prop loc
: (Sil.offset list) Prop.prop_iter list =
let nlexp = match Prop.exp_normalize_prop prop lexp with
| Sil.BinOp(Sil.PlusPI, ep, e) -> (* array access with pointer arithmetic *)
| Sil.BinOp(Binop.PlusPI, ep, e) -> (* array access with pointer arithmetic *)
Sil.Lindex(ep, e)
| e -> e in
let ptr_tested_for_zero =

@ -296,10 +296,10 @@ let prune_ineq ~is_strict ~positive prop e1 e2 =
(* build the pruning condition and its negation, as explained in
the comment above *)
(* build [e1] CMP [e2] *)
let cmp = if is_strict then Sil.Lt else Sil.Le in
let cmp = if is_strict then Binop.Lt else Binop.Le in
let e1_cmp_e2 = Sil.BinOp (cmp, e1, e2) in
(* build !([e1] CMP [e2]) *)
let dual_cmp = if is_strict then Sil.Le else Sil.Lt in
let dual_cmp = if is_strict then Binop.Le else Binop.Lt in
let not_e1_cmp_e2 = Sil.BinOp (dual_cmp, e2, e1) in
(* take polarity into account *)
let (prune_cond, not_prune_cond) =
@ -328,24 +328,26 @@ let rec prune ~positive condition prop =
prune ~positive:(not positive) condition' prop
| Sil.UnOp _ ->
assert false
| Sil.BinOp (Sil.Eq, e, Sil.Const (Const.Cint i))
| Sil.BinOp (Sil.Eq, Sil.Const (Const.Cint i), e) when IntLit.iszero i && not (IntLit.isnull i) ->
| Sil.BinOp (Binop.Eq, e, Sil.Const (Const.Cint i))
| Sil.BinOp (Binop.Eq, Sil.Const (Const.Cint i), e)
when IntLit.iszero i && not (IntLit.isnull i) ->
prune ~positive:(not positive) e prop
| Sil.BinOp (Sil.Eq, e1, e2) ->
| Sil.BinOp (Binop.Eq, e1, e2) ->
prune_ne ~positive:(not positive) e1 e2 prop
| Sil.BinOp (Sil.Ne, e, Sil.Const (Const.Cint i))
| Sil.BinOp (Sil.Ne, Sil.Const (Const.Cint i), e) when IntLit.iszero i && not (IntLit.isnull i) ->
| Sil.BinOp (Binop.Ne, e, Sil.Const (Const.Cint i))
| Sil.BinOp (Binop.Ne, Sil.Const (Const.Cint i), e)
when IntLit.iszero i && not (IntLit.isnull i) ->
prune ~positive e prop
| Sil.BinOp (Sil.Ne, e1, e2) ->
| Sil.BinOp (Binop.Ne, e1, e2) ->
prune_ne ~positive e1 e2 prop
| Sil.BinOp (Sil.Ge, e2, e1) | Sil.BinOp (Sil.Le, e1, e2) ->
| Sil.BinOp (Binop.Ge, e2, e1) | Sil.BinOp (Binop.Le, e1, e2) ->
prune_ineq ~is_strict:false ~positive prop e1 e2
| Sil.BinOp (Sil.Gt, e2, e1) | Sil.BinOp (Sil.Lt, e1, e2) ->
| Sil.BinOp (Binop.Gt, e2, e1) | Sil.BinOp (Binop.Lt, e1, e2) ->
prune_ineq ~is_strict:true ~positive prop e1 e2
| Sil.BinOp (Sil.LAnd, condition1, condition2) ->
| Sil.BinOp (Binop.LAnd, condition1, condition2) ->
let pruner = if positive then prune_inter else prune_union in
pruner ~positive condition1 condition2 prop
| Sil.BinOp (Sil.LOr, condition1, condition2) ->
| Sil.BinOp (Binop.LOr, condition1, condition2) ->
let pruner = if positive then prune_union else prune_inter in
pruner ~positive condition1 condition2 prop
| Sil.BinOp _ | Sil.Lfield _ | Sil.Lindex _ ->
@ -403,7 +405,7 @@ let check_constant_string_dereference lexp =
let c = try Char.code (String.get s (IntLit.to_int n)) with Invalid_argument _ -> 0 in
Sil.exp_int (IntLit.of_int c) in
match lexp with
| Sil.BinOp(Sil.PlusPI, Sil.Const (Const.Cstr s), e)
| Sil.BinOp(Binop.PlusPI, Sil.Const (Const.Cstr s), e)
| Sil.Lindex (Sil.Const (Const.Cstr s), e) ->
let value = match e with
| Sil.Const (Const.Cint n)
@ -447,8 +449,8 @@ let check_already_dereferenced pname cond prop =
Some id
| Sil.UnOp(Unop.LNot, e, _) ->
is_check_zero e
| Sil.BinOp ((Sil.Eq | Sil.Ne), Sil.Const Const.Cint i, Sil.Var id)
| Sil.BinOp ((Sil.Eq | Sil.Ne), Sil.Var id, Sil.Const Const.Cint i) when IntLit.iszero i ->
| Sil.BinOp ((Binop.Eq | Binop.Ne), Sil.Const Const.Cint i, Sil.Var id)
| Sil.BinOp ((Binop.Eq | Binop.Ne), Sil.Var id, Sil.Const Const.Cint i) when IntLit.iszero i ->
Some id
| _ -> None in
let dereferenced_line = match is_check_zero cond with
@ -1069,7 +1071,7 @@ let rec sym_exec tenv current_pdesc _instr (prop_: Prop.normal Prop.t) path
Exceptions.Condition_always_true_false (desc, not (IntLit.iszero i), __POS__) in
let pre_opt = State.get_normalized_pre (Abs.abstract_no_symop current_pname) in
Reporting.log_warning current_pname ~pre: pre_opt exn
| Sil.BinOp ((Sil.Eq | Sil.Ne), lhs, rhs)
| Sil.BinOp ((Binop.Eq | Binop.Ne), lhs, rhs)
when true_branch && !Config.footprint && not (is_comparison_to_nil rhs) ->
(* iOS: check that NSNumber *'s are not used in conditionals without comparing to nil *)
let lhs_normal = Prop.exp_normalize_prop prop__ lhs in

@ -288,10 +288,10 @@ module TransferFunctions (CFG : ProcCfg.S) = struct
| _ -> false
let prunes_tracking_var astate = function
| Sil.BinOp (Sil.Eq, lhs, rhs)
| Sil.BinOp (Binop.Eq, lhs, rhs)
when is_tracking_exp astate lhs ->
Sil.exp_equal rhs Sil.exp_one
| Sil.UnOp (Unop.LNot, Sil.BinOp (Sil.Eq, lhs, rhs), _)
| Sil.UnOp (Unop.LNot, Sil.BinOp (Binop.Eq, lhs, rhs), _)
when is_tracking_exp astate lhs ->
Sil.exp_equal rhs Sil.exp_zero
| _ ->

@ -244,10 +244,10 @@ module BooleanVars = struct
(** Normalize a boolean condition. *)
let normalize_condition cond_e =
match cond_e with
| Sil.UnOp (Unop.LNot, Sil.BinOp (Sil.Eq, e1, e2), _) ->
Sil.BinOp (Sil.Ne, e1, e2)
| Sil.UnOp (Unop.LNot, Sil.BinOp (Sil.Ne, e1, e2), _) ->
Sil.BinOp (Sil.Eq, e1, e2)
| Sil.UnOp (Unop.LNot, Sil.BinOp (Binop.Eq, e1, e2), _) ->
Sil.BinOp (Binop.Ne, e1, e2)
| Sil.UnOp (Unop.LNot, Sil.BinOp (Binop.Ne, e1, e2), _) ->
Sil.BinOp (Binop.Eq, e1, e2)
| _ -> cond_e in
(** Normalize an instruction. *)
@ -258,7 +258,7 @@ module BooleanVars = struct
| instr -> instr in
match normalize_instr instr with
| Sil.Prune (Sil.BinOp (Sil.Eq, _cond_e, Sil.Const (Const.Cint i)), _, _, _)
| Sil.Prune (Sil.BinOp (Binop.Eq, _cond_e, Sil.Const (Const.Cint i)), _, _, _)
when IntLit.iszero i ->
let cond_e = Idenv.expand_expr idenv _cond_e in
let state' = match exp_boolean_var cond_e with
@ -267,7 +267,7 @@ module BooleanVars = struct
State.prune state name false
| None -> state in
state'
| Sil.Prune (Sil.BinOp (Sil.Ne, _cond_e, Sil.Const (Const.Cint i)), _, _, _)
| Sil.Prune (Sil.BinOp (Binop.Ne, _cond_e, Sil.Const (Const.Cint i)), _, _, _)
when IntLit.iszero i ->
let cond_e = Idenv.expand_expr idenv _cond_e in
let state' = match exp_boolean_var cond_e with

@ -118,8 +118,8 @@ module Match = struct
| Some x -> match_elem env x y
let binop_match op1 op2 = match op1, op2 with
| Sil.Eq, "==" -> true
| Sil.Ne, "!=" -> true
| Binop.Eq, "==" -> true
| Binop.Ne, "!=" -> true
| _ -> false
let rec cond_match env idenv cond (ae1, op, ae2) = match cond with
@ -127,10 +127,10 @@ module Match = struct
let e1 = Idenv.expand_expr idenv _e1 in
let e2 = Idenv.expand_expr idenv _e2 in
binop_match bop op && exp_match env ae1 (Vval e1) && exp_match env ae2 (Vval e2)
| Sil.UnOp (Unop.LNot, (Sil.BinOp (Sil.Eq, e1, e2)), _) ->
cond_match env idenv (Sil.BinOp (Sil.Ne, e1, e2)) (ae1, op, ae2)
| Sil.UnOp (Unop.LNot, (Sil.BinOp (Sil.Ne, e1, e2)), _) ->
cond_match env idenv (Sil.BinOp (Sil.Eq, e1, e2)) (ae1, op, ae2)
| Sil.UnOp (Unop.LNot, (Sil.BinOp (Binop.Eq, e1, e2)), _) ->
cond_match env idenv (Sil.BinOp (Binop.Ne, e1, e2)) (ae1, op, ae2)
| Sil.UnOp (Unop.LNot, (Sil.BinOp (Binop.Ne, e1, e2)), _) ->
cond_match env idenv (Sil.BinOp (Binop.Eq, e1, e2)) (ae1, op, ae2)
| _ -> false
(** Iterate over the instructions of the linearly succ nodes. *)

@ -62,34 +62,34 @@ let compound_assignment_binary_operation_instruction boi e1 typ e2 loc =
let instr1 = Sil.Letderef (id, e1, typ, loc) in
let e_res, instr_op = match boi.Clang_ast_t.boi_kind with
| `AddAssign ->
let e1_plus_e2 = Sil.BinOp(Sil.PlusA, Sil.Var id, e2) in
let e1_plus_e2 = Sil.BinOp(Binop.PlusA, Sil.Var id, e2) in
(e1, [Sil.Set (e1, typ, e1_plus_e2, loc)])
| `SubAssign ->
let e1_sub_e2 = Sil.BinOp(Sil.MinusA, Sil.Var id, e2) in
let e1_sub_e2 = Sil.BinOp(Binop.MinusA, Sil.Var id, e2) in
(e1, [Sil.Set (e1, typ, e1_sub_e2, loc)])
| `MulAssign ->
let e1_mul_e2 = Sil.BinOp(Sil.Mult, Sil.Var id, e2) in
let e1_mul_e2 = Sil.BinOp(Binop.Mult, Sil.Var id, e2) in
(e1, [Sil.Set (e1, typ, e1_mul_e2, loc)])
| `DivAssign ->
let e1_div_e2 = Sil.BinOp(Sil.Div, Sil.Var id, e2) in
let e1_div_e2 = Sil.BinOp(Binop.Div, Sil.Var id, e2) in
(e1, [Sil.Set (e1, typ, e1_div_e2, loc)])
| `ShlAssign ->
let e1_shl_e2 = Sil.BinOp(Sil.Shiftlt, Sil.Var id, e2) in
let e1_shl_e2 = Sil.BinOp(Binop.Shiftlt, Sil.Var id, e2) in
(e1, [Sil.Set (e1, typ, e1_shl_e2, loc)])
| `ShrAssign ->
let e1_shr_e2 = Sil.BinOp(Sil.Shiftrt, Sil.Var id, e2) in
let e1_shr_e2 = Sil.BinOp(Binop.Shiftrt, Sil.Var id, e2) in
(e1, [Sil.Set (e1, typ, e1_shr_e2, loc)])
| `RemAssign ->
let e1_mod_e2 = Sil.BinOp(Sil.Mod, Sil.Var id, e2) in
let e1_mod_e2 = Sil.BinOp(Binop.Mod, Sil.Var id, e2) in
(e1, [Sil.Set (e1, typ, e1_mod_e2, loc)])
| `AndAssign ->
let e1_and_e2 = Sil.BinOp(Sil.BAnd, Sil.Var id, e2) in
let e1_and_e2 = Sil.BinOp(Binop.BAnd, Sil.Var id, e2) in
(e1, [Sil.Set (e1, typ, e1_and_e2, loc)])
| `OrAssign ->
let e1_or_e2 = Sil.BinOp(Sil.BOr, Sil.Var id, e2) in
let e1_or_e2 = Sil.BinOp(Binop.BOr, Sil.Var id, e2) in
(e1, [Sil.Set (e1, typ, e1_or_e2, loc)])
| `XorAssign ->
let e1_xor_e2 = Sil.BinOp(Sil.BXor, Sil.Var id, e2) in
let e1_xor_e2 = Sil.BinOp(Binop.BXor, Sil.Var id, e2) in
(e1, [Sil.Set (e1, typ, e1_xor_e2, loc)])
| _ -> assert false in
(e_res, instr1:: instr_op)
@ -101,24 +101,24 @@ let compound_assignment_binary_operation_instruction boi e1 typ e2 loc =
let binary_operation_instruction context boi e1 typ e2 loc rhs_owning_method =
let binop_exp op = Sil.BinOp(op, e1, e2) in
match boi.Clang_ast_t.boi_kind with
| `Add -> (binop_exp (Sil.PlusA), [])
| `Mul -> (binop_exp (Sil.Mult), [])
| `Div -> (binop_exp (Sil.Div), [])
| `Rem -> (binop_exp (Sil.Mod), [])
| `Sub -> (binop_exp (Sil.MinusA), [])
| `Shl -> (binop_exp (Sil.Shiftlt), [])
| `Shr -> (binop_exp(Sil.Shiftrt), [])
| `Or -> (binop_exp (Sil.BOr), [])
| `And -> (binop_exp (Sil.BAnd), [])
| `Xor -> (binop_exp (Sil.BXor), [])
| `LT -> (binop_exp (Sil.Lt), [])
| `GT -> (binop_exp (Sil.Gt), [])
| `LE -> (binop_exp (Sil.Le), [])
| `GE -> (binop_exp (Sil.Ge), [])
| `NE -> (binop_exp (Sil.Ne), [])
| `EQ -> (binop_exp (Sil.Eq), [])
| `LAnd -> (binop_exp (Sil.LAnd), [])
| `LOr -> (binop_exp (Sil.LOr), [])
| `Add -> (binop_exp (Binop.PlusA), [])
| `Mul -> (binop_exp (Binop.Mult), [])
| `Div -> (binop_exp (Binop.Div), [])
| `Rem -> (binop_exp (Binop.Mod), [])
| `Sub -> (binop_exp (Binop.MinusA), [])
| `Shl -> (binop_exp (Binop.Shiftlt), [])
| `Shr -> (binop_exp(Binop.Shiftrt), [])
| `Or -> (binop_exp (Binop.BOr), [])
| `And -> (binop_exp (Binop.BAnd), [])
| `Xor -> (binop_exp (Binop.BXor), [])
| `LT -> (binop_exp (Binop.Lt), [])
| `GT -> (binop_exp (Binop.Gt), [])
| `LE -> (binop_exp (Binop.Le), [])
| `GE -> (binop_exp (Binop.Ge), [])
| `NE -> (binop_exp (Binop.Ne), [])
| `EQ -> (binop_exp (Binop.Eq), [])
| `LAnd -> (binop_exp (Binop.LAnd), [])
| `LOr -> (binop_exp (Binop.LOr), [])
| `Assign ->
if !Config.arc_mode && ObjcInterface_decl.is_pointer_to_objc_class context.CContext.tenv typ then
assignment_arc_mode e1 typ e2 loc rhs_owning_method false
@ -144,12 +144,12 @@ let unary_operation_instruction uoi e typ loc =
| `PostInc ->
let id = Ident.create_fresh Ident.knormal in
let instr1 = Sil.Letderef (id, e, typ, loc) in
let e_plus_1 = Sil.BinOp(Sil.PlusA, Sil.Var id, Sil.Const(Const.Cint (IntLit.one))) in
let e_plus_1 = Sil.BinOp(Binop.PlusA, Sil.Var id, Sil.Const(Const.Cint (IntLit.one))) in
(Sil.Var id, instr1::[Sil.Set (e, typ, e_plus_1, loc)])
| `PreInc ->
let id = Ident.create_fresh Ident.knormal in
let instr1 = Sil.Letderef (id, e, typ, loc) in
let e_plus_1 = Sil.BinOp(Sil.PlusA, Sil.Var id, Sil.Const(Const.Cint (IntLit.one))) in
let e_plus_1 = Sil.BinOp(Binop.PlusA, Sil.Var id, Sil.Const(Const.Cint (IntLit.one))) in
let exp = if General_utils.is_cpp_translation Config.clang_lang then
e
else
@ -158,12 +158,12 @@ let unary_operation_instruction uoi e typ loc =
| `PostDec ->
let id = Ident.create_fresh Ident.knormal in
let instr1 = Sil.Letderef (id, e, typ, loc) in
let e_minus_1 = Sil.BinOp(Sil.MinusA, Sil.Var id, Sil.Const(Const.Cint (IntLit.one))) in
let e_minus_1 = Sil.BinOp(Binop.MinusA, Sil.Var id, Sil.Const(Const.Cint (IntLit.one))) in
(Sil.Var id, instr1::[Sil.Set (e, typ, e_minus_1, loc)])
| `PreDec ->
let id = Ident.create_fresh Ident.knormal in
let instr1 = Sil.Letderef (id, e, typ, loc) in
let e_minus_1 = Sil.BinOp(Sil.MinusA, Sil.Var id, Sil.Const(Const.Cint (IntLit.one))) in
let e_minus_1 = Sil.BinOp(Binop.MinusA, Sil.Var id, Sil.Const(Const.Cint (IntLit.one))) in
let exp = if General_utils.is_cpp_translation Config.clang_lang then
e
else
@ -221,4 +221,4 @@ let sil_const_plus_one const =
match const with
| Sil.Const (Const.Cint n) ->
Sil.Const (Const.Cint (IntLit.add n IntLit.one))
| _ -> Sil.BinOp (Sil.PlusA, const, Sil.Const (Const.Cint (IntLit.one)))
| _ -> Sil.BinOp (Binop.PlusA, const, Sil.Const (Const.Cint (IntLit.one)))

@ -1226,8 +1226,8 @@ struct
(* prune_to_short_c is the prune node that is connected directly with the branch *)
(* where the control flow goes in case of short circuit *)
let prune_to_s2, prune_to_short_c = (match binop with
| Sil.LAnd -> prune_nodes_t, prune_nodes_f
| Sil.LOr -> prune_nodes_f, prune_nodes_t
| Binop.LAnd -> prune_nodes_t, prune_nodes_f
| Binop.LOr -> prune_nodes_f, prune_nodes_t
| _ -> assert false) in
IList.iter
(fun n -> Cfg.Node.set_succs_exn context.cfg n res_trans_s2.root_nodes [])
@ -1250,8 +1250,8 @@ struct
match cond with
| BinaryOperator(_, [s1; s2], _, boi) ->
(match boi.Clang_ast_t.boi_kind with
| `LAnd -> short_circuit (Sil.LAnd) s1 s2
| `LOr -> short_circuit (Sil.LOr) s1 s2
| `LAnd -> short_circuit (Binop.LAnd) s1 s2
| `LOr -> short_circuit (Binop.LOr) s1 s2
| _ -> no_short_circuit_cond ())
| ParenExpr(_,[s], _) -> (* condition can be wrapped in parenthesys *)
cond_trans trans_state s
@ -1400,7 +1400,7 @@ struct
match e_const with
| [(head, _)] -> head
| _ -> assert false in
let sil_eq_cond = Sil.BinOp (Sil.Eq, switch_e_cond', e_const') in
let sil_eq_cond = Sil.BinOp (Binop.Eq, switch_e_cond', e_const') in
let sil_loc = CLocation.get_sil_location stmt_info context in
let true_prune_node =
create_prune_node true [(sil_eq_cond, switch_e_cond'_typ)]

@ -61,9 +61,9 @@ struct
"\nWARNING: Missing expression for Conditional operator. Need to be fixed" in
let e_cond'' =
if branch then
Sil.BinOp(Sil.Ne, e_cond', Sil.exp_zero)
Sil.BinOp(Binop.Ne, e_cond', Sil.exp_zero)
else
Sil.BinOp(Sil.Eq, e_cond', Sil.exp_zero) in
Sil.BinOp(Binop.Eq, e_cond', Sil.exp_zero) in
let instrs_cond'= instrs_cond @ [Sil.Prune(e_cond'', loc, branch, ik)] in
create_node (prune_kind branch) instrs_cond' loc context
@ -298,7 +298,7 @@ let create_alloc_instrs context sil_loc function_type fname size_exp_opt procnam
let function_type_np = CTypes.expand_structured_type context.CContext.tenv function_type_np in
let sizeof_exp_ = Sil.Sizeof (function_type_np, None, Sil.Subtype.exact) in
let sizeof_exp = match size_exp_opt with
| Some exp -> Sil.BinOp (Sil.Mult, sizeof_exp_, exp)
| Some exp -> Sil.BinOp (Binop.Mult, sizeof_exp_, exp)
| None -> sizeof_exp_ in
let exp = (sizeof_exp, Typ.Tint Typ.IULong) in
let procname_arg = match procname_opt with

@ -97,7 +97,7 @@ module ComplexExpressions = struct
| Sil.Ddot (de, f) ->
dexp_to_string de ^ "." ^ Ident.fieldname_to_string f
| Sil.Dbinop (op, de1, de2) ->
"(" ^ dexp_to_string de1 ^ (Sil.str_binop pe_text op) ^ dexp_to_string de2 ^ ")"
"(" ^ dexp_to_string de1 ^ (Binop.str pe_text op) ^ dexp_to_string de2 ^ ")"
| Sil.Dconst (Const.Cfun pn) ->
Procname.to_unique_id pn
| Sil.Dconst c ->
@ -650,7 +650,7 @@ let typecheck_instr
not (TypeAnnotation.origin_is_fun_library ta) in
if checks.eradicate && should_report then
begin
let cond = Sil.BinOp (Sil.Ne, Sil.Lvar pvar, Sil.exp_null) in
let cond = Sil.BinOp (Binop.Ne, Sil.Lvar pvar, Sil.exp_null) in
EradicateChecks.report_error
find_canonical_duplicate
node
@ -704,8 +704,8 @@ let typecheck_instr
let handle_negated_condition cond_node =
let do_instr = function
| Sil.Prune (Sil.BinOp (Sil.Eq, _cond_e, Sil.Const (Const.Cint i)), _, _, _)
| Sil.Prune (Sil.BinOp (Sil.Eq, Sil.Const (Const.Cint i), _cond_e), _, _, _)
| Sil.Prune (Sil.BinOp (Binop.Eq, _cond_e, Sil.Const (Const.Cint i)), _, _, _)
| Sil.Prune (Sil.BinOp (Binop.Eq, Sil.Const (Const.Cint i), _cond_e), _, _, _)
when IntLit.iszero i ->
let cond_e = Idenv.expand_expr_temps idenv cond_node _cond_e in
begin
@ -944,8 +944,8 @@ let typecheck_instr
| _ -> typestate2 in
match c with
| Sil.BinOp (Sil.Eq, Sil.Const (Const.Cint i), e)
| Sil.BinOp (Sil.Eq, e, Sil.Const (Const.Cint i)) when IntLit.iszero i ->
| Sil.BinOp (Binop.Eq, Sil.Const (Const.Cint i), e)
| Sil.BinOp (Binop.Eq, e, Sil.Const (Const.Cint i)) when IntLit.iszero i ->
typecheck_expr_for_errors typestate e loc;
let typestate1, e1, from_call = match from_is_true_on_null e with
| Some e1 ->
@ -973,8 +973,8 @@ let typecheck_instr
typestate2
end
| Sil.BinOp (Sil.Ne, Sil.Const (Const.Cint i), e)
| Sil.BinOp (Sil.Ne, e, Sil.Const (Const.Cint i)) when IntLit.iszero i ->
| Sil.BinOp (Binop.Ne, Sil.Const (Const.Cint i), e)
| Sil.BinOp (Binop.Ne, e, Sil.Const (Const.Cint i)) when IntLit.iszero i ->
typecheck_expr_for_errors typestate e loc;
let typestate1, e1, from_call = match from_instanceof e with
| Some e1 -> (* (e1 instanceof C) implies (e1 != null) *)
@ -1023,10 +1023,10 @@ let typecheck_instr
else typestate2
end
| Sil.UnOp (Unop.LNot, (Sil.BinOp (Sil.Eq, e1, e2)), _) ->
check_condition node' (Sil.BinOp (Sil.Ne, e1, e2))
| Sil.UnOp (Unop.LNot, (Sil.BinOp (Sil.Ne, e1, e2)), _) ->
check_condition node' (Sil.BinOp (Sil.Eq, e1, e2))
| Sil.UnOp (Unop.LNot, (Sil.BinOp (Binop.Eq, e1, e2)), _) ->
check_condition node' (Sil.BinOp (Binop.Ne, e1, e2))
| Sil.UnOp (Unop.LNot, (Sil.BinOp (Binop.Ne, e1, e2)), _) ->
check_condition node' (Sil.BinOp (Binop.Eq, e1, e2))
| _ -> typestate in
(** Handle assigment fron a temp pvar in a condition.

@ -179,23 +179,23 @@ let get_constant (c : JBir.const) =
let get_binop binop =
match binop with
| JBir.Add _ -> Sil.PlusA
| JBir.Sub _ -> Sil.MinusA
| JBir.Mult _ -> Sil.Mult
| JBir.Div _ -> Sil.Div
| JBir.Rem _ -> Sil.Mod
| JBir.IAnd -> Sil.BAnd
| JBir.IShl -> Sil.Shiftlt
| JBir.IShr -> Sil.Shiftrt
| JBir.IOr -> Sil.BOr
| JBir.IXor -> Sil.BXor
| JBir.Add _ -> Binop.PlusA
| JBir.Sub _ -> Binop.MinusA
| JBir.Mult _ -> Binop.Mult
| JBir.Div _ -> Binop.Div
| JBir.Rem _ -> Binop.Mod
| JBir.IAnd -> Binop.BAnd
| JBir.IShl -> Binop.Shiftlt
| JBir.IShr -> Binop.Shiftrt
| JBir.IOr -> Binop.BOr
| JBir.IXor -> Binop.BXor
| JBir.IUshr ->
raise (Frontend_error "Unsigned right shift operator")
| JBir.LShl -> Sil.Shiftlt
| JBir.LShr -> Sil.Shiftrt
| JBir.LAnd -> Sil.BAnd
| JBir.LOr -> Sil.BOr
| JBir.LXor -> Sil.BXor
| JBir.LShl -> Binop.Shiftlt
| JBir.LShr -> Binop.Shiftrt
| JBir.LAnd -> Binop.BAnd
| JBir.LOr -> Binop.BOr
| JBir.LXor -> Binop.BXor
| JBir.LUshr ->
raise (Frontend_error "Unsigned right shift operator")
| JBir.CMP _ ->
@ -205,12 +205,12 @@ let get_binop binop =
let get_test_operator op =
match op with
| `Eq -> Sil.Eq
| `Ge -> Sil.Ge
| `Gt -> Sil.Gt
| `Le -> Sil.Le
| `Lt -> Sil.Lt
| `Ne -> Sil.Ne
| `Eq -> Binop.Eq
| `Ge -> Binop.Ge
| `Gt -> Binop.Gt
| `Le -> Binop.Le
| `Lt -> Binop.Lt
| `Ne -> Binop.Ne
type defined_status =
| Defined of Cfg.Procdesc.t
@ -762,7 +762,7 @@ let is_this expr =
let assume_not_null loc sil_expr =
let builtin_infer_assume = Sil.Const (Const.Cfun ModelBuiltins.__infer_assume) in
let not_null_expr =
Sil.BinOp (Sil.Ne, sil_expr, Sil.exp_null) in
Sil.BinOp (Binop.Ne, sil_expr, Sil.exp_null) in
let assume_call_flag = { Sil.cf_default with Sil.cf_noreturn = true; } in
let call_args = [(not_null_expr, Typ.Tint Typ.IBool)] in
Sil.Call ([], builtin_infer_assume, call_args, loc, assume_call_flag)
@ -1003,12 +1003,12 @@ let rec instruction context pc instr : translation =
| JBir.Check (JBir.CheckNullPointer expr) when Config.report_runtime_exceptions ->
let (instrs, sil_expr, _) = expression context pc expr in
let not_null_node =
let sil_not_null = Sil.BinOp (Sil.Ne, sil_expr, Sil.exp_null) in
let sil_not_null = Sil.BinOp (Binop.Ne, sil_expr, Sil.exp_null) in
let sil_prune_not_null = Sil.Prune (sil_not_null, loc, true, Sil.Ik_if)
and not_null_kind = Cfg.Node.Prune_node (true, Sil.Ik_if, "Not null") in
create_node not_null_kind (instrs @ [sil_prune_not_null]) in
let throw_npe_node =
let sil_is_null = Sil.BinOp (Sil.Eq, sil_expr, Sil.exp_null) in
let sil_is_null = Sil.BinOp (Binop.Eq, sil_expr, Sil.exp_null) in
let sil_prune_null = Sil.Prune (sil_is_null, loc, true, Sil.Ik_if)
and npe_kind = Cfg.Node.Stmt_node "Throw NPE"
and npe_cn = JBasics.make_cn JConfig.npe_cl in
@ -1046,10 +1046,10 @@ let rec instruction context pc instr : translation =
let sil_assume_in_bound =
let sil_in_bound =
let sil_positive_index =
Sil.BinOp (Sil.Ge, sil_index_expr, Sil.Const (Const.Cint IntLit.zero))
Sil.BinOp (Binop.Ge, sil_index_expr, Sil.Const (Const.Cint IntLit.zero))
and sil_less_than_length =
Sil.BinOp (Sil.Lt, sil_index_expr, sil_length_expr) in
Sil.BinOp (Sil.LAnd, sil_positive_index, sil_less_than_length) in
Sil.BinOp (Binop.Lt, sil_index_expr, sil_length_expr) in
Sil.BinOp (Binop.LAnd, sil_positive_index, sil_less_than_length) in
Sil.Prune (sil_in_bound, loc, true, Sil.Ik_if) in
create_node in_bound_node_kind (instrs @ [sil_assume_in_bound])
@ -1059,10 +1059,10 @@ let rec instruction context pc instr : translation =
let sil_assume_out_of_bound =
let sil_out_of_bound =
let sil_negative_index =
Sil.BinOp (Sil.Lt, sil_index_expr, Sil.Const (Const.Cint IntLit.zero))
Sil.BinOp (Binop.Lt, sil_index_expr, Sil.Const (Const.Cint IntLit.zero))
and sil_greater_than_length =
Sil.BinOp (Sil.Gt, sil_index_expr, sil_length_expr) in
Sil.BinOp (Sil.LOr, sil_negative_index, sil_greater_than_length) in
Sil.BinOp (Binop.Gt, sil_index_expr, sil_length_expr) in
Sil.BinOp (Binop.LOr, sil_negative_index, sil_greater_than_length) in
Sil.Prune (sil_out_of_bound, loc, true, Sil.Ik_if) in
let out_of_bound_cn = JBasics.make_cn JConfig.out_of_bound_cl in
let class_type = JTransType.get_class_type program tenv out_of_bound_cn
@ -1095,12 +1095,12 @@ let rec instruction context pc instr : translation =
let call = Sil.Call([ret_id], check_cast, args, loc, Sil.cf_default) in
let res_ex = Sil.Var ret_id in
let is_instance_node =
let check_is_false = Sil.BinOp (Sil.Ne, res_ex, Sil.exp_zero) in
let check_is_false = Sil.BinOp (Binop.Ne, res_ex, Sil.exp_zero) in
let asssume_instance_of = Sil.Prune (check_is_false, loc, true, Sil.Ik_if)
and instance_of_kind = Cfg.Node.Prune_node (true, Sil.Ik_if, "Is instance") in
create_node instance_of_kind (instrs @ [call; asssume_instance_of])
and throw_cast_exception_node =
let check_is_true = Sil.BinOp (Sil.Ne, res_ex, Sil.exp_one) in
let check_is_true = Sil.BinOp (Binop.Ne, res_ex, Sil.exp_one) in
let asssume_not_instance_of = Sil.Prune (check_is_true, loc, true, Sil.Ik_if)
and throw_cast_exception_kind = Cfg.Node.Stmt_node "Class cast exception"
and cce_cn = JBasics.make_cn JConfig.cce_cl in

Loading…
Cancel
Save