Summary: See explanations in D17955104. I put Attributes inside PulseAttribute instead of creating a new file to avoid exposing more internals about ranks. Reviewed By: ezgicicek Differential Revision: D17955284 fbshipit-source-id: a8719a58fmaster
parent
27c0d7258d
commit
994d35ed38
@ -0,0 +1,144 @@
|
|||||||
|
(*
|
||||||
|
* 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.
|
||||||
|
*)
|
||||||
|
open! IStd
|
||||||
|
module F = Format
|
||||||
|
module Invalidation = PulseInvalidation
|
||||||
|
module Trace = PulseTrace
|
||||||
|
module ValueHistory = PulseValueHistory
|
||||||
|
|
||||||
|
(** Make sure we don't depend on {!AbstractAddress} to avoid attributes depending on
|
||||||
|
addresses. Otherwise they become a pain to handle when comparing memory states.
|
||||||
|
|
||||||
|
If you find you need to make attributes depend on {!AbstractAddress} then remember to modify
|
||||||
|
graph operations of {!PulseDomain} and the interprocedural operations in {!PulseAbductiveDomain}
|
||||||
|
*)
|
||||||
|
include struct
|
||||||
|
[@@@warning "-60"]
|
||||||
|
|
||||||
|
module AbstractAddress = struct end
|
||||||
|
|
||||||
|
module PulseAbstractAddress = struct end
|
||||||
|
end
|
||||||
|
|
||||||
|
module Attribute = struct
|
||||||
|
type t =
|
||||||
|
| AddressOfCppTemporary of Var.t * ValueHistory.t
|
||||||
|
| AddressOfStackVariable of Var.t * Location.t * ValueHistory.t
|
||||||
|
| Closure of Typ.Procname.t
|
||||||
|
| Constant of Const.t
|
||||||
|
| Invalid of Invalidation.t Trace.t
|
||||||
|
| MustBeValid of unit Trace.t
|
||||||
|
| StdVectorReserve
|
||||||
|
| WrittenTo of unit Trace.t
|
||||||
|
[@@deriving compare, variants]
|
||||||
|
|
||||||
|
let equal = [%compare.equal: t]
|
||||||
|
|
||||||
|
let to_rank = Variants.to_rank
|
||||||
|
|
||||||
|
let mk_dummy_trace imm = Trace.Immediate {imm; location= Location.dummy; history= []}
|
||||||
|
|
||||||
|
let closure_rank = Variants.to_rank (Closure (Typ.Procname.from_string_c_fun ""))
|
||||||
|
|
||||||
|
let written_to_rank = Variants.to_rank (WrittenTo (mk_dummy_trace ()))
|
||||||
|
|
||||||
|
let address_of_stack_variable_rank =
|
||||||
|
let pname = Typ.Procname.from_string_c_fun "" in
|
||||||
|
let var = Var.of_pvar (Pvar.mk (Mangled.from_string "") pname) in
|
||||||
|
let location = Location.dummy in
|
||||||
|
Variants.to_rank (AddressOfStackVariable (var, location, []))
|
||||||
|
|
||||||
|
|
||||||
|
let invalid_rank = Variants.to_rank (Invalid (mk_dummy_trace Invalidation.Nullptr))
|
||||||
|
|
||||||
|
let must_be_valid_rank = Variants.to_rank (MustBeValid (mk_dummy_trace ()))
|
||||||
|
|
||||||
|
let std_vector_reserve_rank = Variants.to_rank StdVectorReserve
|
||||||
|
|
||||||
|
let const_rank = Variants.to_rank (Constant (Const.Cint IntLit.zero))
|
||||||
|
|
||||||
|
let pp f attribute =
|
||||||
|
let pp_string_if_debug string fmt () =
|
||||||
|
if Config.debug_level_analysis >= 3 then F.pp_print_string fmt string
|
||||||
|
in
|
||||||
|
match attribute with
|
||||||
|
| AddressOfCppTemporary (var, history) ->
|
||||||
|
F.fprintf f "t&%a (%a)" Var.pp var ValueHistory.pp history
|
||||||
|
| AddressOfStackVariable (var, location, history) ->
|
||||||
|
F.fprintf f "s&%a (%a) at %a" Var.pp var ValueHistory.pp history Location.pp location
|
||||||
|
| Closure pname ->
|
||||||
|
Typ.Procname.pp f pname
|
||||||
|
| Constant c ->
|
||||||
|
F.fprintf f "=%a" (Const.pp Pp.text) c
|
||||||
|
| Invalid invalidation ->
|
||||||
|
F.fprintf f "Invalid %a" (Trace.pp Invalidation.pp) invalidation
|
||||||
|
| MustBeValid action ->
|
||||||
|
F.fprintf f "MustBeValid %a" (Trace.pp (pp_string_if_debug "access")) action
|
||||||
|
| StdVectorReserve ->
|
||||||
|
F.pp_print_string f "std::vector::reserve()"
|
||||||
|
| WrittenTo action ->
|
||||||
|
F.fprintf f "WrittenTo %a" (Trace.pp (pp_string_if_debug "mutation")) action
|
||||||
|
end
|
||||||
|
|
||||||
|
module Attributes = struct
|
||||||
|
module Set = PrettyPrintable.MakePPUniqRankSet (Attribute)
|
||||||
|
|
||||||
|
let get_invalid attrs =
|
||||||
|
Set.find_rank attrs Attribute.invalid_rank
|
||||||
|
|> Option.map ~f:(fun attr ->
|
||||||
|
let[@warning "-8"] (Attribute.Invalid invalidation) = attr in
|
||||||
|
invalidation )
|
||||||
|
|
||||||
|
|
||||||
|
let get_must_be_valid attrs =
|
||||||
|
Set.find_rank attrs Attribute.must_be_valid_rank
|
||||||
|
|> Option.map ~f:(fun attr ->
|
||||||
|
let[@warning "-8"] (Attribute.MustBeValid action) = attr in
|
||||||
|
action )
|
||||||
|
|
||||||
|
|
||||||
|
let get_written_to attrs =
|
||||||
|
Set.find_rank attrs Attribute.written_to_rank
|
||||||
|
|> Option.map ~f:(fun attr ->
|
||||||
|
let[@warning "-8"] (Attribute.WrittenTo action) = attr in
|
||||||
|
action )
|
||||||
|
|
||||||
|
|
||||||
|
let get_closure_proc_name attrs =
|
||||||
|
Set.find_rank attrs Attribute.closure_rank
|
||||||
|
|> Option.map ~f:(fun attr ->
|
||||||
|
let[@warning "-8"] (Attribute.Closure proc_name) = attr in
|
||||||
|
proc_name )
|
||||||
|
|
||||||
|
|
||||||
|
let get_address_of_stack_variable attrs =
|
||||||
|
Set.find_rank attrs Attribute.address_of_stack_variable_rank
|
||||||
|
|> Option.map ~f:(fun attr ->
|
||||||
|
let[@warning "-8"] (Attribute.AddressOfStackVariable (var, loc, history)) = attr in
|
||||||
|
(var, loc, history) )
|
||||||
|
|
||||||
|
|
||||||
|
let is_std_vector_reserved attrs =
|
||||||
|
Set.find_rank attrs Attribute.std_vector_reserve_rank |> Option.is_some
|
||||||
|
|
||||||
|
|
||||||
|
let is_modified attrs =
|
||||||
|
Option.is_some (Set.find_rank attrs Attribute.written_to_rank)
|
||||||
|
|| Option.is_some (Set.find_rank attrs Attribute.invalid_rank)
|
||||||
|
|
||||||
|
|
||||||
|
let get_constant attrs =
|
||||||
|
Set.find_rank attrs Attribute.const_rank
|
||||||
|
|> Option.map ~f:(fun attr ->
|
||||||
|
let[@warning "-8"] (Attribute.Constant c) = attr in
|
||||||
|
c )
|
||||||
|
|
||||||
|
|
||||||
|
include Set
|
||||||
|
end
|
||||||
|
|
||||||
|
include Attribute
|
@ -0,0 +1,41 @@
|
|||||||
|
(*
|
||||||
|
* 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.
|
||||||
|
*)
|
||||||
|
open! IStd
|
||||||
|
module Invalidation = PulseInvalidation
|
||||||
|
module Trace = PulseTrace
|
||||||
|
module ValueHistory = PulseValueHistory
|
||||||
|
|
||||||
|
type t =
|
||||||
|
| AddressOfCppTemporary of Var.t * ValueHistory.t
|
||||||
|
| AddressOfStackVariable of Var.t * Location.t * ValueHistory.t
|
||||||
|
| Closure of Typ.Procname.t
|
||||||
|
| Constant of Const.t
|
||||||
|
| Invalid of Invalidation.t Trace.t
|
||||||
|
| MustBeValid of unit Trace.t
|
||||||
|
| StdVectorReserve
|
||||||
|
| WrittenTo of unit Trace.t
|
||||||
|
[@@deriving compare]
|
||||||
|
|
||||||
|
module Attributes : sig
|
||||||
|
include PrettyPrintable.PPUniqRankSet with type elt = t
|
||||||
|
|
||||||
|
val get_address_of_stack_variable : t -> (Var.t * Location.t * ValueHistory.t) option
|
||||||
|
|
||||||
|
val get_closure_proc_name : t -> Typ.Procname.t option
|
||||||
|
|
||||||
|
val get_constant : t -> Const.t option
|
||||||
|
|
||||||
|
val get_invalid : t -> Invalidation.t Trace.t option
|
||||||
|
|
||||||
|
val get_must_be_valid : t -> unit Trace.t option
|
||||||
|
|
||||||
|
val get_written_to : t -> unit Trace.t option
|
||||||
|
|
||||||
|
val is_modified : t -> bool
|
||||||
|
|
||||||
|
val is_std_vector_reserved : t -> bool
|
||||||
|
end
|
Loading…
Reference in new issue