[pulse] move PulseInvalidation inside PulseDomain

Summary:
Just moving code around.

This is needed later to make some types in `PulseInvalidation` depend on
a new type that I'll have to define in `PulseDomain`.

Reviewed By: mbouaziz

Differential Revision: D15824962

fbshipit-source-id: 86cba2bfb
master
Jules Villard 6 years ago committed by Facebook Github Bot
parent 457b017343
commit 512b42ece7

@ -46,14 +46,17 @@ module Memory : sig
HilExp.AccessExpression.t PulseTrace.action HilExp.AccessExpression.t PulseTrace.action
-> AbstractAddress.t -> AbstractAddress.t
-> t -> t
-> (t, PulseInvalidation.t PulseTrace.t) result -> (t, PulseDomain.Invalidation.t PulseTrace.t) result
val find_opt : AbstractAddress.t -> t -> PulseDomain.Memory.cell option val find_opt : AbstractAddress.t -> t -> PulseDomain.Memory.cell option
val set_cell : AbstractAddress.t -> PulseDomain.Memory.cell -> t -> t val set_cell : AbstractAddress.t -> PulseDomain.Memory.cell -> t -> t
val invalidate : val invalidate :
AbstractAddress.t * PulseTrace.breadcrumbs -> PulseInvalidation.t PulseTrace.action -> t -> t AbstractAddress.t * PulseTrace.breadcrumbs
-> PulseDomain.Invalidation.t PulseTrace.action
-> t
-> t
val is_std_vector_reserved : AbstractAddress.t -> t -> bool val is_std_vector_reserved : AbstractAddress.t -> t -> bool

@ -11,7 +11,7 @@ module F = Format
type t = type t =
| AccessToInvalidAddress of | AccessToInvalidAddress of
{ access: HilExp.AccessExpression.t { access: HilExp.AccessExpression.t
; invalidated_by: PulseInvalidation.t PulseTrace.t ; invalidated_by: PulseDomain.Invalidation.t PulseTrace.t
; accessed_by: HilExp.AccessExpression.t PulseTrace.t } ; accessed_by: HilExp.AccessExpression.t PulseTrace.t }
| StackVariableAddressEscape of | StackVariableAddressEscape of
{ variable: Var.t { variable: Var.t
@ -86,10 +86,10 @@ let get_message = function
let pp_invalidation_trace line f trace = let pp_invalidation_trace line f trace =
match trace.PulseTrace.action with match trace.PulseTrace.action with
| Immediate {imm= invalidation; _} -> | Immediate {imm= invalidation; _} ->
F.fprintf f "%a on line %d" PulseInvalidation.describe invalidation line F.fprintf f "%a on line %d" PulseDomain.Invalidation.describe invalidation line
| ViaCall {action; proc_name; _} -> | ViaCall {action; proc_name; _} ->
F.fprintf f "%a on line %d indirectly during the call to `%a`" F.fprintf f "%a on line %d indirectly during the call to `%a`"
PulseInvalidation.describe PulseDomain.Invalidation.describe
(PulseTrace.immediate_of_action action) (PulseTrace.immediate_of_action action)
line Typ.Procname.describe proc_name line Typ.Procname.describe proc_name
in in
@ -112,7 +112,8 @@ let get_message = function
let get_trace = function let get_trace = function
| AccessToInvalidAddress {accessed_by; invalidated_by} -> | AccessToInvalidAddress {accessed_by; invalidated_by} ->
PulseTrace.add_to_errlog ~header:"invalidation part of the trace starts here" PulseTrace.add_to_errlog ~header:"invalidation part of the trace starts here"
(fun f invalidation -> F.fprintf f "memory %a" PulseInvalidation.describe invalidation) (fun f invalidation ->
F.fprintf f "memory %a" PulseDomain.Invalidation.describe invalidation )
invalidated_by invalidated_by
@@ PulseTrace.add_to_errlog ~header:"use-after-lifetime part of the trace starts here" @@ PulseTrace.add_to_errlog ~header:"use-after-lifetime part of the trace starts here"
(fun f access -> F.fprintf f "invalid access to `%a`" HilExp.AccessExpression.pp access) (fun f access -> F.fprintf f "invalid access to `%a`" HilExp.AccessExpression.pp access)
@ -127,6 +128,7 @@ let get_trace = function
let get_issue_type = function let get_issue_type = function
| AccessToInvalidAddress {invalidated_by} -> | AccessToInvalidAddress {invalidated_by} ->
PulseTrace.immediate_of_action invalidated_by.action |> PulseInvalidation.issue_type_of_cause PulseTrace.immediate_of_action invalidated_by.action
|> PulseDomain.Invalidation.issue_type_of_cause
| StackVariableAddressEscape _ -> | StackVariableAddressEscape _ ->
IssueType.stack_variable_address_escape IssueType.stack_variable_address_escape

@ -11,7 +11,7 @@ open! IStd
type t = type t =
| AccessToInvalidAddress of | AccessToInvalidAddress of
{ access: HilExp.AccessExpression.t { access: HilExp.AccessExpression.t
; invalidated_by: PulseInvalidation.t PulseTrace.t ; invalidated_by: PulseDomain.Invalidation.t PulseTrace.t
; accessed_by: HilExp.AccessExpression.t PulseTrace.t } ; accessed_by: HilExp.AccessExpression.t PulseTrace.t }
| StackVariableAddressEscape of | StackVariableAddressEscape of
{ variable: Var.t { variable: Var.t

@ -7,10 +7,95 @@
open! IStd open! IStd
module F = Format module F = Format
module L = Logging module L = Logging
module Invalidation = PulseInvalidation
(* {2 Abstract domain description } *) (* {2 Abstract domain description } *)
module Invalidation = struct
type std_vector_function =
| Assign
| Clear
| Emplace
| EmplaceBack
| Insert
| PushBack
| Reserve
| ShrinkToFit
[@@deriving compare]
let pp_std_vector_function f = function
| Assign ->
F.fprintf f "std::vector::assign"
| Clear ->
F.fprintf f "std::vector::clear"
| Emplace ->
F.fprintf f "std::vector::emplace"
| EmplaceBack ->
F.fprintf f "std::vector::emplace_back"
| Insert ->
F.fprintf f "std::vector::insert"
| PushBack ->
F.fprintf f "std::vector::push_back"
| Reserve ->
F.fprintf f "std::vector::reserve"
| ShrinkToFit ->
F.fprintf f "std::vector::shrink_to_fit"
type t =
| CFree of HilExp.AccessExpression.t
| CppDelete of HilExp.AccessExpression.t
| GoneOutOfScope of Pvar.t * Typ.t
| Nullptr
| StdVector of std_vector_function * HilExp.AccessExpression.t
[@@deriving compare]
let issue_type_of_cause = function
| CFree _ ->
IssueType.use_after_free
| CppDelete _ ->
IssueType.use_after_delete
| GoneOutOfScope _ ->
IssueType.use_after_lifetime
| Nullptr ->
IssueType.null_dereference
| StdVector _ ->
IssueType.vector_invalidation
let describe f = function
| CFree access_expr ->
F.fprintf f "was invalidated by call to `free()` on `%a`" HilExp.AccessExpression.pp
access_expr
| CppDelete access_expr ->
F.fprintf f "was invalidated by `delete` on `%a`" HilExp.AccessExpression.pp access_expr
| GoneOutOfScope (pvar, typ) ->
let pp_var f pvar =
if Pvar.is_cpp_temporary pvar then
F.fprintf f "is the address of a C++ temporary of type `%a`" (Typ.pp_full Pp.text) typ
else F.fprintf f "is the address of a stack variable `%a`" Pvar.pp_value pvar
in
F.fprintf f "%a whose lifetime has ended" pp_var pvar
| Nullptr ->
F.fprintf f "is the null pointer"
| StdVector (std_vector_f, access_expr) ->
F.fprintf f "was potentially invalidated by `%a()` on `%a`" pp_std_vector_function
std_vector_f HilExp.AccessExpression.pp access_expr
let pp f invalidation =
match invalidation with
| CFree _ ->
F.fprintf f "CFree(%a)" describe invalidation
| CppDelete _ ->
F.fprintf f "CppDelete(%a)" describe invalidation
| GoneOutOfScope _ ->
describe f invalidation
| Nullptr ->
describe f invalidation
| StdVector _ ->
F.fprintf f "StdVector(%a)" describe invalidation
end
(** Purposefully declared before [AbstractAddress] to avoid attributes depending on (** Purposefully declared before [AbstractAddress] to avoid attributes depending on
addresses. Otherwise they become a pain to handle when comparing memory states. *) addresses. Otherwise they become a pain to handle when comparing memory states. *)
module Attribute = struct module Attribute = struct

@ -8,9 +8,36 @@
open! IStd open! IStd
module F = Format module F = Format
module Invalidation : sig
type std_vector_function =
| Assign
| Clear
| Emplace
| EmplaceBack
| Insert
| PushBack
| Reserve
| ShrinkToFit
[@@deriving compare]
val pp_std_vector_function : Format.formatter -> std_vector_function -> unit
type t =
| CFree of HilExp.AccessExpression.t
| CppDelete of HilExp.AccessExpression.t
| GoneOutOfScope of Pvar.t * Typ.t
| Nullptr
| StdVector of std_vector_function * HilExp.AccessExpression.t
[@@deriving compare]
val issue_type_of_cause : t -> IssueType.t
val describe : Format.formatter -> t -> unit
end
module Attribute : sig module Attribute : sig
type t = type t =
| Invalid of PulseInvalidation.t PulseTrace.t | Invalid of Invalidation.t PulseTrace.t
| MustBeValid of HilExp.AccessExpression.t PulseTrace.action | MustBeValid of HilExp.AccessExpression.t PulseTrace.action
| AddressOfCppTemporary of Var.t * Location.t option | AddressOfCppTemporary of Var.t * Location.t option
| Closure of Typ.Procname.t | Closure of Typ.Procname.t
@ -94,9 +121,9 @@ module Memory : sig
val add_attributes : AbstractAddress.t -> Attributes.t -> t -> t val add_attributes : AbstractAddress.t -> Attributes.t -> t -> t
val invalidate : val invalidate :
AbstractAddress.t * PulseTrace.breadcrumbs -> PulseInvalidation.t PulseTrace.action -> t -> t AbstractAddress.t * PulseTrace.breadcrumbs -> Invalidation.t PulseTrace.action -> t -> t
val check_valid : AbstractAddress.t -> t -> (unit, PulseInvalidation.t PulseTrace.t) result val check_valid : AbstractAddress.t -> t -> (unit, Invalidation.t PulseTrace.t) result
val std_vector_reserve : AbstractAddress.t -> t -> t val std_vector_reserve : AbstractAddress.t -> t -> t

@ -1,92 +0,0 @@
(*
* 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
type std_vector_function =
| Assign
| Clear
| Emplace
| EmplaceBack
| Insert
| PushBack
| Reserve
| ShrinkToFit
[@@deriving compare]
let pp_std_vector_function f = function
| Assign ->
F.fprintf f "std::vector::assign"
| Clear ->
F.fprintf f "std::vector::clear"
| Emplace ->
F.fprintf f "std::vector::emplace"
| EmplaceBack ->
F.fprintf f "std::vector::emplace_back"
| Insert ->
F.fprintf f "std::vector::insert"
| PushBack ->
F.fprintf f "std::vector::push_back"
| Reserve ->
F.fprintf f "std::vector::reserve"
| ShrinkToFit ->
F.fprintf f "std::vector::shrink_to_fit"
type t =
| CFree of HilExp.AccessExpression.t
| CppDelete of HilExp.AccessExpression.t
| GoneOutOfScope of Pvar.t * Typ.t
| Nullptr
| StdVector of std_vector_function * HilExp.AccessExpression.t
[@@deriving compare]
let issue_type_of_cause = function
| CFree _ ->
IssueType.use_after_free
| CppDelete _ ->
IssueType.use_after_delete
| GoneOutOfScope _ ->
IssueType.use_after_lifetime
| Nullptr ->
IssueType.null_dereference
| StdVector _ ->
IssueType.vector_invalidation
let describe f = function
| CFree access_expr ->
F.fprintf f "was invalidated by call to `free()` on `%a`" HilExp.AccessExpression.pp
access_expr
| CppDelete access_expr ->
F.fprintf f "was invalidated by `delete` on `%a`" HilExp.AccessExpression.pp access_expr
| GoneOutOfScope (pvar, typ) ->
let pp_var f pvar =
if Pvar.is_cpp_temporary pvar then
F.fprintf f "is the address of a C++ temporary of type `%a`" (Typ.pp_full Pp.text) typ
else F.fprintf f "is the address of a stack variable `%a`" Pvar.pp_value pvar
in
F.fprintf f "%a whose lifetime has ended" pp_var pvar
| Nullptr ->
F.fprintf f "is the null pointer"
| StdVector (std_vector_f, access_expr) ->
F.fprintf f "was potentially invalidated by `%a()` on `%a`" pp_std_vector_function
std_vector_f HilExp.AccessExpression.pp access_expr
let pp f invalidation =
match invalidation with
| CFree _ ->
F.fprintf f "CFree(%a)" describe invalidation
| CppDelete _ ->
F.fprintf f "CppDelete(%a)" describe invalidation
| GoneOutOfScope _ ->
describe f invalidation
| Nullptr ->
describe f invalidation
| StdVector _ ->
F.fprintf f "StdVector(%a)" describe invalidation

@ -1,34 +0,0 @@
(*
* 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
type std_vector_function =
| Assign
| Clear
| Emplace
| EmplaceBack
| Insert
| PushBack
| Reserve
| ShrinkToFit
[@@deriving compare]
val pp_std_vector_function : Format.formatter -> std_vector_function -> unit
type t =
| CFree of HilExp.AccessExpression.t
| CppDelete of HilExp.AccessExpression.t
| GoneOutOfScope of Pvar.t * Typ.t
| Nullptr
| StdVector of std_vector_function * HilExp.AccessExpression.t
[@@deriving compare]
val issue_type_of_cause : t -> IssueType.t
val describe : Format.formatter -> t -> unit
val pp : Format.formatter -> t -> unit

@ -26,7 +26,7 @@ module C = struct
match actuals with match actuals with
| [AccessExpression deleted_access] -> | [AccessExpression deleted_access] ->
PulseOperations.invalidate PulseOperations.invalidate
(PulseTrace.Immediate {imm= PulseInvalidation.CFree deleted_access; location}) (PulseTrace.Immediate {imm= PulseDomain.Invalidation.CFree deleted_access; location})
location deleted_access astate location deleted_access astate
>>| List.return >>| List.return
| _ -> | _ ->
@ -41,7 +41,7 @@ module Cplusplus = struct
match actuals with match actuals with
| [AccessExpression deleted_access] -> | [AccessExpression deleted_access] ->
PulseOperations.invalidate PulseOperations.invalidate
(PulseTrace.Immediate {imm= PulseInvalidation.CppDelete deleted_access; location}) (PulseTrace.Immediate {imm= PulseDomain.Invalidation.CppDelete deleted_access; location})
location deleted_access astate location deleted_access astate
>>| List.return >>| List.return
| _ -> | _ ->
@ -104,7 +104,7 @@ module StdVector = struct
let array_address = to_internal_array vector in let array_address = to_internal_array vector in
let array = deref_internal_array vector in let array = deref_internal_array vector in
let invalidation = let invalidation =
PulseTrace.Immediate {imm= PulseInvalidation.StdVector (vector_f, vector); location} PulseTrace.Immediate {imm= PulseDomain.Invalidation.StdVector (vector_f, vector); location}
in in
PulseOperations.invalidate_array_elements invalidation location array astate PulseOperations.invalidate_array_elements invalidation location array astate
>>= PulseOperations.invalidate invalidation location array >>= PulseOperations.invalidate invalidation location array
@ -117,7 +117,9 @@ module StdVector = struct
| AccessExpression vector :: _ -> | AccessExpression vector :: _ ->
let crumb = let crumb =
PulseTrace.Call PulseTrace.Call
{ f= `Model (Format.asprintf "%a" PulseInvalidation.pp_std_vector_function vector_f) { f=
`Model
(Format.asprintf "%a" PulseDomain.Invalidation.pp_std_vector_function vector_f)
; actuals ; actuals
; location } ; location }
in in

@ -62,14 +62,14 @@ val write :
-> t access_result -> t access_result
val invalidate : val invalidate :
PulseInvalidation.t PulseTrace.action PulseDomain.Invalidation.t PulseTrace.action
-> Location.t -> Location.t
-> HilExp.AccessExpression.t -> HilExp.AccessExpression.t
-> t -> t
-> t access_result -> t access_result
val invalidate_array_elements : val invalidate_array_elements :
PulseInvalidation.t PulseTrace.action PulseDomain.Invalidation.t PulseTrace.action
-> Location.t -> Location.t
-> HilExp.AccessExpression.t -> HilExp.AccessExpression.t
-> t -> t

Loading…
Cancel
Save