(* * Copyright (c) 2016 - 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 module F = Format module TraceElem = struct module Kind = struct type t = AccessPath.raw let compare = AccessPath.compare_raw let pp = AccessPath.pp_raw end type t = { site : CallSite.t; kind : Kind.t; } [@@deriving compare] let call_site { site; } = site let kind { kind; } = kind let make kind site = { kind; site; } let with_callsite t site = { t with site; } let pp fmt { site; kind; } = F.fprintf fmt "Unprotected access to %a at %a" Kind.pp kind CallSite.pp site module Set = PrettyPrintable.MakePPSet (struct type nonrec t = t let compare = compare let pp_element = pp end) end let make_access kind loc = let site = CallSite.make Procname.empty_block loc in TraceElem.make kind site (** A bool that is true if a lock is definitely held. Note that this is unsound because it assumes the existence of one global lock. In the case that a lock is held on the access to a variable, but the lock held is the wrong one, we will erroneously say that the access is thread-safe. However, this coarse abstraction saves us from the complexity of tracking which locks are held and which memory locations correspond to the same lock. *) module LocksDomain = AbstractDomain.BooleanAnd module PathDomain = SinkTrace.Make(TraceElem) module ReadWriteDomain = AbstractDomain.Pair (PathDomain) (PathDomain) include AbstractDomain.Pair (LocksDomain) (ReadWriteDomain) (* This is the ThreadSafety abstract domain *) (* a typical element is (){locked}, {vars and fields}) *)