[inferbo] Revert external relational domains (apron, elina)

Summary:
Inferbo does not use the external relational domains, apron and elina.  At some point, the parts of
inferbo using them were broken and they do not seem to be fixed easily in the near future.  Let's
remove them and keep the code base cleaner.

Reviewed By: jvillard

Differential Revision: D19022905

fbshipit-source-id: e0eafe79f
master
Sungkeun Cho 5 years ago committed by Facebook Github Bot
parent ada1d6f3c7
commit 387ef518f9

@ -25,13 +25,12 @@ is required to compile everything from source.
- Xcode >= 6.1 (only needed for the C/Objective-C analysis)
- autoconf >= 2.63 and automake >= 1.11.1 (if building from git)
- gmp
- mpfr
You can install some of these dependencies using
[Homebrew](http://brew.sh/):
```sh
brew install autoconf automake cmake opam pkg-config sqlite gmp mpfr
brew install autoconf automake cmake opam pkg-config sqlite gmp
brew cask install java
```

@ -695,73 +695,6 @@ else
endif
endif
# install dynamic libraries
# use this if you want to distribute infer binaries
install-with-libs: install
test -d '$(DESTDIR)$(libdir)'/infer/infer/libso || \
$(MKDIR_P) '$(DESTDIR)$(libdir)'/infer/infer/libso
ifneq ($(OPAM),no)
set -x; \
OPAM_SHARE=$$($(OPAM) config var share); \
APRON_LIB_PATHS="$$OPAM_SHARE/apron/lib/libapron.so $$OPAM_SHARE/apron/lib/liboctMPQ.so"; \
ELINA_LIB_PATHS="$$OPAM_SHARE/elina/lib/libelinalinearize.so $$OPAM_SHARE/elina/lib/liboptpoly.so $$OPAM_SHARE/elina/lib/libpartitions.so"; \
$(INSTALL_PROGRAM) -C $$APRON_LIB_PATHS '$(DESTDIR)$(libdir)'/infer/infer/libso/; \
$(INSTALL_PROGRAM) -C $$ELINA_LIB_PATHS '$(DESTDIR)$(libdir)'/infer/infer/libso/
ifneq ($(LDD),no)
ifneq ($(PATCHELF),no)
# this sort of assumes Linux
# figure out where libgmp and libmpfr are using ldd
set -x; \
for lib in $$($(LDD) $(INFER_BIN) \
| cut -d ' ' -f 3 \
| grep -e 'lib\(gmp\|mpfr\)'); do \
$(INSTALL_PROGRAM) -C "$$lib" '$(DESTDIR)$(libdir)'/infer/infer/libso/; \
done
# update rpath of executables
for sofile in '$(DESTDIR)$(libdir)'/infer/infer/libso/*.so; do \
$(PATCHELF) --set-rpath '$$ORIGIN' --force-rpath "$$sofile"; \
done
$(PATCHELF) --set-rpath '$$ORIGIN/../libso' --force-rpath '$(DESTDIR)$(libdir)'/infer/infer/bin/infer
ifeq ($(IS_FACEBOOK_TREE),yes)
$(PATCHELF) --set-rpath '$$ORIGIN/../libso' --force-rpath '$(DESTDIR)$(libdir)'/infer/infer/bin/InferCreateTraceViewLinks
endif
else # ldd found but not patchelf
echo "ERROR: ldd (Linux?) found but not patchelf, please install patchelf" >&2; exit 1
endif
else # ldd not found
ifneq ($(OTOOL),no)
ifneq ($(INSTALL_NAME_TOOL),no)
# this sort of assumes osx
# figure out where libgmp and libmpfr are using otool
set -e; \
set -x; \
for lib in $$($(OTOOL) -L $(INFER_BIN) \
| cut -d ' ' -f 1 | tr -d '\t' \
| grep -e 'lib\(gmp\|mpfr\)'); do \
$(INSTALL_PROGRAM) -C "$$lib" '$(DESTDIR)$(libdir)'/infer/infer/libso/; \
done
set -x; \
for sofile in '$(DESTDIR)$(libdir)'/infer/infer/libso/*.{so,dylib}; do \
$(INSTALL_NAME_TOOL) -add_rpath "@executable_path" "$$sofile" 2> /dev/null || true; \
scripts/set_libso_path.sh '$(DESTDIR)$(libdir)'/infer/infer/libso "$$sofile"; \
done
$(INSTALL_NAME_TOOL) -add_rpath '@executable_path/../libso' '$(DESTDIR)$(libdir)'/infer/infer/bin/infer 2> /dev/null || true
scripts/set_libso_path.sh '$(DESTDIR)$(libdir)'/infer/infer/libso '$(DESTDIR)$(libdir)'/infer/infer/bin/infer
ifeq ($(IS_FACEBOOK_TREE),yes)
$(INSTALL_NAME_TOOL) -add_rpath '@executable_path/../libso' '$(DESTDIR)$(libdir)'/infer/infer/bin/InferCreateTraceViewLinks 2> /dev/null || true
scripts/set_libso_path.sh '$(DESTDIR)$(libdir)'/infer/infer/libso '$(DESTDIR)$(libdir)'/infer/infer/bin/InferCreateTraceViewLinks
endif
else # install_name_tool not found
echo "ERROR: otool (OSX?) found but not install_name_tool, please install install_name_tool" >&2; exit 1
endif
else # otool not found
echo "ERROR: need ldd + patchelf (Linux) or otool + install_name_tool (OSX) available" >&2; exit 1
endif
endif # ldd
else # opam
echo "ERROR: need opam" >&2; exit 1
endif
# Nuke objects built from OCaml. Useful when changing the OCaml compiler, for instance.
.PHONY: ocaml_clean
ocaml_clean:

@ -36,13 +36,11 @@ INFER_MINOR = @INFER_MINOR@
INFER_PATCH = @INFER_PATCH@
INSTALL = @INSTALL@
INSTALL_DATA = @INSTALL_DATA@
INSTALL_NAME_TOOL = @INSTALL_NAME_TOOL@
INSTALL_PROGRAM = @INSTALL_PROGRAM@
IS_FACEBOOK_TREE = @IS_FACEBOOK_TREE@
IS_RELEASE_TREE = @IS_RELEASE_TREE@
JAVA_MAJOR_VERSION = @JAVA_MAJOR_VERSION@
JAVAC = @JAVAC@
LDD = @LDD@
LDFLAGS = @LDFLAGS@
libdir = @libdir@
# override in your `make` command to make the install relocatable
@ -68,8 +66,6 @@ OCAMLOPT = @OCAMLOPT@
OPAM = @OPAM@
OPAMROOT = @OPAMROOT@
OPAMSWITCH = @OPAMSWITCH@
OTOOL = @OTOOL@
PATCHELF = @PATCHELF@
PATH = @PATH@
prefix = @prefix@
PYTHON_lxml = @PYTHON_lxml@

@ -400,15 +400,6 @@ AC_SUBST([GNU_SED])
AC_CHECK_TOOL([BREW], [brew], [no])
AC_CHECK_TOOL([INSTALL_NAME_TOOL], [install_name_tool], [no])
AC_SUBST([INSTALL_NAME_TOOL])
AC_CHECK_TOOL([LDD], [ldd], [no])
AC_SUBST([LDD])
AC_CHECK_TOOL([OTOOL], [otool], [no])
AC_SUBST([OTOOL])
AC_CHECK_TOOL([PATCHELF], [patchelf], [no])
AC_SUBST([PATCHELF])
AC_CHECK_INFER_MAN_LAST_MODIFIED()
AC_CONFIG_FILES([

@ -356,10 +356,6 @@ BUCK FLAVORS OPTIONS
BUFFER OVERRUN OPTIONS
--bo-debug int
Debug level for buffer-overrun checker (0-4)
--bo-relational-domain { oct | poly }
Select a relational domain being used in the bufferoverrun checker
(experimental)
CLANG OPTIONS
--annotation-reachability-cxx json
Specify annotation reachability analyses to be performed on

@ -129,10 +129,6 @@ OPTIONS
--bo-debug int
Debug level for buffer-overrun checker (0-4) See also infer-analyze(1).
--bo-relational-domain { oct | poly }
Select a relational domain being used in the bufferoverrun checker
(experimental) See also infer-analyze(1).
--bootclasspath string
Specify the Java bootclasspath See also infer-capture(1).
@ -1188,9 +1184,6 @@ INTERNAL OPTIONS
Activates: Mode for analyzing the biabduction models (Conversely:
--no-biabduction-models-mode)
--bo-relational-domain-reset
Cancel the effect of --bo-relational-domain.
--bootclasspath-reset
Cancel the effect of --bootclasspath.

@ -129,10 +129,6 @@ OPTIONS
--bo-debug int
Debug level for buffer-overrun checker (0-4) See also infer-analyze(1).
--bo-relational-domain { oct | poly }
Select a relational domain being used in the bufferoverrun checker
(experimental) See also infer-analyze(1).
--bootclasspath string
Specify the Java bootclasspath See also infer-capture(1).

@ -851,13 +851,6 @@ and biabduction_model_free_pattern =
"Regex of methods that should be modelled as free if definition is missing"
and bo_relational_domain =
CLOpt.mk_symbol_opt ~long:"bo-relational-domain"
~in_help:InferCommand.[(Analyze, manual_buffer_overrun)]
~symbols:[("oct", `Bo_relational_domain_oct); ("poly", `Bo_relational_domain_poly)]
"Select a relational domain being used in the bufferoverrun checker (experimental)"
and bootclasspath =
CLOpt.mk_string_opt ~long:"bootclasspath"
~in_help:InferCommand.[(Capture, manual_java)]
@ -2756,8 +2749,6 @@ and bootclasspath = !bootclasspath
and bo_debug = !bo_debug
and bo_relational_domain = !bo_relational_domain
and buck = !buck
and buck_blacklist = !buck_blacklist

@ -233,8 +233,6 @@ val biabduction_models_mode : bool
val bo_debug : int
val bo_relational_domain : [`Bo_relational_domain_oct | `Bo_relational_domain_poly] option
val bootclasspath : string option
val buck : bool

@ -65,8 +65,6 @@ module Allocsite = struct
let is_unknown = function Unknown -> true | Symbol _ | Known _ | LiteralString _ -> false
let to_string x = F.asprintf "%a" pp x
let make :
Typ.Procname.t
-> node_hash:int
@ -243,8 +241,6 @@ module Loc = struct
let pp = pp_paren ~paren:false
let to_string x = F.asprintf "%a" pp x
let is_var = function Var _ -> true | _ -> false
let is_c_strlen = function

@ -22,8 +22,6 @@ module Allocsite : sig
include PrettyPrintable.PrintableOrderedType with type t := t
val to_string : t -> string
val unknown : t
val make :
@ -59,8 +57,6 @@ module Loc : sig
include PrettyPrintable.PrintableOrderedType with type t := t
val to_string : t -> string
val of_allocsite : Allocsite.t -> t
val of_c_strlen : t -> t

@ -137,12 +137,6 @@ module TransferFunctions = struct
|> instantiate_latest_prune ~ret_id ~callee_exit_mem eval_sym_trace location
let forget_ret_relation ret callee_pname mem =
let ret_loc = Loc.of_pvar (Pvar.get_ret_pvar callee_pname) in
let ret_var = Loc.of_var (Var.of_id (fst ret)) in
Dom.Mem.relation_forget_locs (PowLoc.add ret_loc (PowLoc.singleton ret_var)) mem
let is_external pname =
match pname with
| Typ.Procname.Java java_pname ->
@ -160,8 +154,7 @@ module TransferFunctions = struct
let instantiate_mem :
Tenv.t
-> Typ.IntegerWidths.t
Typ.IntegerWidths.t
-> Ident.t * Typ.t
-> (Pvar.t * Typ.t) list
-> Typ.Procname.t
@ -170,23 +163,14 @@ module TransferFunctions = struct
-> BufferOverrunAnalysisSummary.t
-> Location.t
-> Dom.Mem.t =
fun tenv integer_type_widths ret callee_formals callee_pname params caller_mem callee_exit_mem
fun integer_type_widths ret callee_formals callee_pname params caller_mem callee_exit_mem
location ->
let eval_sym_trace =
Sem.mk_eval_sym_trace integer_type_widths callee_formals params caller_mem
~mode:Sem.EvalNormal
in
let caller_mem' =
instantiate_mem_reachable ret callee_formals callee_pname ~callee_exit_mem eval_sym_trace
caller_mem location
|> forget_ret_relation ret callee_pname
in
Option.value_map Config.bo_relational_domain ~default:caller_mem' ~f:(fun _ ->
let rel_subst_map =
Sem.get_subst_map tenv integer_type_widths callee_formals params caller_mem
callee_exit_mem
in
Dom.Mem.instantiate_relation rel_subst_map ~caller:caller_mem' ~callee:callee_exit_mem )
let rec is_array_access_exp = function
@ -331,16 +315,6 @@ module TransferFunctions = struct
let v =
Sem.eval integer_type_widths exp2 mem |> Dom.Val.add_assign_trace_elem location locs
in
let mem =
let sym_exps =
Dom.Relation.SymExp.of_exps
~get_int_sym_f:(Sem.get_sym_f integer_type_widths mem)
~get_offset_sym_f:(Sem.get_offset_sym_f integer_type_widths mem)
~get_size_sym_f:(Sem.get_size_sym_f integer_type_widths mem)
exp2
in
Dom.Mem.store_relation locs sym_exps mem
in
let mem = Dom.Mem.update_mem locs v mem in
let mem =
if Language.curr_language_is Clang && Typ.is_char typ then
@ -378,7 +352,7 @@ module TransferFunctions = struct
| None -> (
match get_proc_summary_and_formals callee_pname with
| Some (callee_exit_mem, callee_formals) ->
instantiate_mem tenv integer_type_widths ret callee_formals callee_pname params mem
instantiate_mem integer_type_widths ret callee_formals callee_pname params mem
callee_exit_mem location
| None ->
(* This may happen for procedures with a biabduction model too. *)
@ -417,8 +391,6 @@ module Analyzer = AbstractInterpreter.MakeWTO (TransferFunctions)
type invariant_map = Analyzer.invariant_map
type local_decls = PowLoc.t
type memory_summary = BufferOverrunAnalysisSummary.t
let extract_pre = Analyzer.extract_pre
@ -427,17 +399,6 @@ let extract_post = Analyzer.extract_post
let extract_state = Analyzer.extract_state
let get_local_decls : Procdesc.t -> local_decls =
fun proc_desc ->
let proc_name = Procdesc.get_proc_name proc_desc in
let accum_local_decls acc {ProcAttributes.name} =
let pvar = Pvar.mk name proc_name in
let loc = Loc.of_pvar pvar in
PowLoc.add loc acc
in
Procdesc.get_locals proc_desc |> List.fold ~init:PowLoc.empty ~f:accum_local_decls
let compute_invariant_map :
Summary.t -> Tenv.t -> Typ.IntegerWidths.t -> get_proc_summary_and_formals -> invariant_map =
fun summary tenv integer_type_widths get_proc_summary_and_formals ->
@ -484,16 +445,12 @@ let cached_compute_invariant_map =
inv_map
let compute_summary :
local_decls -> (Pvar.t * Typ.t) list -> CFG.t -> invariant_map -> memory_summary =
fun locals formals cfg inv_map ->
let compute_summary : (Pvar.t * Typ.t) list -> CFG.t -> invariant_map -> memory_summary =
fun formals cfg inv_map ->
let exit_node_id = CFG.exit_node cfg |> CFG.Node.id in
match extract_post exit_node_id inv_map with
| Some exit_mem ->
exit_mem
|> Dom.Mem.forget_unreachable_locs ~formals
|> Dom.Mem.relation_forget_locs locals
|> Dom.Mem.unset_oenv
exit_mem |> Dom.Mem.forget_unreachable_locs ~formals |> Dom.Mem.unset_oenv
| None ->
Bottom
@ -505,8 +462,7 @@ let do_analysis : Callbacks.proc_callback_args -> Summary.t =
let tenv = Exe_env.get_tenv exe_env proc_name in
let integer_type_widths = Exe_env.get_integer_type_widths exe_env proc_name in
let inv_map = cached_compute_invariant_map summary tenv integer_type_widths in
let locals = get_local_decls proc_desc in
let formals = Procdesc.get_pvar_formals proc_desc in
let cfg = CFG.from_pdesc proc_desc in
let payload = compute_summary locals formals cfg inv_map in
let payload = compute_summary formals cfg inv_map in
Payload.update_summary payload summary

@ -8,12 +8,8 @@
open! IStd
module CFG = ProcCfg.NormalOneInstrPerNode
module Payload : SummaryPayload.S with type t = BufferOverrunAnalysisSummary.t
type invariant_map
type local_decls = AbsLoc.PowLoc.t
val cached_compute_invariant_map : Summary.t -> Tenv.t -> Typ.IntegerWidths.t -> invariant_map
val extract_pre : CFG.Node.id -> invariant_map -> BufferOverrunDomain.Mem.t option
@ -23,6 +19,4 @@ val extract_post : CFG.Node.id -> invariant_map -> BufferOverrunDomain.Mem.t opt
val extract_state :
CFG.Node.id -> invariant_map -> BufferOverrunDomain.Mem.t AbstractInterpreter.State.t option
val get_local_decls : Procdesc.t -> local_decls
val do_analysis : Callbacks.proc_callback_t

@ -16,7 +16,6 @@ module F = Format
module L = Logging
module Models = BufferOverrunModels
module PO = BufferOverrunProofObligations
module Relation = BufferOverrunDomainRelation
module Sem = BufferOverrunSemantics
module Trace = BufferOverrunTrace
@ -133,11 +132,8 @@ let check_binop_array_access :
fun integer_type_widths ~is_plus ~e1 ~e2 location mem cond_set ->
let arr = Sem.eval integer_type_widths e1 mem in
let idx = Sem.eval integer_type_widths e2 mem in
let idx_sym_exp = Relation.SymExp.of_exp ~get_sym_f:(Sem.get_sym_f integer_type_widths mem) e2 in
let relation = Dom.Mem.get_relation mem in
let latest_prune = Dom.Mem.get_latest_prune mem in
BoUtils.Check.array_access ~arr ~idx ~idx_sym_exp ~relation ~is_plus ~last_included:false
~latest_prune location cond_set
BoUtils.Check.array_access ~arr ~idx ~is_plus ~last_included:false ~latest_prune location cond_set
let check_binop :
@ -189,11 +185,10 @@ let check_expr_for_array_access :
match exp with
| Exp.Var _ ->
let arr = Sem.eval integer_type_widths exp mem in
let idx, idx_sym_exp = (Dom.Val.Itv.zero, Some Relation.SymExp.zero) in
let relation = Dom.Mem.get_relation mem in
let idx = Dom.Val.Itv.zero in
let latest_prune = Dom.Mem.get_latest_prune mem in
BoUtils.Check.array_access ~arr ~idx ~idx_sym_exp ~relation ~is_plus:true ~last_included:false
~latest_prune location cond_set
BoUtils.Check.array_access ~arr ~idx ~is_plus:true ~last_included:false ~latest_prune location
cond_set
| Exp.BinOp (bop, e1, e2) ->
check_binop integer_type_widths ~bop ~e1 ~e2 location mem cond_set
| _ ->
@ -239,34 +234,23 @@ let rec check_expr_for_integer_overflow integer_type_widths exp location mem con
let instantiate_cond :
Tenv.t
-> Typ.IntegerWidths.t
Typ.IntegerWidths.t
-> Typ.Procname.t
-> (Pvar.t * Typ.t) list
-> (Exp.t * Typ.t) list
-> Dom.Mem.t
-> BufferOverrunAnalysisSummary.t
-> BufferOverrunCheckerSummary.t
-> Location.t
-> PO.ConditionSet.checked_t =
fun tenv integer_type_widths callee_pname callee_formals params caller_mem callee_exit_mem
callee_cond location ->
let rel_subst_map =
Option.value_map Config.bo_relational_domain ~default:Relation.SubstMap.empty ~f:(fun _ ->
Sem.get_subst_map tenv integer_type_widths callee_formals params caller_mem callee_exit_mem
)
in
let caller_rel = Dom.Mem.get_relation caller_mem in
fun integer_type_widths callee_pname callee_formals params caller_mem callee_cond location ->
let eval_sym_trace = Sem.mk_eval_sym_trace integer_type_widths callee_formals params caller_mem in
let latest_prune = Dom.Mem.get_latest_prune caller_mem in
PO.ConditionSet.subst callee_cond eval_sym_trace rel_subst_map caller_rel callee_pname location
latest_prune
PO.ConditionSet.subst callee_cond eval_sym_trace callee_pname location latest_prune
type checks_summary = BufferOverrunCheckerSummary.t
type get_proc_summary =
Typ.Procname.t -> (BufferOverrunAnalysisSummary.t * (Pvar.t * Typ.t) list * checks_summary) option
type get_proc_summary = Typ.Procname.t -> ((Pvar.t * Typ.t) list * checks_summary) option
let check_instr :
get_proc_summary
@ -308,9 +292,9 @@ let check_instr :
check model_env mem cond_set
| None -> (
match get_proc_summary callee_pname with
| Some (callee_mem, callee_formals, callee_condset) ->
instantiate_cond tenv integer_type_widths callee_pname callee_formals params mem
callee_mem callee_condset location
| Some (callee_formals, callee_condset) ->
instantiate_cond integer_type_widths callee_pname callee_formals params mem
callee_condset location
|> PO.ConditionSet.join cond_set
| None ->
(* unknown call / no inferbo payload *) cond_set ) )
@ -416,13 +400,12 @@ let report_errors : Tenv.t -> checks -> Summary.t -> unit =
PO.ConditionSet.report_errors ~report cond_set
let get_checks_summary : BufferOverrunAnalysis.local_decls -> checks -> checks_summary =
fun locals
Checks.
let get_checks_summary : checks -> checks_summary =
fun Checks.
{ cond_set
; unused_branches= _ (* intra-procedural *)
; unreachable_statements= _ (* intra-procedural *) } ->
PO.ConditionSet.for_summary ~relation_forget_locs:locals cond_set
PO.ConditionSet.for_summary cond_set
let checker : Callbacks.proc_callback_args -> Summary.t =
@ -442,17 +425,13 @@ let checker : Callbacks.proc_callback_args -> Summary.t =
let get_proc_summary callee_pname =
Ondemand.analyze_proc_name ~caller_summary:summary callee_pname
|> Option.bind ~f:(fun summary ->
let analysis_payload = BufferOverrunAnalysis.Payload.of_summary summary in
let checker_payload = Payload.of_summary summary in
Option.map2 analysis_payload checker_payload
~f:(fun analysis_payload checker_payload ->
( analysis_payload
, Summary.get_proc_desc summary |> Procdesc.get_pvar_formals
, checker_payload ) ) )
Option.map checker_payload ~f:(fun checker_payload ->
(Summary.get_proc_desc summary |> Procdesc.get_pvar_formals, checker_payload)
) )
in
compute_checks get_proc_summary proc_desc tenv integer_type_widths cfg inv_map
in
report_errors tenv checks summary ;
let locals = BufferOverrunAnalysis.get_local_decls proc_desc in
let cond_set = get_checks_summary locals checks in
let cond_set = get_checks_summary checks in
Payload.update_summary cond_set summary )

@ -13,7 +13,6 @@ open! AbstractDomain.Types
module F = Format
module L = Logging
module OndemandEnv = BufferOverrunOndemandEnv
module Relation = BufferOverrunDomainRelation
module SPath = Symb.SymbolPath
module Trace = BufferOverrunTrace
module TraceSet = Trace.Set
@ -93,11 +92,8 @@ module Val = struct
; itv_thresholds: ItvThresholds.t
; itv_updated_by: ItvUpdatedBy.t
; modeled_range: ModeledRange.t
; sym: Relation.Sym.t
; powloc: PowLoc.t
; arrayblk: ArrayBlk.t
; offset_sym: Relation.Sym.t
; size_sym: Relation.Sym.t
; traces: TraceSet.t }
let bot : t =
@ -105,11 +101,8 @@ module Val = struct
; itv_thresholds= ItvThresholds.empty
; itv_updated_by= ItvUpdatedBy.bottom
; modeled_range= ModeledRange.bottom
; sym= Relation.Sym.bot
; powloc= PowLoc.bot
; arrayblk= ArrayBlk.bot
; offset_sym= Relation.Sym.bot
; size_sym= Relation.Sym.bot
; traces= TraceSet.bottom }
@ -121,9 +114,6 @@ module Val = struct
let itv_updated_by_pp fmt itv_updated_by =
if Config.bo_debug >= 3 then F.fprintf fmt "(updated by %a)" ItvUpdatedBy.pp itv_updated_by
in
let relation_sym_pp fmt sym =
if Option.is_some Config.bo_relational_domain then F.fprintf fmt ", %a" Relation.Sym.pp sym
in
let modeled_range_pp fmt range =
if not (ModeledRange.is_bottom range) then
F.fprintf fmt " (modeled_range:%a)" ModeledRange.pp range
@ -131,10 +121,9 @@ module Val = struct
let trace_pp fmt traces =
if Config.bo_debug >= 1 then F.fprintf fmt ", %a" TraceSet.pp traces
in
F.fprintf fmt "(%a%a%a%a%a, %a, %a%a%a%a)" Itv.pp x.itv itv_thresholds_pp x.itv_thresholds
relation_sym_pp x.sym itv_updated_by_pp x.itv_updated_by modeled_range_pp x.modeled_range
PowLoc.pp x.powloc ArrayBlk.pp x.arrayblk relation_sym_pp x.offset_sym relation_sym_pp
x.size_sym trace_pp x.traces
F.fprintf fmt "(%a%a%a%a, %a, %a%a)" Itv.pp x.itv itv_thresholds_pp x.itv_thresholds
itv_updated_by_pp x.itv_updated_by modeled_range_pp x.modeled_range PowLoc.pp x.powloc
ArrayBlk.pp x.arrayblk trace_pp x.traces
let unknown_from : callee_pname:_ -> location:_ -> t =
@ -144,11 +133,8 @@ module Val = struct
; itv_thresholds= ItvThresholds.empty
; itv_updated_by= ItvUpdatedBy.Top
; modeled_range= ModeledRange.bottom
; sym= Relation.Sym.top
; powloc= PowLoc.unknown
; arrayblk= ArrayBlk.unknown
; offset_sym= Relation.Sym.top
; size_sym= Relation.Sym.top
; traces }
@ -159,11 +145,8 @@ module Val = struct
&& ItvThresholds.leq ~lhs:lhs.itv_thresholds ~rhs:rhs.itv_thresholds
&& ItvUpdatedBy.leq ~lhs:lhs.itv_updated_by ~rhs:rhs.itv_updated_by
&& ModeledRange.leq ~lhs:lhs.modeled_range ~rhs:rhs.modeled_range
&& Relation.Sym.leq ~lhs:lhs.sym ~rhs:rhs.sym
&& PowLoc.leq ~lhs:lhs.powloc ~rhs:rhs.powloc
&& ArrayBlk.leq ~lhs:lhs.arrayblk ~rhs:rhs.arrayblk
&& Relation.Sym.leq ~lhs:lhs.offset_sym ~rhs:rhs.offset_sym
&& Relation.Sym.leq ~lhs:lhs.size_sym ~rhs:rhs.size_sym
let widen ~prev ~next ~num_iters =
@ -179,11 +162,8 @@ module Val = struct
ItvUpdatedBy.widen ~prev:prev.itv_updated_by ~next:next.itv_updated_by ~num_iters
; modeled_range=
ModeledRange.widen ~prev:prev.modeled_range ~next:next.modeled_range ~num_iters
; sym= Relation.Sym.widen ~prev:prev.sym ~next:next.sym ~num_iters
; powloc= PowLoc.widen ~prev:prev.powloc ~next:next.powloc ~num_iters
; arrayblk= ArrayBlk.widen ~prev:prev.arrayblk ~next:next.arrayblk ~num_iters
; offset_sym= Relation.Sym.widen ~prev:prev.offset_sym ~next:next.offset_sym ~num_iters
; size_sym= Relation.Sym.widen ~prev:prev.size_sym ~next:next.size_sym ~num_iters
; traces= TraceSet.join prev.traces next.traces }
@ -195,11 +175,8 @@ module Val = struct
; itv_thresholds= ItvThresholds.join x.itv_thresholds y.itv_thresholds
; itv_updated_by= ItvUpdatedBy.join x.itv_updated_by y.itv_updated_by
; modeled_range= ModeledRange.join x.modeled_range y.modeled_range
; sym= Relation.Sym.join x.sym y.sym
; powloc= PowLoc.join x.powloc y.powloc
; arrayblk= ArrayBlk.join x.arrayblk y.arrayblk
; offset_sym= Relation.Sym.join x.offset_sym y.offset_sym
; size_sym= Relation.Sym.join x.size_sym y.size_sym
; traces= TraceSet.join x.traces y.traces }
@ -209,10 +186,6 @@ module Val = struct
let get_modeled_range : t -> ModeledRange.t = fun x -> x.modeled_range
let get_sym : t -> Relation.Sym.t = fun x -> x.sym
let get_sym_var : t -> Relation.Var.t option = fun x -> Relation.Sym.get_var x.sym
let get_pow_loc : t -> PowLoc.t = fun x -> x.powloc
let get_array_blk : t -> ArrayBlk.t = fun x -> x.arrayblk
@ -221,10 +194,6 @@ module Val = struct
let get_all_locs : t -> PowLoc.t = fun x -> PowLoc.join x.powloc (get_array_locs x)
let get_offset_sym : t -> Relation.Sym.t = fun x -> x.offset_sym
let get_size_sym : t -> Relation.Sym.t = fun x -> x.size_sym
let get_traces : t -> TraceSet.t = fun x -> x.traces
let of_itv ?(traces = TraceSet.bottom) itv = {bot with itv; traces}
@ -243,19 +212,11 @@ module Val = struct
Allocsite.t -> stride:int option -> offset:Itv.t -> size:Itv.t -> traces:TraceSet.t -> t =
fun allocsite ~stride ~offset ~size ~traces ->
let stride = Option.value_map stride ~default:Itv.nat ~f:Itv.of_int in
{ bot with
arrayblk= ArrayBlk.make_c allocsite ~offset ~size ~stride
; offset_sym= Relation.Sym.of_allocsite_offset allocsite
; size_sym= Relation.Sym.of_allocsite_size allocsite
; traces }
{bot with arrayblk= ArrayBlk.make_c allocsite ~offset ~size ~stride; traces}
let of_java_array_alloc : Allocsite.t -> length:Itv.t -> traces:TraceSet.t -> t =
fun allocsite ~length ~traces ->
{ bot with
arrayblk= ArrayBlk.make_java allocsite ~length
; size_sym= Relation.Sym.of_allocsite_size allocsite
; traces }
fun allocsite ~length ~traces -> {bot with arrayblk= ArrayBlk.make_java allocsite ~length; traces}
let of_literal_string : Typ.IntegerWidths.t -> string -> t =
@ -284,11 +245,11 @@ module Val = struct
let set_modeled_range range x = {x with modeled_range= range}
let unknown_bit : t -> t = fun x -> {x with itv= Itv.top; sym= Relation.Sym.top}
let unknown_bit : t -> t = fun x -> {x with itv= Itv.top}
let neg : t -> t = fun x -> {x with itv= Itv.neg x.itv; sym= Relation.Sym.top}
let neg : t -> t = fun x -> {x with itv= Itv.neg x.itv}
let lnot : t -> t = fun x -> {x with itv= Itv.lnot x.itv |> Itv.of_bool; sym= Relation.Sym.top}
let lnot : t -> t = fun x -> {x with itv= Itv.lnot x.itv |> Itv.of_bool}
let lift_itv : (Itv.t -> Itv.t -> Itv.t) -> ?f_trace:_ -> t -> t -> t =
fun f ?f_trace x y ->
@ -1766,7 +1727,6 @@ module MemReach = struct
; mem_pure: MemPure.t
; alias: Alias.t
; latest_prune: LatestPrune.t
; relation: Relation.t
; oenv: ('has_oenv, OndemandEnv.t) GOption.t }
type no_oenv_t = GOption.none t0
@ -1779,7 +1739,6 @@ module MemReach = struct
; mem_pure= MemPure.bot
; alias= Alias.init
; latest_prune= LatestPrune.top
; relation= Relation.empty
; oenv= GOption.GSome oenv }
@ -1790,7 +1749,6 @@ module MemReach = struct
&& MemPure.leq ~lhs:lhs.mem_pure ~rhs:rhs.mem_pure
&& Alias.leq ~lhs:lhs.alias ~rhs:rhs.alias
&& LatestPrune.leq ~lhs:lhs.latest_prune ~rhs:rhs.latest_prune
&& Relation.leq ~lhs:lhs.relation ~rhs:rhs.relation
let widen ~prev ~next ~num_iters =
@ -1802,7 +1760,6 @@ module MemReach = struct
; mem_pure= MemPure.widen oenv ~prev:prev.mem_pure ~next:next.mem_pure ~num_iters
; alias= Alias.widen ~prev:prev.alias ~next:next.alias ~num_iters
; latest_prune= LatestPrune.widen ~prev:prev.latest_prune ~next:next.latest_prune ~num_iters
; relation= Relation.widen ~prev:prev.relation ~next:next.relation ~num_iters
; oenv= prev.oenv } )
@ -1814,16 +1771,13 @@ module MemReach = struct
; mem_pure= MemPure.join oenv x.mem_pure y.mem_pure
; alias= Alias.join x.alias y.alias
; latest_prune= LatestPrune.join x.latest_prune y.latest_prune
; relation= Relation.join x.relation y.relation
; oenv= x.oenv }
let pp : F.formatter -> _ t0 -> unit =
fun fmt x ->
F.fprintf fmt "StackLocs:@;%a@;MemPure:@;%a@;Alias:@;%a@;%a" StackLocs.pp x.stack_locs
MemPure.pp x.mem_pure Alias.pp x.alias LatestPrune.pp x.latest_prune ;
if Option.is_some Config.bo_relational_domain then
F.fprintf fmt "@;Relation:@;%a" Relation.pp x.relation
MemPure.pp x.mem_pure Alias.pp x.alias LatestPrune.pp x.latest_prune
let unset_oenv : t -> no_oenv_t = function x -> {x with oenv= GOption.GNone}
@ -1940,14 +1894,6 @@ module MemReach = struct
let add_heap : ?represents_multiple_values:bool -> Loc.t -> Val.t -> t -> t =
fun ?represents_multiple_values x v m ->
let v =
let sym = if Itv.is_bottom (Val.get_itv v) then Relation.Sym.bot else Relation.Sym.of_loc x in
let offset_sym, size_sym =
if ArrayBlk.is_bot (Val.get_array_blk v) then (Relation.Sym.bot, Relation.Sym.bot)
else (Relation.Sym.of_loc_offset x, Relation.Sym.of_loc_size x)
in
{v with Val.sym; Val.offset_sym; Val.size_sym}
in
{m with mem_pure= MemPure.add ?represents_multiple_values x v m.mem_pure}
@ -2106,30 +2052,6 @@ module MemReach = struct
fun ~filter_loc ~node_id {mem_pure} -> MemPure.range ~filter_loc ~node_id mem_pure
let get_relation : t -> Relation.t = fun m -> m.relation
let is_relation_unsat : t -> bool = fun m -> Relation.is_unsat m.relation
let lift_relation : (Relation.t -> Relation.t) -> t -> t =
fun f m -> {m with relation= f m.relation}
let meet_constraints : Relation.Constraints.t -> t -> t =
fun constrs -> lift_relation (Relation.meet_constraints constrs)
let store_relation :
PowLoc.t
-> Relation.SymExp.t option * Relation.SymExp.t option * Relation.SymExp.t option
-> t
-> t =
fun locs symexp_opts -> lift_relation (Relation.store_relation locs symexp_opts)
let relation_forget_locs : PowLoc.t -> t -> t =
fun locs -> lift_relation (Relation.forget_locs locs)
let forget_unreachable_locs : formals:(Pvar.t * Typ.t) list -> t -> t =
fun ~formals m ->
let is_reachable =
@ -2149,25 +2071,6 @@ module MemReach = struct
let forget_size_alias arr_locs m = {m with alias= Alias.forget_size_alias arr_locs m.alias}
let init_param_relation : Loc.t -> t -> t = fun loc -> lift_relation (Relation.init_param loc)
let init_array_relation :
Allocsite.t
-> offset_opt:Itv.t option
-> size:Itv.t
-> size_exp_opt:Relation.SymExp.t option
-> t
-> t =
fun allocsite ~offset_opt ~size ~size_exp_opt ->
lift_relation (Relation.init_array allocsite ~offset_opt ~size ~size_exp_opt)
let instantiate_relation : Relation.SubstMap.t -> caller:t -> callee:no_oenv_t -> t =
fun subst_map ~caller ~callee ->
{ caller with
relation= Relation.instantiate subst_map ~caller:caller.relation ~callee:callee.relation }
(* unsound *)
let set_first_idx_of_null : Loc.t -> Val.t -> t -> t =
fun loc idx m -> update_mem (PowLoc.singleton (Loc.of_c_strlen loc)) idx m
@ -2412,58 +2315,12 @@ module Mem = struct
fun latest_prune m -> map ~f:(MemReach.set_latest_prune latest_prune) m
let get_relation : t -> Relation.t =
fun m -> f_lift_default ~default:Relation.bot MemReach.get_relation m
let meet_constraints : Relation.Constraints.t -> t -> t =
fun constrs -> map ~f:(MemReach.meet_constraints constrs)
let is_relation_unsat m = f_lift_default ~default:true MemReach.is_relation_unsat m
let store_relation :
PowLoc.t
-> Relation.SymExp.t option * Relation.SymExp.t option * Relation.SymExp.t option
-> t
-> t =
fun locs symexp_opts -> map ~f:(MemReach.store_relation locs symexp_opts)
let relation_forget_locs : PowLoc.t -> t -> t =
fun locs -> map ~f:(MemReach.relation_forget_locs locs)
let forget_unreachable_locs : formals:(Pvar.t * Typ.t) list -> t -> t =
fun ~formals -> map ~f:(MemReach.forget_unreachable_locs ~formals)
let forget_size_alias arr_locs = map ~f:(MemReach.forget_size_alias arr_locs)
let[@warning "-32"] init_param_relation : Loc.t -> t -> t =
fun loc -> map ~f:(MemReach.init_param_relation loc)
let init_array_relation :
Allocsite.t
-> offset_opt:Itv.t option
-> size:Itv.t
-> size_exp_opt:Relation.SymExp.t option
-> t
-> t =
fun allocsite ~offset_opt ~size ~size_exp_opt ->
map ~f:(MemReach.init_array_relation allocsite ~offset_opt ~size ~size_exp_opt)
let instantiate_relation : Relation.SubstMap.t -> caller:t -> callee:no_oenv_t -> t =
fun subst_map ~caller ~callee ->
match callee with
| Bottom | ExcRaised ->
caller
| NonBottom callee ->
map ~f:(fun caller -> MemReach.instantiate_relation subst_map ~caller ~callee) caller
let unset_oenv = function
| (Bottom | ExcRaised) as x ->
x

File diff suppressed because it is too large Load Diff

@ -13,7 +13,6 @@ module BoUtils = BufferOverrunUtils
module Dom = BufferOverrunDomain
module PO = BufferOverrunProofObligations
module Sem = BufferOverrunSemantics
module Relation = BufferOverrunDomainRelation
module Trace = BufferOverrunTrace
open BoUtils.ModelEnv
open ProcnameDispatcher.Call.FuncArg
@ -128,10 +127,6 @@ let malloc ~can_be_zero size_exp =
let allocsite =
Allocsite.make pname ~node_hash ~inst_num:0 ~dimension:1 ~path ~represents_multiple_values
in
let size_exp_opt =
let size_exp = Option.value dyn_length ~default:length0 in
Relation.SymExp.of_exp ~get_sym_f:(Sem.get_sym_f integer_type_widths mem) size_exp
in
if Language.curr_language_is Java then
let internal_arr =
let allocsite =
@ -148,7 +143,6 @@ let malloc ~can_be_zero size_exp =
let v = Dom.Val.of_c_array_alloc allocsite ~stride ~offset ~size ~traces in
mem
|> Dom.Mem.add_stack (Loc.of_id id) v
|> Dom.Mem.init_array_relation allocsite ~offset_opt:(Some offset) ~size ~size_exp_opt
|> BoUtils.Exec.init_c_array_fields model_env path typ (Dom.Val.get_array_locs v) ?dyn_length
and check = check_alloc_size ~can_be_zero size_exp in
{exec; check}
@ -203,11 +197,10 @@ let strcpy dest_exp src_exp =
and check {integer_type_widths; location} mem cond_set =
let access_last_char =
let idx = Dom.Mem.get_c_strlen (Sem.eval_locs src_exp mem) mem in
let relation = Dom.Mem.get_relation mem in
let latest_prune = Dom.Mem.get_latest_prune mem in
fun arr cond_set ->
BoUtils.Check.array_access ~arr ~idx ~idx_sym_exp:None ~relation ~is_plus:true
~last_included:false ~latest_prune location cond_set
BoUtils.Check.array_access ~arr ~idx ~is_plus:true ~last_included:false ~latest_prune
location cond_set
in
cond_set
|> access_last_char (Sem.eval integer_type_widths dest_exp mem)
@ -246,10 +239,9 @@ let strcat dest_exp src_exp =
|> Dom.Mem.add_stack (Loc.of_id id) (Sem.eval integer_type_widths dest_exp mem)
and check {integer_type_widths; location} mem cond_set =
let access_last_char arr idx cond_set =
let relation = Dom.Mem.get_relation mem in
let latest_prune = Dom.Mem.get_latest_prune mem in
BoUtils.Check.array_access ~arr ~idx ~idx_sym_exp:None ~relation ~is_plus:true
~last_included:false ~latest_prune location cond_set
BoUtils.Check.array_access ~arr ~idx ~is_plus:true ~last_included:false ~latest_prune location
cond_set
in
let src_strlen =
let str_loc = Sem.eval_locs src_exp mem in
@ -575,10 +567,9 @@ module ArrObjCommon = struct
and check ({location; integer_type_widths} as model_env) mem cond_set =
let idx = Sem.eval integer_type_widths index_exp mem in
let arr = Dom.Mem.find_set (deref_of model_env arr_exp ~fn mem) mem in
let relation = Dom.Mem.get_relation mem in
let latest_prune = Dom.Mem.get_latest_prune mem in
BoUtils.Check.array_access ~arr ~idx ~idx_sym_exp:None ~relation ~is_plus:true
~last_included:false ~latest_prune location cond_set
BoUtils.Check.array_access ~arr ~idx ~is_plus:true ~last_included:false ~latest_prune location
cond_set
in
{exec; check}
@ -978,13 +969,9 @@ module Collection = struct
Dom.Mem.find_set arr_locs mem
in
let idx = Sem.eval integer_type_widths index_exp mem in
let idx_sym_exp =
Relation.SymExp.of_exp ~get_sym_f:(Sem.get_sym_f integer_type_widths mem) index_exp
in
let relation = Dom.Mem.get_relation mem in
let latest_prune = Dom.Mem.get_latest_prune mem in
BoUtils.Check.array_access ~arr ~idx ~idx_sym_exp ~relation ~is_plus:true ~last_included
~latest_prune location cond_set
BoUtils.Check.array_access ~arr ~idx ~is_plus:true ~last_included ~latest_prune location
cond_set
let add_at_index (coll_id : Ident.t) index_exp =

@ -13,7 +13,6 @@ module Bound = Bounds.Bound
module Dom = BufferOverrunDomain
module ItvPure = Itv.ItvPure
module MF = MarkupFormatter
module Relation = BufferOverrunDomainRelation
module Sem = BufferOverrunSemantics
module ValTrace = BufferOverrunTrace
@ -195,15 +194,7 @@ module AllocSizeCondition = struct
end
module ArrayAccessCondition = struct
type t =
{ offset: ItvPure.t
; idx: ItvPure.t
; size: ItvPure.t
; last_included: bool
; idx_sym_exp: Relation.SymExp.t option
; size_sym_exp: Relation.SymExp.t option
; relation: Relation.t
; void_ptr: bool }
type t = {offset: ItvPure.t; idx: ItvPure.t; size: ItvPure.t; last_included: bool; void_ptr: bool}
[@@deriving compare]
let get_symbols c =
@ -218,10 +209,7 @@ module ArrayAccessCondition = struct
in
let cmp = if c.last_included then "<=" else "<" in
F.fprintf fmt "%t%a %s %a" pp_offset ItvPure.pp c.idx cmp ItvPure.pp
(ItvPure.make_positive c.size) ;
if Option.is_some Config.bo_relational_domain then
F.fprintf fmt "@,%a %s %a when %a" Relation.SymExp.pp_opt c.idx_sym_exp cmp
Relation.SymExp.pp_opt c.size_sym_exp Relation.pp c.relation
(ItvPure.make_positive c.size)
let pp_description : markup:bool -> F.formatter -> t -> unit =
@ -239,20 +227,12 @@ module ArrayAccessCondition = struct
pp_offset (ItvPure.pp_mark ~markup) (ItvPure.make_positive c.size)
let make :
offset:ItvPure.t
-> idx:ItvPure.t
-> size:ItvPure.t
-> last_included:bool
-> idx_sym_exp:Relation.SymExp.t option
-> size_sym_exp:Relation.SymExp.t option
-> relation:Relation.t
-> t option =
fun ~offset ~idx ~size ~last_included ~idx_sym_exp ~size_sym_exp ~relation ->
let make : offset:ItvPure.t -> idx:ItvPure.t -> size:ItvPure.t -> last_included:bool -> t option =
fun ~offset ~idx ~size ~last_included ->
if ItvPure.is_invalid offset || ItvPure.is_invalid idx || ItvPure.is_invalid size then None
else
let void_ptr = ItvPure.has_void_ptr_symb offset || ItvPure.has_void_ptr_symb size in
Some {offset; idx; size; last_included; idx_sym_exp; size_sym_exp; relation; void_ptr}
Some {offset; idx; size; last_included; void_ptr}
let have_similar_bounds {offset= loff; idx= lidx; size= lsiz; last_included= lcol}
@ -365,14 +345,8 @@ module ArrayAccessCondition = struct
if c.last_included then ItvPure.succ size_pos else size_pos
in
(* if sl < 0, use sl' = 0 *)
let not_overrun =
if Relation.lt_sat_opt c.idx_sym_exp c.size_sym_exp c.relation then Boolean.True
else ItvPure.lt_sem real_idx size
in
let not_underrun =
if Relation.le_sat_opt (Some Relation.SymExp.zero) c.idx_sym_exp c.relation then Boolean.True
else ItvPure.le_sem ItvPure.zero real_idx
in
let not_overrun = ItvPure.lt_sem real_idx size in
let not_underrun = ItvPure.le_sem ItvPure.zero real_idx in
(* il >= 0 and iu < sl, definitely not an error *)
if Boolean.is_true not_overrun && Boolean.is_true not_underrun then
{report_issue_type= NotIssue; propagate= false} (* iu < 0 or il >= su, definitely an error *)
@ -400,30 +374,19 @@ module ArrayAccessCondition = struct
{report_issue_type; propagate= is_symbolic}
let subst : Bound.eval_sym -> Relation.SubstMap.t -> Relation.t -> t -> t option =
fun eval_sym rel_map caller_relation c ->
let subst : Bound.eval_sym -> t -> t option =
fun eval_sym c ->
match
(ItvPure.subst c.offset eval_sym, ItvPure.subst c.idx eval_sym, ItvPure.subst c.size eval_sym)
with
| NonBottom offset, NonBottom idx, NonBottom size ->
let idx_sym_exp, size_sym_exp, relation =
if Option.is_none Config.bo_relational_domain then (None, None, Relation.bot)
else
( Relation.SubstMap.symexp_subst_opt rel_map c.idx_sym_exp
, Relation.SubstMap.symexp_subst_opt rel_map c.size_sym_exp
, Relation.instantiate rel_map ~caller:caller_relation ~callee:c.relation )
in
let void_ptr =
c.void_ptr || ItvPure.has_void_ptr_symb offset || ItvPure.has_void_ptr_symb idx
|| ItvPure.has_void_ptr_symb size
in
Some {c with offset; idx; size; idx_sym_exp; size_sym_exp; relation; void_ptr}
Some {c with offset; idx; size; void_ptr}
| _ ->
None
let relation_forget_locs : AbsLoc.PowLoc.t -> t -> t =
fun locs c -> {c with relation= Relation.forget_locs locs c.relation}
end
module BinaryOperationCondition = struct
@ -631,11 +594,11 @@ module Condition = struct
BinaryOperationCondition.get_symbols c
let subst eval_sym rel_map caller_relation = function
let subst eval_sym = function
| AllocSize c ->
AllocSizeCondition.subst eval_sym c |> make_alloc_size
| ArrayAccess c ->
ArrayAccessCondition.subst eval_sym rel_map caller_relation c |> make_array_access
ArrayAccessCondition.subst eval_sym c |> make_array_access
| BinaryOperation c ->
BinaryOperationCondition.subst eval_sym c |> make_binary_operation
@ -701,14 +664,6 @@ module Condition = struct
BinaryOperationCondition.check c trace
let relation_forget_locs locs x =
match x with
| ArrayAccess c ->
ArrayAccess (ArrayAccessCondition.relation_forget_locs locs c)
| AllocSize _ | BinaryOperation _ ->
x
let is_array_access_of_void_ptr = function ArrayAccess {void_ptr} -> void_ptr | _ -> false
end
@ -756,7 +711,7 @@ module ConditionWithTrace = struct
else `NotComparable
let subst eval_sym_trace rel_map caller_relation callee_pname call_site cwt =
let subst eval_sym_trace callee_pname call_site cwt =
let symbols = Condition.get_symbols cwt.cond in
if Symb.SymbolSet.is_empty symbols then
L.(die InternalError)
@ -770,7 +725,7 @@ module ConditionWithTrace = struct
with
| `Reachable reachability -> (
let {Dom.eval_sym; trace_of_sym} = eval_sym_trace ~mode:Sem.EvalPOCond in
match Condition.subst eval_sym rel_map caller_relation cwt.cond with
match Condition.subst eval_sym cwt.cond with
| None ->
None
| Some cond ->
@ -834,7 +789,7 @@ module ConditionWithTrace = struct
report cwt.cond cwt.trace issue_type
let for_summary ~relation_forget_locs = function
let for_summary = function
| _, {propagate= false} | _, {report_issue_type= NotIssue} ->
None
| {cond; trace; reported; reachability}, {report_issue_type} ->
@ -847,7 +802,6 @@ module ConditionWithTrace = struct
| Issue issue_type ->
Some (Reported.make issue_type)
in
let cond = Condition.relation_forget_locs relation_forget_locs cond in
let trace = ConditionTrace.for_summary trace in
Some {cond; trace; reported; reachability}
end
@ -926,9 +880,9 @@ module ConditionSet = struct
join_one condset (check_one cwt)
let add_array_access location ~offset ~idx ~size ~last_included ~idx_sym_exp ~size_sym_exp
~relation ~idx_traces ~arr_traces ~latest_prune condset =
ArrayAccessCondition.make ~offset ~idx ~size ~last_included ~idx_sym_exp ~size_sym_exp ~relation
let add_array_access location ~offset ~idx ~size ~last_included ~idx_traces ~arr_traces
~latest_prune condset =
ArrayAccessCondition.make ~offset ~idx ~size ~last_included
|> Condition.make_array_access
|> add_opt location
(ValTrace.Issue.(binary location ArrayAccess) idx_traces arr_traces)
@ -950,13 +904,9 @@ module ConditionSet = struct
latest_prune condset
let subst condset eval_sym_trace rel_subst_map caller_relation callee_pname call_site latest_prune
=
let subst condset eval_sym_trace callee_pname call_site latest_prune =
let subst_add_cwt condset cwt =
match
ConditionWithTrace.subst eval_sym_trace rel_subst_map caller_relation callee_pname call_site
cwt
with
match ConditionWithTrace.subst eval_sym_trace callee_pname call_site cwt with
| None ->
condset
| Some cwt ->
@ -970,9 +920,7 @@ module ConditionSet = struct
List.iter condset ~f:(ConditionWithTrace.report_errors ~report)
let for_summary ~relation_forget_locs condset =
List.filter_map condset ~f:(ConditionWithTrace.for_summary ~relation_forget_locs)
let for_summary condset = List.filter_map condset ~f:ConditionWithTrace.for_summary
let pp_summary : F.formatter -> _ t0 -> unit =
fun fmt condset ->

@ -8,7 +8,6 @@
open! IStd
open! AbstractDomain.Types
module ItvPure = Itv.ItvPure
module Relation = BufferOverrunDomainRelation
module Condition : sig
type t
@ -39,9 +38,6 @@ module ConditionSet : sig
-> idx:ItvPure.t
-> size:ItvPure.t
-> last_included:bool
-> idx_sym_exp:Relation.SymExp.t option
-> size_sym_exp:Relation.SymExp.t option
-> relation:Relation.t
-> idx_traces:BufferOverrunTrace.Set.t
-> arr_traces:BufferOverrunTrace.Set.t
-> latest_prune:BufferOverrunDomain.LatestPrune.t
@ -74,8 +70,6 @@ module ConditionSet : sig
val subst :
summary_t
-> (mode:BufferOverrunSemantics.eval_mode -> BufferOverrunDomain.eval_sym_trace)
-> Relation.SubstMap.t
-> Relation.t
-> Typ.Procname.t
-> Location.t
-> BufferOverrunDomain.LatestPrune.t
@ -84,7 +78,7 @@ module ConditionSet : sig
val report_errors :
report:(Condition.t -> ConditionTrace.t -> IssueType.t -> unit) -> checked_t -> unit
val for_summary : relation_forget_locs:AbsLoc.PowLoc.t -> checked_t -> summary_t
val for_summary : checked_t -> summary_t
end
val description : markup:bool -> Condition.t -> ConditionTrace.t -> string

@ -475,12 +475,6 @@ let mk_eval_sym_mode ~mode integer_type_widths callee_formals actual_exps caller
let mk_eval_sym_cost = mk_eval_sym_mode ~mode:EvalCost
let get_sym_f integer_type_widths mem e = Val.get_sym (eval integer_type_widths e mem)
let get_offset_sym_f integer_type_widths mem e = Val.get_offset_sym (eval integer_type_widths e mem)
let get_size_sym_f integer_type_widths mem e = Val.get_size_sym (eval integer_type_widths e mem)
(* This function evaluates the array length conservatively, which is useful when there are multiple
array locations and their lengths are joined to top. For example, if the [arr_locs] points to
two arrays [a] and [b] and if their lengths are [a.length] and [b.length], this function
@ -732,9 +726,7 @@ module Prune = struct
let prune_unreachable : Typ.IntegerWidths.t -> Exp.t -> t -> t =
fun integer_type_widths e ({mem} as astate) ->
if is_unreachable_constant integer_type_widths e mem || Mem.is_relation_unsat mem then
{astate with mem= Mem.bot}
else astate
if is_unreachable_constant integer_type_widths e mem then {astate with mem= Mem.bot} else astate
let rec prune_helper integer_type_widths e astate =
@ -779,129 +771,6 @@ module Prune = struct
let prune : Typ.IntegerWidths.t -> Exp.t -> Mem.t -> Mem.t =
fun integer_type_widths e mem ->
let mem, prune_pairs = Mem.apply_latest_prune e mem in
let mem =
let constrs = Relation.Constraints.of_exp e ~get_sym_f:(get_sym_f integer_type_widths mem) in
Mem.meet_constraints constrs mem
in
let {mem; prune_pairs} = prune_helper integer_type_widths e {mem; prune_pairs} in
if PrunePairs.is_reachable prune_pairs then Mem.set_prune_pairs prune_pairs mem else Mem.bot
end
let get_matching_pairs :
Tenv.t
-> Typ.IntegerWidths.t
-> Val.t
-> Val.t
-> Exp.t option
-> Typ.t
-> Mem.t
-> _ Mem.t0
-> (Relation.Var.t * Relation.SymExp.t option) list =
fun tenv integer_type_widths callee_v actual actual_exp_opt typ caller_mem callee_exit_mem ->
let get_offset_sym v = Val.get_offset_sym v in
let get_size_sym v = Val.get_size_sym v in
let get_field_name (fn, _, _) = fn in
let append_field v fn = PowLoc.append_field (Val.get_all_locs v) ~fn in
let deref_field v fn mem = Mem.find_set (append_field v fn) mem in
let deref_ptr v mem =
let array_locs = Val.get_array_locs v in
let locs = if PowLoc.is_empty array_locs then Val.get_pow_loc v else array_locs in
Mem.find_set locs mem
in
let add_pair_sym_main_value v1 v2 ~e2_opt l =
Option.value_map (Val.get_sym_var v1) ~default:l ~f:(fun var ->
let sym_exp_opt =
Option.first_some
(Relation.SymExp.of_exp_opt
~get_sym_f:(get_sym_f integer_type_widths caller_mem)
e2_opt)
(Relation.SymExp.of_sym (Val.get_sym v2))
in
(var, sym_exp_opt) :: l )
in
let add_pair_sym s1 s2 l =
Option.value_map (Relation.Sym.get_var s1) ~default:l ~f:(fun var ->
(var, Relation.SymExp.of_sym s2) :: l )
in
let add_pair_val v1 v2 ~e2_opt rel_pairs =
rel_pairs
|> add_pair_sym_main_value v1 v2 ~e2_opt
|> add_pair_sym (get_offset_sym v1) (get_offset_sym v2)
|> add_pair_sym (get_size_sym v1) (get_size_sym v2)
in
let add_pair_field v1 v2 pairs fn =
let v1' = deref_field v1 fn callee_exit_mem in
let v2' = deref_field v2 fn caller_mem in
add_pair_val v1' v2' ~e2_opt:None pairs
in
let add_pair_ptr typ v1 v2 pairs =
match typ.Typ.desc with
| Typ.Tptr ({desc= Tstruct typename}, _) -> (
match Tenv.lookup tenv typename with
| Some str ->
let fns = List.map ~f:get_field_name str.Typ.Struct.fields in
List.fold ~f:(add_pair_field v1 v2) ~init:pairs fns
| _ ->
pairs )
| Typ.Tptr (_, _) ->
let v1' = deref_ptr v1 callee_exit_mem in
let v2' = deref_ptr v2 caller_mem in
add_pair_val v1' v2' ~e2_opt:None pairs
| _ ->
pairs
in
[] |> add_pair_val callee_v actual ~e2_opt:actual_exp_opt |> add_pair_ptr typ callee_v actual
let subst_map_of_rel_pairs : (Relation.Var.t * Relation.SymExp.t option) list -> Relation.SubstMap.t
=
fun pairs ->
let add_pair rel_map (x, e) = Relation.SubstMap.add x e rel_map in
List.fold pairs ~init:Relation.SubstMap.empty ~f:add_pair
let rec list_fold2_def :
default:Val.t * Exp.t option
-> f:('a -> Val.t * Exp.t option -> 'b -> 'b)
-> 'a list
-> (Val.t * Exp.t option) list
-> init:'b
-> 'b =
fun ~default ~f xs ys ~init:acc ->
match (xs, ys) with
| [], _ ->
acc
| x :: xs', [] ->
list_fold2_def ~default ~f xs' ys ~init:(f x default acc)
| [x], _ :: _ ->
let v = List.fold ys ~init:Val.bot ~f:(fun acc (y, _) -> Val.join y acc) in
let exp_opt = match ys with [(_, exp_opt)] -> exp_opt | _ -> None in
f x (v, exp_opt) acc
| x :: xs', y :: ys' ->
list_fold2_def ~default ~f xs' ys' ~init:(f x y acc)
let get_subst_map :
Tenv.t
-> Typ.IntegerWidths.t
-> (Pvar.t * Typ.t) list
-> (Exp.t * 'a) list
-> Mem.t
-> _ Mem.t0
-> Relation.SubstMap.t =
fun tenv integer_type_widths callee_formals params caller_mem callee_exit_mem ->
let add_pair (formal, typ) (actual, actual_exp) rel_l =
let callee_v = Mem.find (Loc.of_pvar formal) callee_exit_mem in
let new_rel_matching =
get_matching_pairs tenv integer_type_widths callee_v actual actual_exp typ caller_mem
callee_exit_mem
in
List.rev_append new_rel_matching rel_l
in
let actuals =
List.map ~f:(fun (a, _) -> (eval integer_type_widths a caller_mem, Some a)) params
in
let rel_pairs =
list_fold2_def ~default:(Val.Itv.top, None) ~f:add_pair callee_formals actuals ~init:[]
in
subst_map_of_rel_pairs rel_pairs

@ -10,7 +10,6 @@ open AbsLoc
open! AbstractDomain.Types
module L = Logging
module Dom = BufferOverrunDomain
module Relation = BufferOverrunDomainRelation
module PO = BufferOverrunProofObligations
module Sem = BufferOverrunSemantics
module Trace = BufferOverrunTrace
@ -77,16 +76,15 @@ module Exec = struct
Allocsite.make pname ~node_hash ~inst_num ~dimension ~path ~represents_multiple_values
in
let mem =
let arr, offset_opt =
let arr =
let traces = Trace.(Set.singleton location ArrayDeclaration) in
match Typ.Procname.get_language pname with
| Language.Clang ->
let offset = Itv.zero in
(Dom.Val.of_c_array_alloc allocsite ~stride ~offset ~size ~traces, Some offset)
Dom.Val.of_c_array_alloc allocsite ~stride ~offset ~size ~traces
| Language.Java ->
(Dom.Val.of_java_array_alloc allocsite ~length:size ~traces, None)
Dom.Val.of_java_array_alloc allocsite ~length:size ~traces
in
let mem = Dom.Mem.init_array_relation allocsite ~offset_opt ~size ~size_exp_opt:None mem in
if Int.equal dimension 1 then Dom.Mem.add_stack ~represents_multiple_values loc arr mem
else Dom.Mem.add_heap ~represents_multiple_values loc arr mem
in
@ -128,8 +126,6 @@ module Exec = struct
Dom.Val.of_c_array_alloc allocsite ~stride ~offset ~size ~traces
in
mem |> Dom.Mem.strong_update field_loc v
|> Dom.Mem.init_array_relation allocsite ~offset_opt:(Some offset) ~size
~size_exp_opt:None
| _ ->
init_fields field_path field_typ field_loc dimension ?dyn_length mem
in
@ -239,12 +235,12 @@ module Exec = struct
end
module Check = struct
let check_access ~size ~idx ~offset ~size_sym_exp ~idx_sym_exp ~relation ~arr_traces ~idx_traces
~last_included ~latest_prune location cond_set =
let check_access ~size ~idx ~offset ~arr_traces ~idx_traces ~last_included ~latest_prune location
cond_set =
match (size, idx) with
| NonBottom length, NonBottom idx ->
PO.ConditionSet.add_array_access location ~size:length ~offset ~idx ~size_sym_exp
~idx_sym_exp ~relation ~last_included ~idx_traces ~arr_traces ~latest_prune cond_set
PO.ConditionSet.add_array_access location ~size:length ~offset ~idx ~last_included
~idx_traces ~arr_traces ~latest_prune cond_set
| _ ->
cond_set
@ -264,27 +260,19 @@ module Check = struct
offset
let array_access ~arr ~idx ~idx_sym_exp ~relation ~is_plus ~last_included ~latest_prune location
cond_set =
let array_access ~arr ~idx ~is_plus ~last_included ~latest_prune location cond_set =
let idx_traces = Dom.Val.get_traces idx in
let idx =
let idx_itv = Dom.Val.get_itv idx in
if is_plus then idx_itv else Itv.neg idx_itv
in
let arr_traces = Dom.Val.get_traces arr in
let size_sym_exp = Relation.SymExp.of_sym (Dom.Val.get_size_sym arr) in
let idx_sym_exp =
let offset_sym_exp = Relation.SymExp.of_sym (Dom.Val.get_offset_sym arr) in
Option.map2 offset_sym_exp idx_sym_exp ~f:(fun offset_sym_exp idx_sym_exp ->
let op = if is_plus then Relation.SymExp.plus else Relation.SymExp.minus in
op idx_sym_exp offset_sym_exp )
in
let array_access1 allocsite arr_info acc =
let size = ArrayBlk.ArrInfo.get_size arr_info in
let offset = offsetof arr_info in
log_array_access allocsite size offset idx ;
check_access ~size ~idx ~offset ~size_sym_exp ~idx_sym_exp ~relation ~arr_traces ~idx_traces
~last_included ~latest_prune location acc
check_access ~size ~idx ~offset ~arr_traces ~idx_traces ~last_included ~latest_prune location
acc
in
ArrayBlk.fold array_access1 (Dom.Val.get_array_blk arr) cond_set
@ -297,17 +285,11 @@ module Check = struct
if PowLoc.is_empty arr_locs then Dom.Val.Itv.top else Dom.Mem.find_set arr_locs mem
else Sem.eval_arr integer_type_widths array_exp mem
in
let idx_sym_exp =
Relation.SymExp.of_exp ~get_sym_f:(Sem.get_sym_f integer_type_widths mem) index_exp
in
let relation = Dom.Mem.get_relation mem in
let latest_prune = Dom.Mem.get_latest_prune mem in
array_access ~arr ~idx ~idx_sym_exp ~relation ~is_plus:true ~last_included ~latest_prune
location cond_set
array_access ~arr ~idx ~is_plus:true ~last_included ~latest_prune location cond_set
let array_access_byte ~arr ~idx ~relation ~is_plus ~last_included ~latest_prune location cond_set
=
let array_access_byte ~arr ~idx ~is_plus ~last_included ~latest_prune location cond_set =
let idx_traces = Dom.Val.get_traces idx in
let idx =
let idx_itv = Dom.Val.get_itv idx in
@ -318,8 +300,8 @@ module Check = struct
let size = ArrayBlk.ArrInfo.byte_size arr_info in
let offset = offsetof arr_info in
log_array_access allocsite size offset idx ;
check_access ~size ~idx ~offset ~size_sym_exp:None ~idx_sym_exp:None ~relation ~arr_traces
~idx_traces ~last_included ~latest_prune location acc
check_access ~size ~idx ~offset ~arr_traces ~idx_traces ~last_included ~latest_prune location
acc
in
ArrayBlk.fold array_access_byte1 (Dom.Val.get_array_blk arr) cond_set
@ -328,10 +310,8 @@ module Check = struct
cond_set =
let idx = Sem.eval integer_type_widths byte_index_exp mem in
let arr = Sem.eval_arr integer_type_widths array_exp mem in
let relation = Dom.Mem.get_relation mem in
let latest_prune = Dom.Mem.get_latest_prune mem in
array_access_byte ~arr ~idx ~relation ~is_plus:true ~last_included ~latest_prune location
cond_set
array_access_byte ~arr ~idx ~is_plus:true ~last_included ~latest_prune location cond_set
let binary_operation integer_type_widths bop ~lhs ~rhs ~latest_prune location cond_set =

@ -8,7 +8,6 @@
open! IStd
open AbsLoc
module Dom = BufferOverrunDomain
module Relation = BufferOverrunDomainRelation
module PO = BufferOverrunProofObligations
module ModelEnv : sig
@ -56,8 +55,6 @@ module Check : sig
val array_access :
arr:Dom.Val.t
-> idx:Dom.Val.t
-> idx_sym_exp:Relation.SymExp.t option
-> relation:Relation.t
-> is_plus:bool
-> last_included:bool
-> latest_prune:Dom.LatestPrune.t

@ -66,15 +66,12 @@ let common_optflags = match build_mode with Opt -> ["-O3"] | Default | Test -> [
let common_libraries =
(if java then ["javalib"; "sawja"] else [])
@ [ "ANSITerminal"
; "apron"
; "apron.octMPQ"
; "async"
; "atdgen"
; "base"
; "base64"
; "cmdliner"
; "core"
; "elina"
; "mtime.clock.os"
; "ocamlgraph"
; "oUnit"

@ -21,20 +21,16 @@ install: [
]
depends: [
"ANSITerminal" {>="0.7"}
"apron" {<"v0.9.12"}
"async" {>="v0.12.0" & < "v0.13"}
"atdgen" {>="2.0.0"}
"base64" {>="3.0.0"}
"cmdliner" {>="1.0.0"}
"core" {>="v0.12.0" & < "v0.13"}
"conf-autoconf" {build}
"conf-gmp" {build}
"conf-mpfr" {build}
"conf-sqlite3" {build}
"conf-zlib" {build}
"ctypes" {>="0.9.2"}
"dune" {build & >="1.0"}
"elina" {>="1.1"}
"javalib" {>="3.1.1"}
"mlgmpidl" {>="1.2.12"}
"mtime"

@ -21,7 +21,6 @@ install: [
]
depends: [
"ANSITerminal" {= "0.8.1"}
"apron" {= "20160125"}
"async" {= "v0.12.0"}
"async_extra" {= "v0.12.0"}
"async_kernel" {= "v0.12.0"}
@ -40,13 +39,11 @@ depends: [
"base_quickcheck" {= "v0.12.1"}
"bin_prot" {= "v0.12.0"}
"biniou" {= "1.2.1"}
"camlidl" {= "1.07"}
"camlzip" {= "1.09"}
"cmdliner" {= "1.0.4"}
"conf-autoconf" {= "0.1"}
"conf-gmp" {= "1"}
"conf-m4" {= "1"}
"conf-mpfr" {= "1"}
"conf-perl" {= "1"}
"conf-pkg-config" {= "1.1"}
"conf-sqlite3" {= "1"}
@ -59,7 +56,6 @@ depends: [
"dune" {= "1.11.4"}
"dune-configurator" {= "1.0.0"}
"easy-format" {= "1.3.2"}
"elina" {= "1.1"}
"extlib" {= "1.7.6"}
"fieldslib" {= "v0.12.0"}
"integers" {= "0.3.0"}
@ -68,7 +64,6 @@ depends: [
"jbuilder" {= "transition"}
"jst-config" {= "v0.12.0"}
"menhir" {= "20190924"}
"mlgmpidl" {= "1.2.12"}
"mtime" {= "1.2.0"}
"num" {= "1.3"}
"ocaml" {= "4.08.1"}

@ -46,7 +46,7 @@ touch .release
--prefix="/$RELEASE_NAME"
make -j "$JOBS" \
install-with-libs \
install \
BUILD_MODE=opt \
DESTDIR="$ROOT_DIR" \
libdir_relative_to_bindir=../lib

@ -1,30 +0,0 @@
#!/bin/bash
# Copyright (c) Facebook, Inc. and its affiliates.
#
# This source code is licensed under the MIT license found in the
# LICENSE file in the root directory of this source tree.
# Usage: set_libso_path.sh [LIBSO_DIR] [TARGET]
#
# This changes MacOSX's executable [TARGET] to use shared libraries in
# [LIBSO_DIR] when rpath has been set to [LIBSO_DIR].
set -e
set -o pipefail
set -u
LIBSO_DIR=$1
TARGET=$2
TMP=$( mktemp )
trap "rm $TMP" EXIT
otool -L "$TARGET" | tail -n +2 > "$TMP"
while IFS='' read -r line || [[ -n "$line" ]]; do
LIB_PATH=$( echo $line | awk '{print $1}' )
LIB_FILE=$( basename "${LIB_PATH}" )
if [ -f "${LIBSO_DIR}/${LIB_FILE}" ]; then
install_name_tool -change "${LIB_PATH}" "@rpath/${LIB_FILE}" "$TARGET"
fi
done < "$TMP"
Loading…
Cancel
Save