Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Use AddressDomain for MayPointTo and ReachableFrom queries #1142

Merged
merged 58 commits into from
Sep 18, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
58 commits
Select commit Hold shift + click to select a range
24c07c4
Add MayPointTo query with address domain
karoliineh Aug 22, 2023
0ecf575
Use MayPointToA in mutexEventAnalysis
karoliineh Aug 22, 2023
fb43b5f
Use MayPointToA in threadEscape
karoliineh Aug 22, 2023
e1263bc
Use MayPointToA in memLeak
karoliineh Aug 22, 2023
eb951b6
Use MayPointToA in mutexTypeAnalysis
karoliineh Aug 22, 2023
4bd38f5
Use MayPointToA in pthreadSignals
karoliineh Aug 22, 2023
68f5bb2
Use MayPointToA in useAfterFree
karoliineh Aug 22, 2023
940a771
Use MayPointToA in relationAnalysis
karoliineh Aug 22, 2023
ca39daf
Add mutex addr to unlock warning
karoliineh Aug 22, 2023
158a450
Use MayPointToA in relationAnalysis cont.
karoliineh Aug 22, 2023
4bfa786
Add TODO for removing fold from memLeak
karoliineh Aug 22, 2023
71789d1
Use MayPointToA in useAfterFree cont.
karoliineh Aug 22, 2023
3cbd31f
Use MayPointToA in varEq
karoliineh Aug 22, 2023
b5f6c4b
Use MayPointToA in uninit
karoliineh Aug 22, 2023
8937455
Use MayPointToA in spec
karoliineh Aug 22, 2023
e417443
Use MayPointToA in mallocFresh
karoliineh Aug 22, 2023
16f3500
Use MayPointToA in malloc_null
karoliineh Aug 22, 2023
68d6588
Use MayPointToA in fileUse
karoliineh Aug 22, 2023
e697504
Use MayPointToA in extractPthread
karoliineh Aug 22, 2023
076da53
Use MayPointToA in condVars
karoliineh Aug 22, 2023
1c7186c
Use MayPointToA in mvalMapDomain
karoliineh Aug 22, 2023
f7b38a0
Add ReachableFrom query with address domain
karoliineh Aug 22, 2023
b49f0e0
Use MayPointToA and ReachableFromA in accessAnalysis
karoliineh Aug 22, 2023
20b75c6
Use MayPointToA and ReachableFromA in varEq
karoliineh Aug 22, 2023
5e8e2c7
Make getaddrinfo specification more precise
sim642 Aug 23, 2023
e079212
Remove unnecessary offset double conversions
sim642 Aug 23, 2023
2f4119d
Use AddressDomain helper functions for to_mval and to_var_may
sim642 Aug 23, 2023
cfab28c
Use ReachableFromA in extractPthread
karoliineh Aug 23, 2023
178a9c6
Remove duplicated Tasks module from extractPthread
karoliineh Aug 23, 2023
08c9f1d
Use ReachableFromA in malloc_null
karoliineh Aug 23, 2023
5dbfb02
Use ReachableFromA in poisonVariables
karoliineh Aug 23, 2023
de9c475
Use ReachableFromA in threadEscape
karoliineh Aug 23, 2023
2cd0ae6
Extract to_extra fun from fold in malloc_null
karoliineh Aug 23, 2023
e4bef9c
Use ReachableFromA in uninit
karoliineh Aug 23, 2023
973edf6
Use ReachableFromA in useAfterFree
karoliineh Aug 23, 2023
cf58111
Use ReachableFromA in relationAnalysis
karoliineh Aug 23, 2023
2e4b9f3
Refactor everything until memLeak
karoliineh Aug 25, 2023
641de7d
Refactor everything after memLeak
karoliineh Aug 25, 2023
f3c3d18
Use MayPointToA and ReachableFromA in taindPartialContexts
karoliineh Aug 25, 2023
22da3df
Use MayPointToA for may_point_to in queries
karoliineh Aug 25, 2023
5cf96d1
Remove MayPointTo and ReachableFrom queries with LS
karoliineh Aug 25, 2023
9291c8a
Rename MayPointToA -> MayPointTo
karoliineh Aug 25, 2023
43223d0
Rename ReachableFromA -> ReachableFrom
karoliineh Aug 25, 2023
866f517
Rename a -> ad, where missed
karoliineh Aug 25, 2023
57549d0
Simplify cardinal > 0 to not is_empty
karoliineh Aug 25, 2023
3cbc8e7
Remove done TODO from uninit
karoliineh Aug 28, 2023
6bfb97b
Use AddressDomain for queries in base
karoliineh Aug 28, 2023
5938225
Remove unneccessary module calls before AD and Addr in base
karoliineh Aug 28, 2023
c8cc6c4
Add TODOs about AddressDomain queries usage
sim642 Sep 11, 2023
7edb312
Simplify some AddressDomain query result manipulation
sim642 Sep 11, 2023
3e01426
Cherry-pick AddressDomain.filter from 224615f63b07448ba45afb79f42c2d8…
sim642 Sep 11, 2023
bb8a926
Merge branch 'master' into queries-ad
sim642 Sep 11, 2023
5583f04
Merge branch 'master' into queries-ad
karoliineh Sep 12, 2023
dce70e2
Add comment about unsoundness back to extractPthread
karoliineh Sep 12, 2023
0568edd
Simplify do_exp in uninit and malloc_null
karoliineh Sep 12, 2023
3ee9af8
Simplify remove_unreachable in uninit and malloc_null
karoliineh Sep 12, 2023
f18d808
D.remove instead of diffing singleton in memLeak
karoliineh Sep 13, 2023
64a0a6f
Merge branch 'master' into queries-ad
sim642 Sep 18, 2023
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
37 changes: 16 additions & 21 deletions src/analyses/accessAnalysis.ml
Original file line number Diff line number Diff line change
Expand Up @@ -34,8 +34,8 @@ struct
let do_access (ctx: (D.t, G.t, C.t, V.t) ctx) (kind:AccessKind.t) (reach:bool) (e:exp) =
if M.tracing then M.trace "access" "do_access %a %a %B\n" d_exp e AccessKind.pretty kind reach;
let reach_or_mpt: _ Queries.t = if reach then ReachableFrom e else MayPointTo e in
let ls = ctx.ask reach_or_mpt in
ctx.emit (Access {exp=e; lvals=ls; kind; reach})
let ad = ctx.ask reach_or_mpt in
ctx.emit (Access {exp=e; ad; kind; reach})

(** Three access levels:
+ [deref=false], [reach=false] - Access [exp] without dereferencing, used for all normal reads and all function call arguments.
Expand Down Expand Up @@ -137,25 +137,20 @@ struct

let event ctx e octx =
match e with
| Events.Access {lvals; kind; _} when !collect_local && !AnalysisState.postsolving ->
begin match lvals with
| ls when Queries.LS.is_top ls ->
let access: AccessDomain.Event.t = {var_opt = None; offs_opt = None; kind} in
ctx.sideg ctx.node (G.singleton access)
| ls ->
let events = Queries.LS.fold (fun (var, offs) acc ->
let coffs = Offset.Exp.to_cil offs in
let access: AccessDomain.Event.t =
if CilType.Varinfo.equal var dummyFunDec.svar then
{var_opt = None; offs_opt = (Some coffs); kind}
else
{var_opt = (Some var); offs_opt = (Some coffs); kind}
in
G.add access acc
) ls (G.empty ())
in
ctx.sideg ctx.node events
end
| Events.Access {ad; kind; _} when !collect_local && !AnalysisState.postsolving ->
let events = Queries.AD.fold (fun addr es ->
match addr with
| Queries.AD.Addr.Addr (var, offs) ->
let coffs = ValueDomain.Offs.to_cil offs in
let access: AccessDomain.Event.t = {var_opt = (Some var); offs_opt = (Some coffs); kind} in
G.add access es
| UnknownPtr ->
let access: AccessDomain.Event.t = {var_opt = None; offs_opt = None; kind} in
G.add access es
| _ -> es
) ad (G.empty ())
in
ctx.sideg ctx.node events
| _ ->
ctx.local
end
Expand Down
80 changes: 50 additions & 30 deletions src/analyses/apron/relationAnalysis.apron.ml
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ open Analyses
open RelationDomain

module M = Messages
module VS = SetDomain.Make (CilType.Varinfo)

module SpecFunctor (Priv: RelationPriv.S) (RD: RelationDomain.RD) (PCU: RelationPrecCompareUtil.Util) =
struct
Expand Down Expand Up @@ -157,15 +158,13 @@ struct
{st' with rel = rel''}
)
| (Mem v, NoOffset) ->
(let r = ask.f (Queries.MayPointTo v) in
match r with
| `Top ->
st
| `Lifted s ->
let lvals = Queries.LS.elements r in
let ass' = List.map (fun lv -> assign_to_global_wrapper ask getg sideg st (Mval.Exp.to_cil lv) f) lvals in
List.fold_right D.join ass' (D.bot ())
)
begin match ask.f (Queries.MayPointTo v) with
| ad when Queries.AD.is_top ad -> st
| ad ->
let mvals = Queries.AD.to_mval ad in
let ass' = List.map (fun mval -> assign_to_global_wrapper ask getg sideg st (ValueDomain.Addr.Mval.to_cil mval) f) mvals in
List.fold_right D.join ass' (D.bot ())
end
(* Ignoring all other assigns *)
| _ ->
st
Expand Down Expand Up @@ -217,12 +216,16 @@ struct
| CastE (t,e) -> CastE (t, inner e)
| Lval (Var v, off) -> Lval (Var v, off)
| Lval (Mem e, NoOffset) ->
(match ask (Queries.MayPointTo e) with
| a when not (Queries.LS.is_top a || Queries.LS.mem (dummyFunDec.svar, `NoOffset) a) && (Queries.LS.cardinal a) = 1 ->
Mval.Exp.to_cil_exp (Queries.LS.choose a)
(* It would be possible to do better here, exploiting e.g. that the things pointed to are known to be equal *)
(* see: https://github.com/goblint/analyzer/pull/742#discussion_r879099745 *)
| _ -> Lval (Mem e, NoOffset))
begin match ask (Queries.MayPointTo e) with
| ad when not (Queries.AD.is_top ad) && (Queries.AD.cardinal ad) = 1 ->
begin match Queries.AD.Addr.to_mval (Queries.AD.choose ad) with
| Some mval -> ValueDomain.Addr.Mval.to_cil_exp mval
| None -> Lval (Mem e, NoOffset)
end
(* It would be possible to do better here, exploiting e.g. that the things pointed to are known to be equal *)
(* see: https://github.com/goblint/analyzer/pull/742#discussion_r879099745 *)
| _ -> Lval (Mem e, NoOffset)
end
| e -> e (* TODO: Potentially recurse further? *)
in
inner e
Expand Down Expand Up @@ -268,7 +271,15 @@ struct
let any_local_reachable fundec reachable_from_args =
let locals = fundec.sformals @ fundec.slocals in
let locals_id = List.map (fun v -> v.vid) locals in
Queries.LS.exists (fun (v',_) -> List.mem v'.vid locals_id && RD.Tracked.varinfo_tracked v') reachable_from_args
VS.exists (fun v -> List.mem v.vid locals_id && RD.Tracked.varinfo_tracked v) reachable_from_args

let reachable_from_args ctx args =
let to_vs e =
ctx.ask (ReachableFrom e)
|> Queries.AD.to_var_may
|> VS.of_list
in
List.fold (fun vs e -> VS.join vs (to_vs e)) (VS.empty ()) args

let pass_to_callee fundec any_local_reachable var =
(* TODO: currently, we pass all locals of the caller to the callee, provided one of them is reachbale to preserve relationality *)
Expand All @@ -288,7 +299,6 @@ struct
|> List.filter (fun (x, _) -> RD.Tracked.varinfo_tracked x)
|> List.map (Tuple2.map1 RV.arg)
in
let reachable_from_args = List.fold (fun ls e -> Queries.LS.join ls (ctx.ask (ReachableFrom e))) (Queries.LS.empty ()) args in
let arg_vars = List.map fst arg_assigns in
let new_rel = RD.add_vars st.rel arg_vars in
(* RD.assign_exp_parallel_with new_rel arg_assigns; (* doesn't need to be parallel since exps aren't arg vars directly *) *)
Expand All @@ -304,6 +314,7 @@ struct
)
) new_rel arg_assigns
in
let reachable_from_args = reachable_from_args ctx args in
let any_local_reachable = any_local_reachable fundec reachable_from_args in
RD.remove_filter_with new_rel (fun var ->
match RV.find_metadata var with
Expand Down Expand Up @@ -366,16 +377,20 @@ struct

let combine_env ctx r fe f args fc fun_st (f_ask : Queries.ask) =
let st = ctx.local in
let reachable_from_args = List.fold (fun ls e -> Queries.LS.join ls (ctx.ask (ReachableFrom e))) (Queries.LS.empty ()) args in
let reachable_from_args = reachable_from_args ctx args in
let fundec = Node.find_fundec ctx.node in
if M.tracing then M.tracel "combine" "relation f: %a\n" CilType.Varinfo.pretty f.svar;
if M.tracing then M.tracel "combine" "relation formals: %a\n" (d_list "," CilType.Varinfo.pretty) f.sformals;
if M.tracing then M.tracel "combine" "relation args: %a\n" (d_list "," d_exp) args;
let new_fun_rel = RD.add_vars fun_st.rel (RD.vars st.rel) in
let arg_substitutes =
let filter_actuals (x,e) =
RD.Tracked.varinfo_tracked x
&& List.for_all (fun v -> not (VS.mem v reachable_from_args)) (Basetype.CilExp.get_vars e)
in
GobList.combine_short f.sformals args (* TODO: is it right to ignore missing formals/args? *)
(* Do not do replacement for actuals whose value may be modified after the call *)
|> List.filter (fun (x, e) -> RD.Tracked.varinfo_tracked x && List.for_all (fun v -> not (Queries.LS.exists (fun (v',_) -> v'.vid = v.vid) reachable_from_args)) (Basetype.CilExp.get_vars e))
|> List.filter filter_actuals
|> List.map (Tuple2.map1 RV.arg)
in
(* RD.substitute_exp_parallel_with new_fun_rel arg_substitutes; (* doesn't need to be parallel since exps aren't arg vars directly *) *)
Expand Down Expand Up @@ -438,13 +453,13 @@ struct
match st with
| None -> None
| Some st ->
let vs = ask.f (Queries.ReachableFrom e) in
if Queries.LS.is_top vs then
let ad = ask.f (Queries.ReachableFrom e) in
if Queries.AD.is_top ad then
None
else
Some (Queries.LS.join vs st)
Some (Queries.AD.join ad st)
in
List.fold_right reachable es (Some (Queries.LS.empty ()))
List.fold_right reachable es (Some (Queries.AD.empty ()))


let forget_reachable ctx st es =
Expand All @@ -456,9 +471,13 @@ struct
RD.vars st.rel
|> List.filter_map RV.to_cil_varinfo
|> List.map Cil.var
| Some rs ->
Queries.LS.elements rs
|> List.map Mval.Exp.to_cil
| Some ad ->
let to_cil addr rs =
match addr with
| Queries.AD.Addr.Addr mval -> (ValueDomain.Addr.Mval.to_cil mval) :: rs
| _ -> rs
in
Queries.AD.fold to_cil ad []
in
List.fold_left (fun st lval ->
invalidate_one ask ctx st lval
Expand Down Expand Up @@ -515,10 +534,11 @@ struct
| None -> st)
| _, _ ->
let lvallist e =
let s = ask.f (Queries.MayPointTo e) in
match s with
| `Top -> []
| `Lifted _ -> List.map Mval.Exp.to_cil (Queries.LS.elements s)
match ask.f (Queries.MayPointTo e) with
| ad when Queries.AD.is_top ad -> []
| ad ->
Queries.AD.to_mval ad
|> List.map ValueDomain.Addr.Mval.to_cil
in
let shallow_addrs = LibraryDesc.Accesses.find desc.accs { kind = Write; deep = false } args in
let deep_addrs = LibraryDesc.Accesses.find desc.accs { kind = Write; deep = true } args in
Expand Down
59 changes: 25 additions & 34 deletions src/analyses/base.ml
Original file line number Diff line number Diff line change
Expand Up @@ -108,7 +108,7 @@ struct
| (info,(value:VD.t))::xs ->
match value with
| Address t when hasAttribute "goblint_array_domain" info.vattr ->
let possibleVars = List.to_seq (PreValueDomain.AD.to_var_may t) in
let possibleVars = List.to_seq (AD.to_var_may t) in
Seq.fold_left (fun map arr -> VarMap.add arr (info.vattr) map) (pointedArrayMap xs) @@ Seq.filter (fun info -> isArrayType info.vtype) possibleVars
| _ -> pointedArrayMap xs
in
Expand Down Expand Up @@ -345,15 +345,15 @@ struct
if AD.is_definite x && AD.is_definite y then
let ax = AD.choose x in
let ay = AD.choose y in
let handle_address_is_multiple addr = begin match AD.Addr.to_var addr with
let handle_address_is_multiple addr = begin match Addr.to_var addr with
| Some v when a.f (Q.IsMultiple v) ->
if M.tracing then M.tracel "addr" "IsMultiple %a\n" CilType.Varinfo.pretty v;
None
| _ ->
Some true
end
in
match AD.Addr.semantic_equal ax ay with
match Addr.semantic_equal ax ay with
| Some true ->
if M.tracing then M.tracel "addr" "semantic_equal %a %a\n" AD.pretty x AD.pretty y;
handle_address_is_multiple ax
Expand Down Expand Up @@ -593,7 +593,7 @@ struct
| Struct n -> Struct (ValueDomain.Structs.map replace_val n)
| Union (f,v) -> Union (f,replace_val v)
| Blob (n,s,o) -> Blob (replace_val n,s,o)
| Address x -> Address (ValueDomain.AD.map ValueDomain.Addr.top_indices x)
| Address x -> Address (AD.map ValueDomain.Addr.top_indices x)
| x -> x
in
CPA.map replace_val st
Expand All @@ -613,16 +613,6 @@ struct
%> f (ContextUtil.should_keep ~isAttr:GobContext ~keepOption:"ana.base.context.interval" ~removeAttr:"base.no-interval" ~keepAttr:"base.interval" fd) drop_interval
%> f (ContextUtil.should_keep ~isAttr:GobContext ~keepOption:"ana.base.context.interval_set" ~removeAttr:"base.no-interval_set" ~keepAttr:"base.interval_set" fd) drop_intervalSet

(* TODO: Use AddressDomain for queries *)
let convertToQueryLval = function
| ValueDomain.AD.Addr.Addr (v,o) -> [v, Addr.Offs.to_exp o]
| _ -> []

let addrToLvalSet a =
let add x y = Q.LS.add y x in
try
AD.fold (fun e c -> List.fold_left add c (convertToQueryLval e)) a (Q.LS.empty ())
with SetDomain.Unsupported _ -> Q.LS.top ()

let reachable_top_pointers_types ctx (ps: AD.t) : Queries.TS.t =
let module TS = Queries.TS in
Expand Down Expand Up @@ -1262,9 +1252,10 @@ struct
(* ignore @@ printf "BlobSize %a MayPointTo %a\n" d_plainexp e VD.pretty p; *)
match p with
| Address a ->
let s = addrToLvalSet a in
(* If there's a non-heap var or an offset in the lval set, we answer with bottom *)
if ValueDomainQueries.LS.exists (fun (v, o) -> (not @@ ctx.ask (Queries.IsHeapVar v)) || o <> `NoOffset) s then
if AD.exists (function
| Addr (v,o) -> (not @@ ctx.ask (Queries.IsHeapVar v)) || o <> `NoOffset
| _ -> false) a then
Queries.Result.bot q
else (
let r = get ~full:true (Analyses.ask_of_ctx ctx) ctx.global ctx.local a None in
Expand All @@ -1277,11 +1268,7 @@ struct
end
| Q.MayPointTo e -> begin
match eval_rv_address (Analyses.ask_of_ctx ctx) ctx.global ctx.local e with
| Address a ->
let s = addrToLvalSet a in
if AD.mem Addr.UnknownPtr a
then Q.LS.add (dummyFunDec.svar, `NoOffset) s
else s
| Address a -> a
| Bot -> Queries.Result.bot q (* TODO: remove *)
| _ -> Queries.Result.top q
end
Expand All @@ -1298,14 +1285,10 @@ struct
| Top -> Queries.Result.top q
| Bot -> Queries.Result.bot q (* TODO: remove *)
| Address a ->
let a' = AD.remove Addr.UnknownPtr a in (* run reachable_vars without unknown just to be safe *)
let xs = List.map addrToLvalSet (reachable_vars (Analyses.ask_of_ctx ctx) [a'] ctx.global ctx.local) in
let addrs = List.fold_left (Q.LS.join) (Q.LS.empty ()) xs in
if AD.mem Addr.UnknownPtr a then
Q.LS.add (dummyFunDec.svar, `NoOffset) addrs (* add unknown back *)
else
addrs
| _ -> Q.LS.empty ()
let a' = AD.remove Addr.UnknownPtr a in (* run reachable_vars without unknown just to be safe: TODO why? *)
let addrs = reachable_vars (Analyses.ask_of_ctx ctx) [a'] ctx.global ctx.local in
List.fold_left (AD.join) (AD.empty ()) addrs
| _ -> AD.empty ()
end
| Q.ReachableUkTypes e -> begin
match eval_rv_address (Analyses.ask_of_ctx ctx) ctx.global ctx.local e with
Expand All @@ -1332,7 +1315,8 @@ struct
(* ignore @@ printf "EvalStr Address: %a -> %s (must %i, may %i)\n" d_plainexp e (VD.short 80 (Address a)) (List.length @@ AD.to_var_must a) (List.length @@ AD.to_var_may a); *)
begin match unrollType (Cilfacade.typeOf e) with
| TPtr(TInt(IChar, _), _) ->
let lval = Mval.Exp.to_cil @@ Q.LS.choose @@ addrToLvalSet a in
let mval = List.hd (AD.to_mval a) in
let lval = Addr.Mval.to_cil mval in
(try `Lifted (Bytes.to_string (Hashtbl.find char_array lval))
with Not_found -> Queries.Result.top q)
| _ -> (* what about ISChar and IUChar? *)
Expand Down Expand Up @@ -2010,14 +1994,21 @@ struct
invalidate ~deep:true ~ctx (Analyses.ask_of_ctx ctx) gs st' deep_addrs

let check_invalid_mem_dealloc ctx special_fn ptr =
let has_non_heap_var = AD.exists (function
| Addr (v,_) -> not (ctx.ask (Q.IsHeapVar v))
| _ -> false)
in
let has_non_zero_offset = AD.exists (function
| Addr (_,o) -> Offs.cmp_zero_offset o <> `MustZero
| _ -> false)
in
match eval_rv_address (Analyses.ask_of_ctx ctx) ctx.global ctx.local ptr with
| Address a ->
let points_to_set = addrToLvalSet a in
if Q.LS.is_top points_to_set then
if AD.is_top a then
M.warn ~category:(Behavior (Undefined InvalidMemoryDeallocation)) ~tags:[CWE 590] "Points-to set for pointer %a in function %s is top. Potentially invalid memory deallocation may occur" d_exp ptr special_fn.vname
else if (Q.LS.exists (fun (v, _) -> not (ctx.ask (Q.IsHeapVar v))) points_to_set) || (AD.mem Addr.UnknownPtr a) then
else if has_non_heap_var a then
M.warn ~category:(Behavior (Undefined InvalidMemoryDeallocation)) ~tags:[CWE 590] "Free of non-dynamically allocated memory in function %s for pointer %a" special_fn.vname d_exp ptr
else if Q.LS.exists (fun (_, o) -> Offset.Exp.cmp_zero_offset o <> `MustZero) points_to_set then
else if has_non_zero_offset a then
M.warn ~category:(Behavior (Undefined InvalidMemoryDeallocation)) ~tags:[CWE 761] "Free of memory not at start of buffer in function %s for pointer %a" special_fn.vname d_exp ptr
| _ -> M.warn ~category:MessageCategory.Analyzer "Pointer %a in function %s doesn't evaluate to a valid address." d_exp ptr special_fn.vname

Expand Down
20 changes: 10 additions & 10 deletions src/analyses/condVars.ml
Original file line number Diff line number Diff line change
Expand Up @@ -64,16 +64,16 @@ struct
let (>?) = Option.bind

let mayPointTo ctx exp =
match ctx.ask (Queries.MayPointTo exp) with
| a when not (Queries.LS.is_top a) && Queries.LS.cardinal a > 0 ->
let top_elt = (dummyFunDec.svar, `NoOffset) in
let a' = if Queries.LS.mem top_elt a then (
M.info ~category:Unsound "mayPointTo: query result for %a contains TOP!" d_exp exp; (* UNSOUND *)
Queries.LS.remove top_elt a
) else a
in
Queries.LS.elements a'
| _ -> []
let ad = ctx.ask (Queries.MayPointTo exp) in
let a' = if Queries.AD.mem UnknownPtr ad then (
M.info ~category:Unsound "mayPointTo: query result for %a contains TOP!" d_exp exp; (* UNSOUND *)
Queries.AD.remove UnknownPtr ad
) else ad
in
List.filter_map (function
| ValueDomain.Addr.Addr (v,o) -> Some (v, ValueDomain.Addr.Offs.to_exp o) (* TODO: use unconverted addrs in domain? *)
| _ -> None
) (Queries.AD.elements a')

let mustPointTo ctx exp = (* this is just to get Mval.Exp *)
match mayPointTo ctx exp with
Expand Down
Loading
Loading