From c67732283d828aa9f5ea795f14749210d2761bbd Mon Sep 17 00:00:00 2001 From: Allan Blanchard <allan.blanchard@cea.fr> Date: Fri, 27 Mar 2020 09:01:43 +0100 Subject: [PATCH] [Instantiate] Moves a not generic function from basic_blocks to mem_utils --- src/plugins/instantiate/basic_blocks.ml | 12 ----- src/plugins/instantiate/basic_blocks.mli | 5 -- src/plugins/instantiate/string/mem_utils.ml | 49 ++++++++++++++------ src/plugins/instantiate/string/mem_utils.mli | 19 +++++++- src/plugins/instantiate/string/memcmp.ml | 8 +++- src/plugins/instantiate/string/memcpy.ml | 8 +++- src/plugins/instantiate/string/memmove.ml | 8 +++- src/plugins/instantiate/string/memset.ml | 24 +++++----- 8 files changed, 85 insertions(+), 48 deletions(-) diff --git a/src/plugins/instantiate/basic_blocks.ml b/src/plugins/instantiate/basic_blocks.ml index 0fcd642c58f..660db8c83c0 100644 --- a/src/plugins/instantiate/basic_blocks.ml +++ b/src/plugins/instantiate/basic_blocks.ml @@ -50,18 +50,6 @@ let call_function lval vi args = let args = List.map2 gen_arg args typs in Call(lval, (Cil.evar vi), args, loc) -let exp_type_of_pointed x = - let no_cast = Cil.stripCasts x in - if not (Cil.isPointerType (Cil.typeOf no_cast)) then - match Cil.constFoldToInt x with - | Some t when Integer.(equal t (of_int 0)) -> - Some (Cil.typeOf_pointed (Cil.typeOf x)) - | _ -> None - else - let xt = Cil.unrollTypeDeep (Cil.typeOf no_cast) in - let xt = Cil.type_remove_qualifier_attributes_deep xt in - Some (Cil.typeOf_pointed xt) - let rec string_of_typ_aux = function | TVoid(_) -> "void" | TInt(IBool, _) -> "bool" diff --git a/src/plugins/instantiate/basic_blocks.mli b/src/plugins/instantiate/basic_blocks.mli index d8723d96765..8b22347ecc1 100644 --- a/src/plugins/instantiate/basic_blocks.mli +++ b/src/plugins/instantiate/basic_blocks.mli @@ -42,11 +42,6 @@ val ttype_of_pointed: logic_type -> logic_type (** {2 C} *) -(** For an expression, return the type of the pointed data. - If the expression is not a pointer, returns None. -*) -val exp_type_of_pointed: exp -> typ option - (** For a type [T], returns [T*] *) val ptr_of: typ -> typ diff --git a/src/plugins/instantiate/string/mem_utils.ml b/src/plugins/instantiate/string/mem_utils.ml index 71247c78162..9d88bb79b94 100644 --- a/src/plugins/instantiate/string/mem_utils.ml +++ b/src/plugins/instantiate/string/mem_utils.ml @@ -24,12 +24,30 @@ open Basic_blocks open Cil_types open Logic_const -type kind = CPtr | Ptr | Len | Int +type kind = CPtr | Ptr | Data of typ type action = Strip | Id type param = string * kind * action type proto = kind * param list type 'a spec_gen = location -> typ -> term -> term -> term -> 'a +type pointed_expr_type = + | Of_null of typ + | Value_of of typ + | No_pointed + +let exp_type_of_pointed x = + let no_cast = Cil.stripCasts x in + if not (Cil.isPointerType (Cil.typeOf no_cast)) then + match Cil.constFoldToInt x with + | Some t when Integer.(equal t (of_int 0)) -> + Of_null (Cil.typeOf_pointed (Cil.typeOf x)) + | _ -> + No_pointed + else + let xt = Cil.unrollTypeDeep (Cil.typeOf no_cast) in + let xt = Cil.type_remove_qualifier_attributes_deep xt in + Value_of (Cil.typeOf_pointed xt) + let unexpected = Options.fatal "Mem_utils: %s" let mem2s_typing _ = function @@ -88,7 +106,7 @@ let memcpy_memmove_common_ensures name loc t dest src len = module type Function = sig val name: string - val prototype: proto + val prototype: unit -> proto val well_typed: typ option -> typ list -> bool end @@ -98,10 +116,9 @@ struct let to_type = function | CPtr -> ptr_of (const_of t) | Ptr -> ptr_of t - | Len -> size_t() - | Int -> Cil.intType + | Data t -> t in - let ret, ps = F.prototype in + let ret, ps = F.prototype () in let ret = to_type ret in let ps = List.map (fun (name, kind, _) -> name, (to_type kind), []) ps in TFun(ret, Some ps, false, []) @@ -112,21 +129,25 @@ struct name, ftype let well_typed_call lval args = - let _, ps = F.prototype in + let _, ps = F.prototype () in if List.length args <> List.length ps then false else let extract e = function | _, (CPtr | Ptr), _ -> exp_type_of_pointed e - | _, (Len | Int), _ -> Some (Cil.typeOf e) + | _, Data _ , _ -> Value_of (Cil.typeOf e) in let lvt = Extlib.opt_map Cil.typeOfLval lval in let pts = List.map2 extract args ps in - let is_none = function None -> true | _ -> false in - if List.exists is_none pts then false - else F.well_typed lvt (List.map (fun x -> Extlib.the x) pts) + let is_no_pointed = function No_pointed -> true | _ -> false in + let the_typ = function + | No_pointed -> assert false + | Value_of t | Of_null t -> t + in + if List.exists is_no_pointed pts then false + else F.well_typed lvt (List.map the_typ pts) let retype_args _ args = - let _, ps = F.prototype in + let _, ps = F.prototype () in if List.length args <> List.length ps then unexpected "trying to retype arguments on an ill-typed call" else @@ -137,12 +158,12 @@ struct List.map2 retype args ps let key_from_call _ret args = - let _, ps = F.prototype in + let _, ps = F.prototype () in match ps, args with | (_, (Ptr|CPtr), _)::ps, fst::args when List.(length ps = length args) -> begin match exp_type_of_pointed fst with - | Some t -> t - | None -> + | Value_of t -> t + | _ -> unexpected "Mem_utils: trying to get key on an ill-typed call" end | _ -> diff --git a/src/plugins/instantiate/string/mem_utils.mli b/src/plugins/instantiate/string/mem_utils.mli index 543e5b06bc1..d4b205be01e 100644 --- a/src/plugins/instantiate/string/mem_utils.mli +++ b/src/plugins/instantiate/string/mem_utils.mli @@ -22,14 +22,22 @@ open Cil_types -type kind = CPtr | Ptr | Len | Int +type kind = CPtr | Ptr | Data of typ type action = Strip | Id type param = string * kind * action type proto = kind * param list module type Function = sig val name: string - val prototype: proto + + val prototype: unit -> proto + + (** receives the type of the lvalue and the types of the arguments recieved + for a call to the function and returns [true] iff they are correct. + The received types depend on the [prototype] of the module. + - if the kind is [Data t] -> it is the exact type of the expr/lvalue + - it the kind is [(C)Ptr] -> it is the pointed type of the expr/lvalue + *) val well_typed: typ option -> typ list -> bool end @@ -58,3 +66,10 @@ val memcpy_memmove_common_assigns: assigns spec_gen val memcpy_memmove_common_ensures: string -> (termination_kind * identified_predicate) list spec_gen + +type pointed_expr_type = + | Of_null of typ + | Value_of of typ + | No_pointed + +val exp_type_of_pointed: exp -> pointed_expr_type \ No newline at end of file diff --git a/src/plugins/instantiate/string/memcmp.ml b/src/plugins/instantiate/string/memcmp.ml index c8518480ed8..59969c7ddee 100644 --- a/src/plugins/instantiate/string/memcmp.ml +++ b/src/plugins/instantiate/string/memcmp.ml @@ -66,7 +66,13 @@ module Function = struct open Mem_utils let name = function_name - let prototype = Int, [ ("s1",CPtr,Strip);("s2",CPtr,Strip);("len",Len,Id)] + let prototype () = + Data Cil.intType, + [ + ("s1" , CPtr,Strip) ; + ("s2" , CPtr,Strip) ; + ("len", Data (size_t ()) ,Id) + ] let well_typed = Mem_utils.mem2s_typing end module Memcmp_base = Mem_utils.Make(Function) diff --git a/src/plugins/instantiate/string/memcpy.ml b/src/plugins/instantiate/string/memcpy.ml index b13a13067cb..e56778e6a57 100644 --- a/src/plugins/instantiate/string/memcpy.ml +++ b/src/plugins/instantiate/string/memcpy.ml @@ -45,7 +45,13 @@ let generate_spec = mem2s_spec ~requires ~assigns ~ensures module Function = struct let name = function_name - let prototype = Ptr, [("dest",Ptr,Strip);("src",CPtr,Strip);("len",Len,Id)] + let prototype () = + Ptr, + [ + ("dest", Ptr, Strip) ; + ("src", CPtr, Strip) ; + ("len", Data (size_t()), Id) + ] let well_typed = Mem_utils.mem2s_typing end module Memcpy_base = Mem_utils.Make(Function) diff --git a/src/plugins/instantiate/string/memmove.ml b/src/plugins/instantiate/string/memmove.ml index 0295236f2cd..9ce6d75b6bd 100644 --- a/src/plugins/instantiate/string/memmove.ml +++ b/src/plugins/instantiate/string/memmove.ml @@ -33,7 +33,13 @@ let generate_spec = mem2s_spec ~requires ~assigns ~ensures module Function = struct let name = function_name - let prototype = Ptr, [("dest",Ptr,Strip);("src",CPtr,Strip);("len",Len,Id)] + let prototype () = + Ptr, + [ + ("dest", Ptr, Strip); + ("src" , CPtr, Strip); + ("len", Data (Basic_blocks.size_t()), Id) + ] let well_typed = Mem_utils.mem2s_typing end module Memmove_base = Mem_utils.Make(Function) diff --git a/src/plugins/instantiate/string/memset.ml b/src/plugins/instantiate/string/memset.ml index a8fc72f07a5..f681aa0ef13 100644 --- a/src/plugins/instantiate/string/memset.ml +++ b/src/plugins/instantiate/string/memset.ml @@ -194,12 +194,12 @@ let rec contains_union_type t = let well_typed_call _ret = function | [ ptr ; value ; _ ] -> - begin match exp_type_of_pointed ptr, memset_value value with - | None , _ -> false - | Some t, _ when any_char_composed_type t -> true - | Some t, _ when contains_union_type t -> false - | Some t, _ when Cil.isVoidType t -> false - | Some t, _ when not (Cil.isCompleteType t) -> false + begin match Mem_utils.exp_type_of_pointed ptr, memset_value value with + | (No_pointed | Of_null _) , _ -> false + | Value_of t , _ when any_char_composed_type t -> true + | Value_of t , _ when contains_union_type t -> false + | Value_of t , _ when Cil.isVoidType t -> false + | Value_of t , _ when not (Cil.isCompleteType t) -> false | _, None -> false | _, Some _ -> true end @@ -207,9 +207,9 @@ let well_typed_call _ret = function let key_from_call _ret = function | [ ptr ; value ; _ ] -> - begin match exp_type_of_pointed ptr, memset_value value with - | Some t, _ when any_char_composed_type t -> t, None - | Some t, value when not (contains_union_type t) -> t, value + begin match Mem_utils.exp_type_of_pointed ptr, memset_value value with + | Value_of t, _ when any_char_composed_type t -> t, None + | Value_of t, value when not (contains_union_type t) -> t, value | _ , _ -> unexpected "trying to generate a key on an ill-typed call" end | _ -> unexpected "trying to generate a key on an ill-typed call" @@ -247,9 +247,9 @@ let retype_args (_t, e) args = match e, args with | None, [ ptr ; v ; n ] -> let ptr = Cil.stripCasts ptr in - let base_type = match exp_type_of_pointed ptr with - | Some t -> base_char_type t - | None -> unexpected "trying to retype arguments on an ill-typed call" + let base_type = match Mem_utils.exp_type_of_pointed ptr with + | Value_of t -> base_char_type t + | _ -> unexpected "trying to retype arguments on an ill-typed call" in let v = Cil.mkCast (Cil.stripCasts v) base_type in [ ptr ; v ; n ] -- GitLab