From 33c4faca8f32f343b3c252b067dd04a8f79097c2 Mon Sep 17 00:00:00 2001 From: Allan Blanchard <allan.blanchard@cea.fr> Date: Mon, 15 Feb 2021 17:13:08 +0100 Subject: [PATCH] [wp] Dispatch nullable in Factory --- src/plugins/wp/Factory.ml | 15 +++++++++++---- src/plugins/wp/MemVar.ml | 14 +++++++------- src/plugins/wp/MemoryContext.ml | 32 +++++++++++++++++++++++++------- src/plugins/wp/MemoryContext.mli | 4 +++- 4 files changed, 46 insertions(+), 19 deletions(-) diff --git a/src/plugins/wp/Factory.ml b/src/plugins/wp/Factory.ml index cdb4593efb4..f35c4a52596 100644 --- a/src/plugins/wp/Factory.ml +++ b/src/plugins/wp/Factory.ml @@ -111,6 +111,10 @@ module type Proxy = sig (Cil_types.varinfo -> unit) -> unit end +let nullable_status x = + if RefUsage.is_nullable x then MemoryContext.Nullable + else Valid + module MakeVarUsage(V : Proxy) : MemVar.VarUsage = struct let datatype = "VarUsage." ^ V.datatype @@ -124,7 +128,7 @@ struct let module S = Datatype.String.Set in let open MemoryContext in if S.mem x.vname (get_addr ()) then ByAddr else - if S.mem x.vname (get_ctxt ()) then InContext else + if S.mem x.vname (get_ctxt ()) then InContext (nullable_status x) else if S.mem x.vname (get_refs ()) then ByRef else if S.mem x.vname (get_vars ()) then ByValue else V.param x @@ -182,16 +186,19 @@ let refusage_param ~byref ~context x = | RefUsage.NoAccess -> MemoryContext.NotUsed | RefUsage.ByAddr -> MemoryContext.ByAddr | RefUsage.ByValue -> - if context && is_formal_ptr x then MemoryContext.InContext + if context && is_formal_ptr x then + MemoryContext.InContext (nullable_status x) else if is_ptr x && not (is_fun_ptr x) then MemoryContext.ByShift else MemoryContext.ByValue | RefUsage.ByRef -> if byref - then MemoryContext.ByRef + then + if RefUsage.is_nullable x then MemoryContext.InContext Nullable + else MemoryContext.ByRef else MemoryContext.ByValue | RefUsage.ByArray -> if context && is_formal_ptr x - then MemoryContext.InArray + then MemoryContext.InArray (nullable_status x) else MemoryContext.ByShift let refusage_iter ?kf ~init f = RefUsage.iter ?kf ~init (fun x _usage -> f x) diff --git a/src/plugins/wp/MemVar.ml b/src/plugins/wp/MemVar.ml index 2776f437fd7..70e14713b79 100644 --- a/src/plugins/wp/MemVar.ml +++ b/src/plugins/wp/MemVar.ml @@ -104,7 +104,7 @@ struct match V.param x with | ByRef -> "ra_" ^ LogicUsage.basename x - | NotUsed | ByValue | ByShift | ByAddr | InContext | InArray -> + | NotUsed | ByValue | ByShift | ByAddr | InContext _ | InArray _ -> "ta_" ^ LogicUsage.basename x let is_framed = is_framed_var end @@ -600,7 +600,7 @@ struct let pp_var_model fmt = function | ByValue | ByShift | NotUsed -> Format.pp_print_string fmt "non-aliased" (* cf. -wp-unalias-vars *) | ByRef -> Format.pp_print_string fmt "by reference" (* cf. -wp-ref-vars *) - | InContext | InArray -> Format.pp_print_string fmt "in an isolated context" (* cf. -wp-context-vars *) + | InContext _ | InArray _ -> Format.pp_print_string fmt "in an isolated context" (* cf. -wp-context-vars *) | ByAddr -> Format.pp_print_string fmt "aliased" (* cf. -wp-alias-vars *) let pretty fmt = function @@ -631,7 +631,7 @@ struct let cvar x = match V.param x with | NotUsed | ByValue | ByShift -> Val(CVAL,x,[]) | ByAddr -> Val(HEAP,x,[]) - | InContext | InArray | ByRef -> Ref x + | InContext _ | InArray _ | ByRef -> Ref x (* -------------------------------------------------------------------------- *) (* --- Lifting --- *) @@ -730,9 +730,9 @@ struct let load sigma obj = function | Ref x -> begin match V.param x with - | ByRef -> Sigs.Loc(Val(CREF,x,[])) - | InContext -> Sigs.Loc(Val(CTXT,x,[])) - | InArray -> Sigs.Loc(Val(CARR,x,[])) + | ByRef -> Sigs.Loc(Val(CREF,x,[])) + | InContext _ -> Sigs.Loc(Val(CTXT,x,[])) + | InArray _ -> Sigs.Loc(Val(CARR,x,[])) | NotUsed | ByAddr | ByValue | ByShift -> assert false end | Val((CREF|CVAL),x,ofs) -> @@ -1180,7 +1180,7 @@ struct let is_mvar_alloc x = match V.param x with - | ByRef | InContext | InArray | NotUsed -> false + | ByRef | InContext _ | InArray _ | NotUsed -> false | ByValue | ByShift | ByAddr -> true let alloc sigma xs = diff --git a/src/plugins/wp/MemoryContext.ml b/src/plugins/wp/MemoryContext.ml index e337a196331..fcdb60c025d 100644 --- a/src/plugins/wp/MemoryContext.ml +++ b/src/plugins/wp/MemoryContext.ml @@ -24,16 +24,23 @@ (* --- Variable Partitionning --- *) (* -------------------------------------------------------------------------- *) -type param = NotUsed | ByAddr | ByValue | ByShift | ByRef | InContext | InArray +type validity = Valid | Nullable +type param = + | NotUsed | ByAddr | ByValue | ByShift | ByRef + | InContext of validity | InArray of validity + +let nullable_string = function + | Valid -> "" + | Nullable -> "(nullable)" let pp_param fmt = function | NotUsed -> Format.pp_print_string fmt "not used" | ByAddr -> Format.pp_print_string fmt "in heap" | ByValue -> Format.pp_print_string fmt "by value" | ByShift -> Format.pp_print_string fmt "by value with shift" - | ByRef -> Format.pp_print_string fmt "by ref." - | InContext -> Format.pp_print_string fmt "in context" - | InArray -> Format.pp_print_string fmt "in array" + | ByRef -> Format.pp_print_string fmt "by ref" + | InContext n -> Format.pp_print_string fmt ("in context" ^ nullable_string n) + | InArray n -> Format.pp_print_string fmt ("in array" ^ nullable_string n) (* -------------------------------------------------------------------------- *) (* --- Separation Hypotheses --- *) @@ -50,6 +57,7 @@ type partition = { globals : zone list ; (* [ &G , G[...], ... ] *) to_heap : zone list ; (* [ p, ... ] *) context : zone list ; (* [ p+(..), ... ] *) + nullable : zone list ; (* [ p+(..), ... ] but can be NULL *) by_addr : zone list ; (* [ &(x + ..), ... ] *) } @@ -60,6 +68,7 @@ type partition = { let empty = { globals = [] ; context = [] ; + nullable = [] ; to_heap = [] ; by_addr = [] ; } @@ -68,12 +77,21 @@ let set x p w = match p with | NotUsed -> w | ByAddr -> { w with by_addr = Var x :: w.by_addr } - | ByRef | InContext -> + | ByRef -> if Cil.isFunctionType x.vtype then w else { w with context = Ptr x :: w.context } - | InArray -> + | InContext v -> + if Cil.isFunctionType x.vtype then w else + begin match v with + | Nullable -> { w with nullable = Ptr x :: w.nullable } + | Valid -> { w with context = Ptr x :: w.context } + end + | InArray v -> if Cil.isFunctionType x.vtype then w else - { w with context = Arr x :: w.context } + begin match v with + | Nullable -> { w with nullable = Arr x :: w.nullable } + | Valid -> { w with context = Arr x :: w.context } + end | ByValue | ByShift -> if x.vghost then w else if Cil.isFunctionType x.vtype then w else diff --git a/src/plugins/wp/MemoryContext.mli b/src/plugins/wp/MemoryContext.mli index c0698fa9ea1..9cf4ea56bfc 100644 --- a/src/plugins/wp/MemoryContext.mli +++ b/src/plugins/wp/MemoryContext.mli @@ -22,7 +22,9 @@ open Cil_types -type param = NotUsed | ByAddr | ByValue | ByShift | ByRef | InContext | InArray +type validity = Valid | Nullable +type param = NotUsed | ByAddr | ByValue | ByShift | ByRef + | InContext of validity | InArray of validity val pp_param: Format.formatter -> param -> unit -- GitLab