@ -78,7 +78,7 @@ let bounds_check tenv pname prop len e =
let rec create_struct_values pname tenv orig_prop footprint_part kind max_stamp ( t : Typ . t )
let rec create_struct_values pname tenv orig_prop footprint_part kind max_stamp ( t : Typ . t )
( off : Sil. offset list ) inst : Sil . atom list * Sil . strexp * Typ . t =
( off : Predicates. offset list ) inst : Predicates . atom list * Predicates . strexp * Typ . t =
if Config . trace_rearrange then (
if Config . trace_rearrange then (
L . d_increase_indent () ;
L . d_increase_indent () ;
L . d_strln " entering create_struct_values " ;
L . d_strln " entering create_struct_values " ;
@ -86,7 +86,7 @@ let rec create_struct_values pname tenv orig_prop footprint_part kind max_stamp
Typ . d_full t ;
Typ . d_full t ;
L . d_ln () ;
L . d_ln () ;
L . d_str " off: " ;
L . d_str " off: " ;
Sil . d_offset_list off ;
Predicates . d_offset_list off ;
L . d_ln () ;
L . d_ln () ;
L . d_ln () ) ;
L . d_ln () ) ;
let new_id () = incr max_stamp ; Ident . create kind ! max_stamp in
let new_id () = incr max_stamp ; Ident . create kind ! max_stamp in
@ -95,13 +95,13 @@ let rec create_struct_values pname tenv orig_prop footprint_part kind max_stamp
L . d_str " create_struct_values type: " ;
L . d_str " create_struct_values type: " ;
Typ . d_full t ;
Typ . d_full t ;
L . d_str " off: " ;
L . d_str " off: " ;
Sil . d_offset_list off ;
Predicates . d_offset_list off ;
L . d_ln () ;
L . d_ln () ;
raise ( Exceptions . Bad_footprint pos )
raise ( Exceptions . Bad_footprint pos )
in
in
match ( t . desc , off ) with
match ( t . desc , off ) with
| Tstruct _ , [] ->
| Tstruct _ , [] ->
( [] , Sil . Estruct ( [] , inst ) , t )
( [] , Predicates . Estruct ( [] , inst ) , t )
| Tstruct name , Off_fld ( f , _ ) :: off' -> (
| Tstruct name , Off_fld ( f , _ ) :: off' -> (
match Tenv . lookup tenv name with
match Tenv . lookup tenv name with
| Some ( { fields ; statics } as struct_typ ) -> (
| Some ( { fields ; statics } as struct_typ ) -> (
@ -110,7 +110,7 @@ let rec create_struct_values pname tenv orig_prop footprint_part kind max_stamp
let atoms' , se' , res_t' =
let atoms' , se' , res_t' =
create_struct_values pname tenv orig_prop footprint_part kind max_stamp t' off' inst
create_struct_values pname tenv orig_prop footprint_part kind max_stamp t' off' inst
in
in
let se = Sil . Estruct ( [ ( f , se' ) ] , inst ) in
let se = Predicates . Estruct ( [ ( f , se' ) ] , inst ) in
let replace_typ_of_f ( f' , t' , a' ) =
let replace_typ_of_f ( f' , t' , a' ) =
if Typ . Fieldname . equal f f' then ( f , res_t' , a' ) else ( f' , t' , a' )
if Typ . Fieldname . equal f f' then ( f , res_t' , a' ) else ( f' , t' , a' )
in
in
@ -129,30 +129,30 @@ let rec create_struct_values pname tenv orig_prop footprint_part kind max_stamp
in
in
let e' = Absarray . array_clean_new_index footprint_part e in
let e' = Absarray . array_clean_new_index footprint_part e in
let len = Exp . Var ( new_id () ) in
let len = Exp . Var ( new_id () ) in
let se = Sil . Earray ( len , [ ( e' , se' ) ] , inst ) in
let se = Predicates . Earray ( len , [ ( e' , se' ) ] , inst ) in
let res_t = Typ . mk_array res_t' in
let res_t = Typ . mk_array res_t' in
( Sil . Aeq ( e , e' ) :: atoms' , se , res_t )
( Predicates . Aeq ( e , e' ) :: atoms' , se , res_t )
| Tarray { elt = t' ; length ; stride } , off -> (
| Tarray { elt = t' ; length ; stride } , off -> (
let len =
let len =
match length with None -> Exp . Var ( new_id () ) | Some len -> Exp . Const ( Const . Cint len )
match length with None -> Exp . Var ( new_id () ) | Some len -> Exp . Const ( Const . Cint len )
in
in
match off with
match off with
| [] ->
| [] ->
( [] , Sil . Earray ( len , [] , inst ) , t )
( [] , Predicates . Earray ( len , [] , inst ) , t )
| Sil . Off_index e :: off' ->
| Predicates . Off_index e :: off' ->
bounds_check tenv pname orig_prop len e ( State . get_loc_exn () ) ;
bounds_check tenv pname orig_prop len e ( State . get_loc_exn () ) ;
let atoms' , se' , res_t' =
let atoms' , se' , res_t' =
create_struct_values pname tenv orig_prop footprint_part kind max_stamp t' off' inst
create_struct_values pname tenv orig_prop footprint_part kind max_stamp t' off' inst
in
in
let e' = Absarray . array_clean_new_index footprint_part e in
let e' = Absarray . array_clean_new_index footprint_part e in
let se = Sil . Earray ( len , [ ( e' , se' ) ] , inst ) in
let se = Predicates . Earray ( len , [ ( e' , se' ) ] , inst ) in
let res_t = Typ . mk_array ~ default : t res_t' ? length ? stride in
let res_t = Typ . mk_array ~ default : t res_t' ? length ? stride in
( Sil . Aeq ( e , e' ) :: atoms' , se , res_t )
( Predicates . Aeq ( e , e' ) :: atoms' , se , res_t )
| Sil . Off_fld _ :: _ ->
| Predicates . Off_fld _ :: _ ->
assert false )
assert false )
| Tint _ , [] | Tfloat _ , [] | Tvoid , [] | Tfun , [] | Tptr _ , [] | TVar _ , [] ->
| Tint _ , [] | Tfloat _ , [] | Tvoid , [] | Tfun , [] | Tptr _ , [] | TVar _ , [] ->
let id = new_id () in
let id = new_id () in
( [] , Sil . Eexp ( Exp . Var id , inst ) , t )
( [] , Predicates . Eexp ( Exp . Var id , inst ) , t )
| ( Tint _ | Tfloat _ | Tvoid | Tfun | Tptr _ | TVar _ ) , Off_index e :: off' ->
| ( Tint _ | Tfloat _ | Tvoid | Tfun | Tptr _ | TVar _ ) , Off_index e :: off' ->
(* In this case, we lift t to the t array. *)
(* In this case, we lift t to the t array. *)
let t' , mk_typ_f =
let t' , mk_typ_f =
@ -167,16 +167,16 @@ let rec create_struct_values pname tenv orig_prop footprint_part kind max_stamp
create_struct_values pname tenv orig_prop footprint_part kind max_stamp t' off' inst
create_struct_values pname tenv orig_prop footprint_part kind max_stamp t' off' inst
in
in
let e' = Absarray . array_clean_new_index footprint_part e in
let e' = Absarray . array_clean_new_index footprint_part e in
let se = Sil . Earray ( len , [ ( e' , se' ) ] , inst ) in
let se = Predicates . Earray ( len , [ ( e' , se' ) ] , inst ) in
let res_t = mk_typ_f ( Tarray { elt = res_t' ; length = None ; stride = None } ) in
let res_t = mk_typ_f ( Tarray { elt = res_t' ; length = None ; stride = None } ) in
( Sil . Aeq ( e , e' ) :: atoms' , se , res_t )
( Predicates . Aeq ( e , e' ) :: atoms' , se , res_t )
| Tint _ , _ | Tfloat _ , _ | Tvoid , _ | Tfun , _ | Tptr _ , _ | TVar _ , _ ->
| Tint _ , _ | Tfloat _ , _ | Tvoid , _ | Tfun , _ | Tptr _ , _ | TVar _ , _ ->
fail t off _ _ POS__
fail t off _ _ POS__
in
in
if Config . trace_rearrange then (
if Config . trace_rearrange then (
let _ , se , _ = res in
let _ , se , _ = res in
L . d_strln " exiting create_struct_values, returning " ;
L . d_strln " exiting create_struct_values, returning " ;
Sil . d_sexp se ;
Predicates . d_sexp se ;
L . d_decrease_indent () ;
L . d_decrease_indent () ;
L . d_ln () ;
L . d_ln () ;
L . d_ln () ) ;
L . d_ln () ) ;
@ -189,18 +189,18 @@ let rec create_struct_values pname tenv orig_prop footprint_part kind max_stamp
If we want to implement the checks for array bounds errors ,
If we want to implement the checks for array bounds errors ,
we need to change this function . * )
we need to change this function . * )
let rec strexp_extend_values_ pname tenv orig_prop footprint_part kind max_stamp se ( typ : Typ . t )
let rec strexp_extend_values_ pname tenv orig_prop footprint_part kind max_stamp se ( typ : Typ . t )
( off : Sil . offset list ) inst =
( off : Predicates . offset list ) inst =
let new_id () = incr max_stamp ; Ident . create kind ! max_stamp in
let new_id () = incr max_stamp ; Ident . create kind ! max_stamp in
match ( off , se , typ . desc ) with
match ( off , se , typ . desc ) with
| [] , Sil. Eexp _ , _ | [] , Sil . Estruct _ , _ ->
| [] , Predicates. Eexp _ , _ | [] , Predicates . Estruct _ , _ ->
[ ( [] , se , typ ) ]
[ ( [] , se , typ ) ]
| [] , Sil . Earray _ , _ ->
| [] , Predicates . Earray _ , _ ->
let off_new = Sil . Off_index Exp . zero :: off in
let off_new = Predicates . Off_index Exp . zero :: off in
strexp_extend_values_ pname tenv orig_prop footprint_part kind max_stamp se typ off_new inst
strexp_extend_values_ pname tenv orig_prop footprint_part kind max_stamp se typ off_new inst
| Off_fld _ :: _ , Sil . Earray _ , Tarray _ ->
| Off_fld _ :: _ , Predicates . Earray _ , Tarray _ ->
let off_new = Sil . Off_index Exp . zero :: off in
let off_new = Predicates . Off_index Exp . zero :: off in
strexp_extend_values_ pname tenv orig_prop footprint_part kind max_stamp se typ off_new inst
strexp_extend_values_ pname tenv orig_prop footprint_part kind max_stamp se typ off_new inst
| Off_fld ( f , _ ) :: off' , Sil . Estruct ( fsel , inst' ) , Tstruct name -> (
| Off_fld ( f , _ ) :: off' , Predicates . Estruct ( fsel , inst' ) , Tstruct name -> (
match Tenv . lookup tenv name with
match Tenv . lookup tenv name with
| Some ( { fields ; statics } as struct_typ ) -> (
| Some ( { fields ; statics } as struct_typ ) -> (
match List . find ~ f : ( fun ( f' , _ , _ ) -> Typ . Fieldname . equal f f' ) ( fields @ statics ) with
match List . find ~ f : ( fun ( f' , _ , _ ) -> Typ . Fieldname . equal f f' ) ( fields @ statics ) with
@ -216,7 +216,7 @@ let rec strexp_extend_values_ pname tenv orig_prop footprint_part kind max_stamp
if Typ . Fieldname . equal f1 f then ( f1 , res_se' ) else ft1
if Typ . Fieldname . equal f1 f then ( f1 , res_se' ) else ft1
in
in
let res_fsel' =
let res_fsel' =
List . sort ~ compare : [ % compare : Typ . Fieldname . t * Sil . strexp ]
List . sort ~ compare : [ % compare : Typ . Fieldname . t * Predicates . strexp ]
( List . map ~ f : replace_fse fsel )
( List . map ~ f : replace_fse fsel )
in
in
let replace_fta ( ( f1 , _ , a1 ) as fta1 ) =
let replace_fta ( ( f1 , _ , a1 ) as fta1 ) =
@ -226,7 +226,7 @@ let rec strexp_extend_values_ pname tenv orig_prop footprint_part kind max_stamp
List . sort ~ compare : Typ . Struct . compare_field ( List . map ~ f : replace_fta fields )
List . sort ~ compare : Typ . Struct . compare_field ( List . map ~ f : replace_fta fields )
in
in
ignore ( Tenv . mk_struct tenv ~ default : struct_typ ~ fields : fields' name ) ;
ignore ( Tenv . mk_struct tenv ~ default : struct_typ ~ fields : fields' name ) ;
( res_atoms' , Sil . Estruct ( res_fsel' , inst' ) , typ ) :: acc
( res_atoms' , Predicates . Estruct ( res_fsel' , inst' ) , typ ) :: acc
in
in
List . fold ~ f : replace ~ init : [] atoms_se_typ_list'
List . fold ~ f : replace ~ init : [] atoms_se_typ_list'
| None ->
| None ->
@ -234,7 +234,7 @@ let rec strexp_extend_values_ pname tenv orig_prop footprint_part kind max_stamp
create_struct_values pname tenv orig_prop footprint_part kind max_stamp typ' off' inst
create_struct_values pname tenv orig_prop footprint_part kind max_stamp typ' off' inst
in
in
let res_fsel' =
let res_fsel' =
List . sort ~ compare : [ % compare : Typ . Fieldname . t * Sil . strexp ] ( ( f , se' ) :: fsel )
List . sort ~ compare : [ % compare : Typ . Fieldname . t * Predicates . strexp ] ( ( f , se' ) :: fsel )
in
in
let replace_fta ( f' , t' , a' ) =
let replace_fta ( f' , t' , a' ) =
if Typ . Fieldname . equal f' f then ( f , res_typ' , a' ) else ( f' , t' , a' )
if Typ . Fieldname . equal f' f then ( f , res_typ' , a' ) else ( f' , t' , a' )
@ -243,30 +243,30 @@ let rec strexp_extend_values_ pname tenv orig_prop footprint_part kind max_stamp
List . sort ~ compare : Typ . Struct . compare_field ( List . map ~ f : replace_fta fields )
List . sort ~ compare : Typ . Struct . compare_field ( List . map ~ f : replace_fta fields )
in
in
ignore ( Tenv . mk_struct tenv ~ default : struct_typ ~ fields : fields' name ) ;
ignore ( Tenv . mk_struct tenv ~ default : struct_typ ~ fields : fields' name ) ;
[ ( atoms' , Sil . Estruct ( res_fsel' , inst' ) , typ ) ] )
[ ( atoms' , Predicates . Estruct ( res_fsel' , inst' ) , typ ) ] )
| None ->
| None ->
raise ( Exceptions . Missing_fld ( f , _ _ POS__ ) ) )
raise ( Exceptions . Missing_fld ( f , _ _ POS__ ) ) )
| None ->
| None ->
raise ( Exceptions . Missing_fld ( f , _ _ POS__ ) ) )
raise ( Exceptions . Missing_fld ( f , _ _ POS__ ) ) )
| Off_fld _ :: _ , _ , _ ->
| Off_fld _ :: _ , _ , _ ->
raise ( Exceptions . Bad_footprint _ _ POS__ )
raise ( Exceptions . Bad_footprint _ _ POS__ )
| Off_index _ :: _ , Sil . Eexp _ , ( Tint _ | Tfloat _ | Tvoid | Tfun | Tptr _ )
| Off_index _ :: _ , Predicates . Eexp _ , ( Tint _ | Tfloat _ | Tvoid | Tfun | Tptr _ )
| Off_index _ :: _ , Sil . Estruct _ , Tstruct _ ->
| Off_index _ :: _ , Predicates . Estruct _ , Tstruct _ ->
(* L.d_strln ~color:Orange "turn into an array"; *)
(* L.d_strln ~color:Orange "turn into an array"; *)
let len =
let len =
match se with
match se with
| Sil. Eexp ( _ , Sil . Ialloc ) ->
| Predicates. Eexp ( _ , Predicates . Ialloc ) ->
Exp . one (* if allocated explicitly, we know len is 1 *)
Exp . one (* if allocated explicitly, we know len is 1 *)
| _ ->
| _ ->
if Config . type_size then Exp . one (* Exp.Sizeof ( typ, Subtype.exact ) *)
if Config . type_size then Exp . one (* Exp.Sizeof ( typ, Subtype.exact ) *)
else Exp . Var ( new_id () )
else Exp . Var ( new_id () )
in
in
let se_new = Sil . Earray ( len , [ ( Exp . zero , se ) ] , inst ) in
let se_new = Predicates . Earray ( len , [ ( Exp . zero , se ) ] , inst ) in
let typ_new = Typ . mk_array typ in
let typ_new = Typ . mk_array typ in
strexp_extend_values_ pname tenv orig_prop footprint_part kind max_stamp se_new typ_new off
strexp_extend_values_ pname tenv orig_prop footprint_part kind max_stamp se_new typ_new off
inst
inst
| ( Off_index e :: off'
| ( Off_index e :: off'
, Sil . Earray ( len , esel , inst_arr )
, Predicates . Earray ( len , esel , inst_arr )
, Tarray { elt = typ' ; length = len_for_typ' ; stride } ) -> (
, Tarray { elt = typ' ; length = len_for_typ' ; stride } ) -> (
bounds_check tenv pname orig_prop len e ( State . get_loc_exn () ) ;
bounds_check tenv pname orig_prop len e ( State . get_loc_exn () ) ;
match List . find ~ f : ( fun ( e' , _ ) -> Exp . equal e e' ) esel with
match List . find ~ f : ( fun ( e' , _ ) -> Exp . equal e e' ) esel with
@ -280,7 +280,7 @@ let rec strexp_extend_values_ pname tenv orig_prop footprint_part kind max_stamp
let res_esel' = List . map ~ f : replace_ise esel in
let res_esel' = List . map ~ f : replace_ise esel in
if Typ . equal res_typ' typ' | | Int . equal ( List . length res_esel' ) 1 then
if Typ . equal res_typ' typ' | | Int . equal ( List . length res_esel' ) 1 then
( res_atoms'
( res_atoms'
, Sil . Earray ( len , res_esel' , inst_arr )
, Predicates . Earray ( len , res_esel' , inst_arr )
, Typ . mk_array ~ default : typ res_typ' ? length : len_for_typ' ? stride )
, Typ . mk_array ~ default : typ res_typ' ? length : len_for_typ' ? stride )
:: acc
:: acc
else raise ( Exceptions . Bad_footprint _ _ POS__ )
else raise ( Exceptions . Bad_footprint _ _ POS__ )
@ -310,7 +310,7 @@ and array_case_analysis_index pname tenv orig_prop footprint_part kind max_stamp
false
false
in
in
if index_in_array then
if index_in_array then
let array_default = Sil . Earray ( array_len , array_cont , inst_arr ) in
let array_default = Predicates . Earray ( array_len , array_cont , inst_arr ) in
let typ_default = Typ . mk_array ~ default : typ_array typ_cont ? length : typ_array_len in
let typ_default = Typ . mk_array ~ default : typ_array typ_cont ? length : typ_array_len in
[ ( [] , array_default , typ_default ) ]
[ ( [] , array_default , typ_default ) ]
else if ! BiabductionConfig . footprint then (
else if ! BiabductionConfig . footprint then (
@ -319,9 +319,9 @@ and array_case_analysis_index pname tenv orig_prop footprint_part kind max_stamp
in
in
check_sound elem_typ ;
check_sound elem_typ ;
let cont_new =
let cont_new =
List . sort ~ compare : [ % compare : Exp . t * Sil . strexp ] ( ( index , elem_se ) :: array_cont )
List . sort ~ compare : [ % compare : Exp . t * Predicates . strexp ] ( ( index , elem_se ) :: array_cont )
in
in
let array_new = Sil . Earray ( array_len , cont_new , inst_arr ) in
let array_new = Predicates . Earray ( array_len , cont_new , inst_arr ) in
let typ_new = Typ . mk_array ~ default : typ_array elem_typ ? length : typ_array_len in
let typ_new = Typ . mk_array ~ default : typ_array elem_typ ? length : typ_array_len in
[ ( atoms , array_new , typ_new ) ] )
[ ( atoms , array_new , typ_new ) ] )
else
else
@ -333,9 +333,9 @@ and array_case_analysis_index pname tenv orig_prop footprint_part kind max_stamp
in
in
check_sound elem_typ ;
check_sound elem_typ ;
let cont_new =
let cont_new =
List . sort ~ compare : [ % compare : Exp . t * Sil . strexp ] ( ( index , elem_se ) :: array_cont )
List . sort ~ compare : [ % compare : Exp . t * Predicates . strexp ] ( ( index , elem_se ) :: array_cont )
in
in
let array_new = Sil . Earray ( array_len , cont_new , inst_arr ) in
let array_new = Predicates . Earray ( array_len , cont_new , inst_arr ) in
let typ_new = Typ . mk_array ~ default : typ_array elem_typ ? length : typ_array_len in
let typ_new = Typ . mk_array ~ default : typ_array elem_typ ? length : typ_array_len in
[ ( atoms , array_new , typ_new ) ]
[ ( atoms , array_new , typ_new ) ]
in
in
@ -351,9 +351,9 @@ and array_case_analysis_index pname tenv orig_prop footprint_part kind max_stamp
List . fold
List . fold
~ f : ( fun acc' ( atoms' , se' , typ' ) ->
~ f : ( fun acc' ( atoms' , se' , typ' ) ->
check_sound typ' ;
check_sound typ' ;
let atoms_new = Sil . Aeq ( index , i ) :: atoms' in
let atoms_new = Predicates . Aeq ( index , i ) :: atoms' in
let isel_new = list_rev_and_concat isel_seen_rev ( ( i , se' ) :: isel_unseen ) in
let isel_new = list_rev_and_concat isel_seen_rev ( ( i , se' ) :: isel_unseen ) in
let array_new = Sil . Earray ( array_len , isel_new , inst_arr ) in
let array_new = Predicates . Earray ( array_len , isel_new , inst_arr ) in
let typ_new = Typ . mk_array ~ default : typ_array typ' ? length : typ_array_len in
let typ_new = Typ . mk_array ~ default : typ_array typ' ? length : typ_array_len in
( atoms_new , array_new , typ_new ) :: acc' )
( atoms_new , array_new , typ_new ) :: acc' )
~ init : [] atoms_se_typ_list
~ init : [] atoms_se_typ_list
@ -372,10 +372,10 @@ let laundry_offset_for_footprint max_stamp offs_in =
match offs with
match offs with
| [] ->
| [] ->
( List . rev offs_seen , List . rev eqs )
( List . rev offs_seen , List . rev eqs )
| ( Sil . Off_fld _ as off ) :: offs' ->
| ( Predicates . Off_fld _ as off ) :: offs' ->
let offs_seen' = off :: offs_seen in
let offs_seen' = off :: offs_seen in
laundry offs_seen' eqs offs'
laundry offs_seen' eqs offs'
| ( Sil . Off_index idx as off ) :: offs' ->
| ( Predicates . Off_index idx as off ) :: offs' ->
if exp_has_only_footprint_ids idx then
if exp_has_only_footprint_ids idx then
let offs_seen' = off :: offs_seen in
let offs_seen' = off :: offs_seen in
laundry offs_seen' eqs offs'
laundry offs_seen' eqs offs'
@ -383,7 +383,7 @@ let laundry_offset_for_footprint max_stamp offs_in =
let () = incr max_stamp in
let () = incr max_stamp in
let fid_new = Ident . create Ident . kfootprint ! max_stamp in
let fid_new = Ident . create Ident . kfootprint ! max_stamp in
let exp_new = Exp . Var fid_new in
let exp_new = Exp . Var fid_new in
let off_new = Sil . Off_index exp_new in
let off_new = Predicates . Off_index exp_new in
let offs_seen' = off_new :: offs_seen in
let offs_seen' = off_new :: offs_seen in
let eqs' = ( fid_new , idx ) :: eqs in
let eqs' = ( fid_new , idx ) :: eqs in
laundry offs_seen' eqs' offs'
laundry offs_seen' eqs' offs'
@ -392,7 +392,7 @@ let laundry_offset_for_footprint max_stamp offs_in =
let strexp_extend_values pname tenv orig_prop footprint_part kind max_stamp se te
let strexp_extend_values pname tenv orig_prop footprint_part kind max_stamp se te
( off : Sil . offset list ) inst =
( off : Predicates . offset list ) inst =
let typ = Exp . texp_to_typ None te in
let typ = Exp . texp_to_typ None te in
let off' , laundry_atoms =
let off' , laundry_atoms =
let off' , eqs = laundry_offset_for_footprint max_stamp off in
let off' , eqs = laundry_offset_for_footprint max_stamp off in
@ -402,11 +402,11 @@ let strexp_extend_values pname tenv orig_prop footprint_part kind max_stamp se t
in
in
if Config . trace_rearrange then (
if Config . trace_rearrange then (
L . d_str " entering strexp_extend_values se: " ;
L . d_str " entering strexp_extend_values se: " ;
Sil . d_sexp se ;
Predicates . d_sexp se ;
L . d_str " typ: " ;
L . d_str " typ: " ;
Typ . d_full typ ;
Typ . d_full typ ;
L . d_str " off': " ;
L . d_str " off': " ;
Sil . d_offset_list off' ;
Predicates . d_offset_list off' ;
L . d_strln ( if footprint_part then " FP " else " RE " ) ) ;
L . d_strln ( if footprint_part then " FP " else " RE " ) ) ;
let atoms_se_typ_list =
let atoms_se_typ_list =
strexp_extend_values_ pname tenv orig_prop footprint_part kind max_stamp se typ off' inst
strexp_extend_values_ pname tenv orig_prop footprint_part kind max_stamp se typ off' inst
@ -432,13 +432,13 @@ let strexp_extend_values pname tenv orig_prop footprint_part kind max_stamp se t
let collect_root_offset exp =
let collect_root_offset exp =
let root = Exp . root_of_lexp exp in
let root = Exp . root_of_lexp exp in
let offsets = Sil . exp_get_offsets exp in
let offsets = Predicates . exp_get_offsets exp in
( root , offsets )
( root , offsets )
(* * Exp.Construct a points-to predicate for an expression, to add to a footprint. *)
(* * Exp.Construct a points-to predicate for an expression, to add to a footprint. *)
let mk_ptsto_exp_footprint pname tenv orig_prop ( lexp , typ ) max_stamp inst :
let mk_ptsto_exp_footprint pname tenv orig_prop ( lexp , typ ) max_stamp inst :
Sil. hpred * Sil . hpred * Sil . atom list =
Predicates. hpred * Predicates . hpred * Predicates . atom list =
let root , off = collect_root_offset lexp in
let root , off = collect_root_offset lexp in
if not ( exp_has_only_footprint_ids root ) then
if not ( exp_has_only_footprint_ids root ) then
if
if
@ -463,7 +463,7 @@ let mk_ptsto_exp_footprint pname tenv orig_prop (lexp, typ) max_stamp inst :
let fun_exp = Exp . Const ( Const . Cfun fun_name ) in
let fun_exp = Exp . Const ( Const . Cfun fun_name ) in
( []
( []
, Prop . mk_ptsto tenv root
, Prop . mk_ptsto tenv root
( Sil . Eexp ( fun_exp , inst ) )
( Predicates . Eexp ( fun_exp , inst ) )
( Exp . Sizeof { typ ; nbytes = None ; dynamic_length = None ; subtype } ) )
( Exp . Sizeof { typ ; nbytes = None ; dynamic_length = None ; subtype } ) )
| _ , [] , Typ . Tfun ->
| _ , [] , Typ . Tfun ->
let atoms , se , typ =
let atoms , se , typ =
@ -483,8 +483,8 @@ let mk_ptsto_exp_footprint pname tenv orig_prop (lexp, typ) max_stamp inst :
)
)
in
in
let atoms , ptsto_foot = create_ptsto true off_foot in
let atoms , ptsto_foot = create_ptsto true off_foot in
let sub = Sil . subst_of_list eqs in
let sub = Predicates . subst_of_list eqs in
let ptsto = Sil . hpred_sub sub ptsto_foot in
let ptsto = Predicates . hpred_sub sub ptsto_foot in
let atoms' = List . map ~ f : ( fun ( id , e ) -> Prop . mk_eq tenv ( Exp . Var id ) e ) eqs in
let atoms' = List . map ~ f : ( fun ( id , e ) -> Prop . mk_eq tenv ( Exp . Var id ) e ) eqs in
( ptsto , ptsto_foot , atoms @ atoms' )
( ptsto , ptsto_foot , atoms @ atoms' )
@ -492,10 +492,10 @@ let mk_ptsto_exp_footprint pname tenv orig_prop (lexp, typ) max_stamp inst :
(* * Check if the path in exp exists already in the current ptsto predicate.
(* * Check if the path in exp exists already in the current ptsto predicate.
If it exists , return None . Otherwise , return [ Some fld ] with [ fld ] the missing field . * )
If it exists , return None . Otherwise , return [ Some fld ] with [ fld ] the missing field . * )
let prop_iter_check_fields_ptsto_shallow tenv iter lexp =
let prop_iter_check_fields_ptsto_shallow tenv iter lexp =
let offset = Sil . exp_get_offsets lexp in
let offset = Predicates . exp_get_offsets lexp in
let _ , se , _ =
let _ , se , _ =
match Prop . prop_iter_current tenv iter with
match Prop . prop_iter_current tenv iter with
| Sil . Hpointsto ( e , se , t ) , _ ->
| Predicates . Hpointsto ( e , se , t ) , _ ->
( e , se , t )
( e , se , t )
| _ ->
| _ ->
assert false
assert false
@ -503,9 +503,9 @@ let prop_iter_check_fields_ptsto_shallow tenv iter lexp =
let rec check_offset se = function
let rec check_offset se = function
| [] ->
| [] ->
None
None
| Sil . Off_fld ( fld , _ ) :: off' -> (
| Predicates . Off_fld ( fld , _ ) :: off' -> (
match se with
match se with
| Sil . Estruct ( fsel , _ ) -> (
| Predicates . Estruct ( fsel , _ ) -> (
match List . find ~ f : ( fun ( fld' , _ ) -> Typ . Fieldname . equal fld fld' ) fsel with
match List . find ~ f : ( fun ( fld' , _ ) -> Typ . Fieldname . equal fld fld' ) fsel with
| Some ( _ , se' ) ->
| Some ( _ , se' ) ->
check_offset se' off'
check_offset se' off'
@ -513,7 +513,7 @@ let prop_iter_check_fields_ptsto_shallow tenv iter lexp =
Some fld )
Some fld )
| _ ->
| _ ->
Some fld )
Some fld )
| Sil . Off_index _ :: _ ->
| Predicates . Off_index _ :: _ ->
None
None
in
in
check_offset se offset
check_offset se offset
@ -528,36 +528,37 @@ let prop_iter_extend_ptsto pname tenv orig_prop iter lexp inst =
L . d_str " entering prop_iter_extend_ptsto lexp: " ;
L . d_str " entering prop_iter_extend_ptsto lexp: " ;
Exp . d_exp lexp ;
Exp . d_exp lexp ;
L . d_ln () ) ;
L . d_ln () ) ;
let offset = Sil . exp_get_offsets lexp in
let offset = Predicates . exp_get_offsets lexp in
let max_stamp = Prop . prop_iter_max_stamp iter in
let max_stamp = Prop . prop_iter_max_stamp iter in
let extend_footprint_pred = function
let extend_footprint_pred = function
| Sil . Hpointsto ( e , se , te ) ->
| Predicates . Hpointsto ( e , se , te ) ->
let atoms_se_te_list =
let atoms_se_te_list =
strexp_extend_values pname tenv orig_prop true Ident . kfootprint ( ref max_stamp ) se te
strexp_extend_values pname tenv orig_prop true Ident . kfootprint ( ref max_stamp ) se te
offset inst
offset inst
in
in
List . map
List . map
~ f : ( fun ( atoms' , se' , te' ) -> ( atoms' , Sil . Hpointsto ( e , se' , te' ) ) )
~ f : ( fun ( atoms' , se' , te' ) -> ( atoms' , Predicates . Hpointsto ( e , se' , te' ) ) )
atoms_se_te_list
atoms_se_te_list
| Sil . Hlseg ( k , hpara , e1 , e2 , el ) -> (
| Predicates . Hlseg ( k , hpara , e1 , e2 , el ) -> (
match hpara . Sil . body with
match hpara . Predicates . body with
| Sil . Hpointsto ( e' , se' , te' ) :: body_rest ->
| Predicates . Hpointsto ( e' , se' , te' ) :: body_rest ->
let atoms_se_te_list =
let atoms_se_te_list =
strexp_extend_values pname tenv orig_prop true Ident . kfootprint ( ref max_stamp ) se' te'
strexp_extend_values pname tenv orig_prop true Ident . kfootprint ( ref max_stamp ) se' te'
offset inst
offset inst
in
in
let atoms_body_list =
let atoms_body_list =
List . map
List . map
~ f : ( fun ( atoms0 , se0 , te0 ) -> ( atoms0 , Sil . Hpointsto ( e' , se0 , te0 ) :: body_rest ) )
~ f : ( fun ( atoms0 , se0 , te0 ) ->
( atoms0 , Predicates . Hpointsto ( e' , se0 , te0 ) :: body_rest ) )
atoms_se_te_list
atoms_se_te_list
in
in
let atoms_hpara_list =
let atoms_hpara_list =
List . map
List . map
~ f : ( fun ( atoms , body' ) -> ( atoms , { hpara with Sil . body = body' } ) )
~ f : ( fun ( atoms , body' ) -> ( atoms , { hpara with Predicates . body = body' } ) )
atoms_body_list
atoms_body_list
in
in
List . map
List . map
~ f : ( fun ( atoms , hpara' ) -> ( atoms , Sil . Hlseg ( k , hpara' , e1 , e2 , el ) ) )
~ f : ( fun ( atoms , hpara' ) -> ( atoms , Predicates . Hlseg ( k , hpara' , e1 , e2 , el ) ) )
atoms_hpara_list
atoms_hpara_list
| _ ->
| _ ->
assert false )
assert false )
@ -568,7 +569,7 @@ let prop_iter_extend_ptsto pname tenv orig_prop iter lexp inst =
let iter' =
let iter' =
List . fold ~ f : ( Prop . prop_iter_add_atom ! BiabductionConfig . footprint ) ~ init : iter atoms
List . fold ~ f : ( Prop . prop_iter_add_atom ! BiabductionConfig . footprint ) ~ init : iter atoms
in
in
Prop . prop_iter_update_current iter' ( Sil . Hpointsto ( e , se , te ) )
Prop . prop_iter_update_current iter' ( Predicates . Hpointsto ( e , se , te ) )
in
in
let do_extend e se te =
let do_extend e se te =
if Config . trace_rearrange then (
if Config . trace_rearrange then (
@ -576,7 +577,7 @@ let prop_iter_extend_ptsto pname tenv orig_prop iter lexp inst =
L . d_str " e: " ;
L . d_str " e: " ;
Exp . d_exp e ;
Exp . d_exp e ;
L . d_str " se : " ;
L . d_str " se : " ;
Sil . d_sexp se ;
Predicates . d_sexp se ;
L . d_str " te: " ;
L . d_str " te: " ;
Exp . d_texp_full te ;
Exp . d_texp_full te ;
L . d_ln () ;
L . d_ln () ;
@ -608,11 +609,11 @@ let prop_iter_extend_ptsto pname tenv orig_prop iter lexp inst =
let sigma_pto , sigma_rest =
let sigma_pto , sigma_rest =
List . partition_tf
List . partition_tf
~ f : ( function
~ f : ( function
| Sil . Hpointsto ( e' , _ , _ ) ->
| Predicates . Hpointsto ( e' , _ , _ ) ->
Exp . equal e e'
Exp . equal e e'
| Sil . Hlseg ( _ , _ , e1 , _ , _ ) ->
| Predicates . Hlseg ( _ , _ , e1 , _ , _ ) ->
Exp . equal e e1
Exp . equal e e1
| Sil . Hdllseg ( _ , _ , e_iF , _ , _ , e_iB , _ ) ->
| Predicates . Hdllseg ( _ , _ , e_iF , _ , _ , e_iB , _ ) ->
Exp . equal e e_iF | | Exp . equal e e_iB )
Exp . equal e e_iF | | Exp . equal e e_iB )
footprint_sigma
footprint_sigma
in
in
@ -630,7 +631,8 @@ let prop_iter_extend_ptsto pname tenv orig_prop iter lexp inst =
[ ( [] , footprint_sigma ) ]
[ ( [] , footprint_sigma ) ]
in
in
List . map
List . map
~ f : ( fun ( atoms , sigma' ) -> ( atoms , List . stable_sort ~ compare : Sil . compare_hpred sigma' ) )
~ f : ( fun ( atoms , sigma' ) ->
( atoms , List . stable_sort ~ compare : Predicates . compare_hpred sigma' ) )
atoms_sigma_list
atoms_sigma_list
in
in
let iter_atoms_fp_sigma_list = list_product iter_list atoms_fp_sigma_list in
let iter_atoms_fp_sigma_list = list_product iter_list atoms_fp_sigma_list in
@ -660,7 +662,7 @@ let prop_iter_extend_ptsto pname tenv orig_prop iter lexp inst =
res_iter_list
res_iter_list
in
in
match Prop . prop_iter_current tenv iter with
match Prop . prop_iter_current tenv iter with
| Sil . Hpointsto ( e , se , te ) , _ ->
| Predicates . Hpointsto ( e , se , te ) , _ ->
do_extend e se te
do_extend e se te
| _ ->
| _ ->
assert false
assert false
@ -695,7 +697,7 @@ let prop_iter_add_hpred_footprint_to_prop pname tenv prop (lexp, typ) inst =
| Some iter ->
| Some iter ->
Prop . prop_iter_prev_then_insert iter ptsto
Prop . prop_iter_prev_then_insert iter ptsto
in
in
let offsets_default = Sil . exp_get_offsets lexp in
let offsets_default = Predicates . exp_get_offsets lexp in
Prop . prop_iter_set_state iter offsets_default
Prop . prop_iter_set_state iter offsets_default
@ -817,10 +819,10 @@ let add_guarded_by_constraints tenv prop lexp pdesc =
false
false
in
in
match get_fld_strexp_and_typ typ typ_matches_guarded_by flds with
match get_fld_strexp_and_typ typ typ_matches_guarded_by flds with
| Some ( Sil . Eexp ( matching_exp , _ ) , _ ) ->
| Some ( Predicates . Eexp ( matching_exp , _ ) , _ ) ->
List . find_map
List . find_map
~ f : ( function
~ f : ( function
| Sil . Hpointsto ( lhs_exp , Estruct ( matching_flds , _ ) , Sizeof { typ = fld_typ } )
| Predicates . Hpointsto ( lhs_exp , Estruct ( matching_flds , _ ) , Sizeof { typ = fld_typ } )
when Exp . equal lhs_exp matching_exp ->
when Exp . equal lhs_exp matching_exp ->
get_fld_strexp_and_typ fld_typ ( is_guarded_by_fld field_part ) matching_flds
get_fld_strexp_and_typ fld_typ ( is_guarded_by_fld field_part ) matching_flds
| _ ->
| _ ->
@ -835,11 +837,12 @@ let add_guarded_by_constraints tenv prop lexp pdesc =
~ f : ( fun hpred ->
~ f : ( fun hpred ->
(* FIXME: silenced warning may be legit *)
(* FIXME: silenced warning may be legit *)
match [ @ warning " -57 " ] hpred with
match [ @ warning " -57 " ] hpred with
| Sil . Hpointsto ( ( Const ( Cclass clazz ) as lhs_exp ) , _ , Exp . Sizeof { typ } )
| Predicates . Hpointsto ( ( Const ( Cclass clazz ) as lhs_exp ) , _ , Exp . Sizeof { typ } )
| Sil . Hpointsto ( _ , Sil . Eexp ( ( Const ( Cclass clazz ) as lhs_exp ) , _ ) , Exp . Sizeof { typ } )
| Predicates . Hpointsto
( _ , Predicates . Eexp ( ( Const ( Cclass clazz ) as lhs_exp ) , _ ) , Exp . Sizeof { typ } )
when guarded_by_str_is_class guarded_by_str0 ( Ident . name_to_string clazz ) ->
when guarded_by_str_is_class guarded_by_str0 ( Ident . name_to_string clazz ) ->
Some ( Sil. Eexp ( lhs_exp , Sil . inst_none ) , typ )
Some ( Predicates. Eexp ( lhs_exp , Predicates . inst_none ) , typ )
| Sil . Hpointsto ( _ , Estruct ( flds , _ ) , Exp . Sizeof { typ } ) -> (
| Predicates . Hpointsto ( _ , Estruct ( flds , _ ) , Exp . Sizeof { typ } ) -> (
(* first, try to find a field that exactly matches the guarded-by string *)
(* first, try to find a field that exactly matches the guarded-by string *)
match get_fld_strexp_and_typ typ ( is_guarded_by_fld guarded_by_str0 ) flds with
match get_fld_strexp_and_typ typ ( is_guarded_by_fld guarded_by_str0 ) flds with
| None when guarded_by_str_is_this guarded_by_str0 ->
| None when guarded_by_str_is_this guarded_by_str0 ->
@ -852,7 +855,7 @@ let add_guarded_by_constraints tenv prop lexp pdesc =
match_on_field_type typ flds
match_on_field_type typ flds
| Some _ as res_opt ->
| Some _ as res_opt ->
res_opt )
res_opt )
| Sil . Hpointsto ( Lvar pvar , rhs_exp , Exp . Sizeof { typ } )
| Predicates . Hpointsto ( Lvar pvar , rhs_exp , Exp . Sizeof { typ } )
when ( guarded_by_str_is_current_class_this guarded_by_str0 pname
when ( guarded_by_str_is_current_class_this guarded_by_str0 pname
| | guarded_by_str_is_super_class_this guarded_by_str0 pname )
| | guarded_by_str_is_super_class_this guarded_by_str0 pname )
&& Pvar . is_this pvar ->
&& Pvar . is_this pvar ->
@ -915,7 +918,7 @@ let add_guarded_by_constraints tenv prop lexp pdesc =
false )
false )
| | (* or the prop says we already have the lock *)
| | (* or the prop says we already have the lock *)
List . exists
List . exists
~ f : ( function Sil . Apred ( Alocked , _ ) -> true | _ -> false )
~ f : ( function Predicates . Apred ( Alocked , _ ) -> true | _ -> false )
( Attribute . get_for_exp tenv prop guarded_by_exp )
( Attribute . get_for_exp tenv prop guarded_by_exp )
in
in
let guardedby_is_self_referential =
let guardedby_is_self_referential =
@ -937,13 +940,13 @@ let add_guarded_by_constraints tenv prop lexp pdesc =
let is_accessible_through_local_ref exp =
let is_accessible_through_local_ref exp =
List . exists
List . exists
~ f : ( function
~ f : ( function
| Sil . Hpointsto ( Lvar _ , Eexp ( rhs_exp , _ ) , _ ) ->
| Predicates . Hpointsto ( Lvar _ , Eexp ( rhs_exp , _ ) , _ ) ->
Exp . equal exp rhs_exp
Exp . equal exp rhs_exp
| Sil . Hpointsto ( _ , Estruct ( flds , _ ) , _ ) ->
| Predicates . Hpointsto ( _ , Estruct ( flds , _ ) , _ ) ->
List . exists
List . exists
~ f : ( fun ( fld , strexp ) ->
~ f : ( fun ( fld , strexp ) ->
match strexp with
match strexp with
| Sil . Eexp ( rhs_exp , _ ) ->
| Predicates . Eexp ( rhs_exp , _ ) ->
Exp . equal exp rhs_exp && not ( Typ . Fieldname . equal fld accessed_fld )
Exp . equal exp rhs_exp && not ( Typ . Fieldname . equal fld accessed_fld )
| _ ->
| _ ->
false )
false )
@ -965,7 +968,7 @@ let add_guarded_by_constraints tenv prop lexp pdesc =
&& not ( proc_has_suppress_guarded_by_annot pdesc )
&& not ( proc_has_suppress_guarded_by_annot pdesc )
in
in
match find_guarded_by_exp guarded_by_str prop . Prop . sigma with
match find_guarded_by_exp guarded_by_str prop . Prop . sigma with
| Some ( Sil . Eexp ( guarded_by_exp , _ ) , typ ) ->
| Some ( Predicates . Eexp ( guarded_by_exp , _ ) , typ ) ->
if is_read_write_lock typ then
if is_read_write_lock typ then
(* TODO: model/understand read-write locks rather than ignoring them *)
(* TODO: model/understand read-write locks rather than ignoring them *)
prop
prop
@ -1006,13 +1009,13 @@ let add_guarded_by_constraints tenv prop lexp pdesc =
in
in
let check_fld_locks typ prop_acc ( fld , strexp ) =
let check_fld_locks typ prop_acc ( fld , strexp ) =
match strexp with
match strexp with
| Sil . Eexp ( exp , _ ) when Exp . equal exp lexp ->
| Predicates . Eexp ( exp , _ ) when Exp . equal exp lexp ->
enforce_guarded_access fld typ prop_acc
enforce_guarded_access fld typ prop_acc
| _ ->
| _ ->
prop_acc
prop_acc
in
in
let hpred_check_flds prop_acc = function
let hpred_check_flds prop_acc = function
| Sil . Hpointsto ( _ , Estruct ( flds , _ ) , Sizeof { typ } ) ->
| Predicates . Hpointsto ( _ , Estruct ( flds , _ ) , Sizeof { typ } ) ->
List . fold ~ f : ( check_fld_locks typ ) ~ init : prop_acc flds
List . fold ~ f : ( check_fld_locks typ ) ~ init : prop_acc flds
| _ ->
| _ ->
prop_acc
prop_acc
@ -1053,7 +1056,7 @@ let prop_iter_add_hpred_footprint pname tenv orig_prop iter (lexp, typ) inst =
List . fold ~ f : ( Prop . prop_iter_add_atom ! BiabductionConfig . footprint ) ~ init : iter_foot atoms
List . fold ~ f : ( Prop . prop_iter_add_atom ! BiabductionConfig . footprint ) ~ init : iter_foot atoms
in
in
let iter' = Prop . prop_iter_replace_footprint_sigma iter_foot_atoms sigma_fp in
let iter' = Prop . prop_iter_replace_footprint_sigma iter_foot_atoms sigma_fp in
let offsets_default = Sil . exp_get_offsets lexp in
let offsets_default = Predicates . exp_get_offsets lexp in
Prop . prop_iter_set_state iter' offsets_default
Prop . prop_iter_set_state iter' offsets_default
@ -1117,7 +1120,7 @@ let iter_rearrange_ptsto pname tenv orig_prop iter lexp inst =
else (
else (
check_field_splitting () ;
check_field_splitting () ;
match Prop . prop_iter_current tenv iter with
match Prop . prop_iter_current tenv iter with
| Sil . Hpointsto ( e , se , te ) , offset ->
| Predicates . Hpointsto ( e , se , te ) , offset ->
let max_stamp = Prop . prop_iter_max_stamp iter in
let max_stamp = Prop . prop_iter_max_stamp iter in
let atoms_se_te_list =
let atoms_se_te_list =
strexp_extend_values pname tenv orig_prop false Ident . kprimed ( ref max_stamp ) se te
strexp_extend_values pname tenv orig_prop false Ident . kprimed ( ref max_stamp ) se te
@ -1127,7 +1130,7 @@ let iter_rearrange_ptsto pname tenv orig_prop iter lexp inst =
let iter' =
let iter' =
List . fold ~ f : ( Prop . prop_iter_add_atom ! BiabductionConfig . footprint ) ~ init : iter atoms'
List . fold ~ f : ( Prop . prop_iter_add_atom ! BiabductionConfig . footprint ) ~ init : iter atoms'
in
in
Prop . prop_iter_update_current iter' ( Sil . Hpointsto ( e , se' , te' ) )
Prop . prop_iter_update_current iter' ( Predicates . Hpointsto ( e , se' , te' ) )
in
in
let filter it =
let filter it =
let p = Prop . prop_iter_to_prop tenv it in
let p = Prop . prop_iter_to_prop tenv it in
@ -1151,20 +1154,20 @@ let iter_rearrange_ne_lseg tenv recurse_on_iters iter para e1 e2 elist =
if Config . nelseg then
if Config . nelseg then
let iter_inductive_case =
let iter_inductive_case =
let n' = Exp . Var ( Ident . create_fresh Ident . kprimed ) in
let n' = Exp . Var ( Ident . create_fresh Ident . kprimed ) in
let _ , para_inst1 = Sil . hpara_instantiate para e1 n' elist in
let _ , para_inst1 = Predicates . hpara_instantiate para e1 n' elist in
let hpred_list1 = para_inst1 @ [ Prop . mk_lseg tenv Sil . Lseg_NE para n' e2 elist ] in
let hpred_list1 = para_inst1 @ [ Prop . mk_lseg tenv Lseg_NE para n' e2 elist ] in
Prop . prop_iter_update_current_by_list iter hpred_list1
Prop . prop_iter_update_current_by_list iter hpred_list1
in
in
let iter_base_case =
let iter_base_case =
let _ , para_inst = Sil . hpara_instantiate para e1 e2 elist in
let _ , para_inst = Predicates . hpara_instantiate para e1 e2 elist in
Prop . prop_iter_update_current_by_list iter para_inst
Prop . prop_iter_update_current_by_list iter para_inst
in
in
recurse_on_iters [ iter_inductive_case ; iter_base_case ]
recurse_on_iters [ iter_inductive_case ; iter_base_case ]
else
else
let iter_inductive_case =
let iter_inductive_case =
let n' = Exp . Var ( Ident . create_fresh Ident . kprimed ) in
let n' = Exp . Var ( Ident . create_fresh Ident . kprimed ) in
let _ , para_inst1 = Sil . hpara_instantiate para e1 n' elist in
let _ , para_inst1 = Predicates . hpara_instantiate para e1 n' elist in
let hpred_list1 = para_inst1 @ [ Prop . mk_lseg tenv Sil . Lseg_PE para n' e2 elist ] in
let hpred_list1 = para_inst1 @ [ Prop . mk_lseg tenv Lseg_PE para n' e2 elist ] in
Prop . prop_iter_update_current_by_list iter hpred_list1
Prop . prop_iter_update_current_by_list iter hpred_list1
in
in
recurse_on_iters [ iter_inductive_case ]
recurse_on_iters [ iter_inductive_case ]
@ -1174,14 +1177,12 @@ let iter_rearrange_ne_lseg tenv recurse_on_iters iter para e1 e2 elist =
let iter_rearrange_ne_dllseg_first tenv recurse_on_iters iter para_dll e1 e2 e3 e4 elist =
let iter_rearrange_ne_dllseg_first tenv recurse_on_iters iter para_dll e1 e2 e3 e4 elist =
let iter_inductive_case =
let iter_inductive_case =
let n' = Exp . Var ( Ident . create_fresh Ident . kprimed ) in
let n' = Exp . Var ( Ident . create_fresh Ident . kprimed ) in
let _ , para_dll_inst1 = Sil . hpara_dll_instantiate para_dll e1 e2 n' elist in
let _ , para_dll_inst1 = Predicates . hpara_dll_instantiate para_dll e1 e2 n' elist in
let hpred_list1 =
let hpred_list1 = para_dll_inst1 @ [ Prop . mk_dllseg tenv Lseg_NE para_dll n' e1 e3 e4 elist ] in
para_dll_inst1 @ [ Prop . mk_dllseg tenv Sil . Lseg_NE para_dll n' e1 e3 e4 elist ]
in
Prop . prop_iter_update_current_by_list iter hpred_list1
Prop . prop_iter_update_current_by_list iter hpred_list1
in
in
let iter_base_case =
let iter_base_case =
let _ , para_dll_inst = Sil . hpara_dll_instantiate para_dll e1 e2 e3 elist in
let _ , para_dll_inst = Predicates . hpara_dll_instantiate para_dll e1 e2 e3 elist in
let iter' = Prop . prop_iter_update_current_by_list iter para_dll_inst in
let iter' = Prop . prop_iter_update_current_by_list iter para_dll_inst in
let prop' = Prop . prop_iter_to_prop tenv iter' in
let prop' = Prop . prop_iter_to_prop tenv iter' in
let prop'' = Prop . conjoin_eq tenv ~ footprint : ! BiabductionConfig . footprint e1 e4 prop' in
let prop'' = Prop . conjoin_eq tenv ~ footprint : ! BiabductionConfig . footprint e1 e4 prop' in
@ -1194,14 +1195,12 @@ let iter_rearrange_ne_dllseg_first tenv recurse_on_iters iter para_dll e1 e2 e3
let iter_rearrange_ne_dllseg_last tenv recurse_on_iters iter para_dll e1 e2 e3 e4 elist =
let iter_rearrange_ne_dllseg_last tenv recurse_on_iters iter para_dll e1 e2 e3 e4 elist =
let iter_inductive_case =
let iter_inductive_case =
let n' = Exp . Var ( Ident . create_fresh Ident . kprimed ) in
let n' = Exp . Var ( Ident . create_fresh Ident . kprimed ) in
let _ , para_dll_inst1 = Sil . hpara_dll_instantiate para_dll e4 n' e3 elist in
let _ , para_dll_inst1 = Predicates . hpara_dll_instantiate para_dll e4 n' e3 elist in
let hpred_list1 =
let hpred_list1 = para_dll_inst1 @ [ Prop . mk_dllseg tenv Lseg_NE para_dll e1 e2 e4 n' elist ] in
para_dll_inst1 @ [ Prop . mk_dllseg tenv Sil . Lseg_NE para_dll e1 e2 e4 n' elist ]
in
Prop . prop_iter_update_current_by_list iter hpred_list1
Prop . prop_iter_update_current_by_list iter hpred_list1
in
in
let iter_base_case =
let iter_base_case =
let _ , para_dll_inst = Sil . hpara_dll_instantiate para_dll e4 e2 e3 elist in
let _ , para_dll_inst = Predicates . hpara_dll_instantiate para_dll e4 e2 e3 elist in
let iter' = Prop . prop_iter_update_current_by_list iter para_dll_inst in
let iter' = Prop . prop_iter_update_current_by_list iter para_dll_inst in
let prop' = Prop . prop_iter_to_prop tenv iter' in
let prop' = Prop . prop_iter_to_prop tenv iter' in
let prop'' = Prop . conjoin_eq tenv ~ footprint : ! BiabductionConfig . footprint e1 e4 prop' in
let prop'' = Prop . conjoin_eq tenv ~ footprint : ! BiabductionConfig . footprint e1 e4 prop' in
@ -1214,8 +1213,8 @@ let iter_rearrange_ne_dllseg_last tenv recurse_on_iters iter para_dll e1 e2 e3 e
let iter_rearrange_pe_lseg tenv recurse_on_iters default_case_iter iter para e1 e2 elist =
let iter_rearrange_pe_lseg tenv recurse_on_iters default_case_iter iter para e1 e2 elist =
let iter_nonemp_case =
let iter_nonemp_case =
let n' = Exp . Var ( Ident . create_fresh Ident . kprimed ) in
let n' = Exp . Var ( Ident . create_fresh Ident . kprimed ) in
let _ , para_inst1 = Sil . hpara_instantiate para e1 n' elist in
let _ , para_inst1 = Predicates . hpara_instantiate para e1 n' elist in
let hpred_list1 = para_inst1 @ [ Prop . mk_lseg tenv Sil . Lseg_PE para n' e2 elist ] in
let hpred_list1 = para_inst1 @ [ Prop . mk_lseg tenv Lseg_PE para n' e2 elist ] in
Prop . prop_iter_update_current_by_list iter hpred_list1
Prop . prop_iter_update_current_by_list iter hpred_list1
in
in
let iter_subcases =
let iter_subcases =
@ -1236,10 +1235,8 @@ let iter_rearrange_pe_dllseg_first tenv recurse_on_iters default_case_iter iter
elist =
elist =
let iter_inductive_case =
let iter_inductive_case =
let n' = Exp . Var ( Ident . create_fresh Ident . kprimed ) in
let n' = Exp . Var ( Ident . create_fresh Ident . kprimed ) in
let _ , para_dll_inst1 = Sil . hpara_dll_instantiate para_dll e1 e2 n' elist in
let _ , para_dll_inst1 = Predicates . hpara_dll_instantiate para_dll e1 e2 n' elist in
let hpred_list1 =
let hpred_list1 = para_dll_inst1 @ [ Prop . mk_dllseg tenv Lseg_PE para_dll n' e1 e3 e4 elist ] in
para_dll_inst1 @ [ Prop . mk_dllseg tenv Sil . Lseg_PE para_dll n' e1 e3 e4 elist ]
in
Prop . prop_iter_update_current_by_list iter hpred_list1
Prop . prop_iter_update_current_by_list iter hpred_list1
in
in
let iter_subcases =
let iter_subcases =
@ -1261,10 +1258,8 @@ let iter_rearrange_pe_dllseg_last tenv recurse_on_iters default_case_iter iter p
elist =
elist =
let iter_inductive_case =
let iter_inductive_case =
let n' = Exp . Var ( Ident . create_fresh Ident . kprimed ) in
let n' = Exp . Var ( Ident . create_fresh Ident . kprimed ) in
let _ , para_dll_inst1 = Sil . hpara_dll_instantiate para_dll e4 n' e3 elist in
let _ , para_dll_inst1 = Predicates . hpara_dll_instantiate para_dll e4 n' e3 elist in
let hpred_list1 =
let hpred_list1 = para_dll_inst1 @ [ Prop . mk_dllseg tenv Lseg_PE para_dll e1 e2 e4 n' elist ] in
para_dll_inst1 @ [ Prop . mk_dllseg tenv Sil . Lseg_PE para_dll e1 e2 e4 n' elist ]
in
Prop . prop_iter_update_current_by_list iter hpred_list1
Prop . prop_iter_update_current_by_list iter hpred_list1
in
in
let iter_subcases =
let iter_subcases =
@ -1283,7 +1278,7 @@ let iter_rearrange_pe_dllseg_last tenv recurse_on_iters default_case_iter iter p
(* * find the type at the offset from the given type expression, if any *)
(* * find the type at the offset from the given type expression, if any *)
let type_at_offset tenv texp off =
let type_at_offset tenv texp off =
let rec strip_offset ( off : Sil . offset list ) ( typ : Typ . t ) =
let rec strip_offset ( off : Predicates . offset list ) ( typ : Typ . t ) =
match ( off , typ . desc ) with
match ( off , typ . desc ) with
| [] , _ ->
| [] , _ ->
Some typ
Some typ
@ -1310,7 +1305,7 @@ let type_at_offset tenv texp off =
let check_type_size tenv pname prop texp off typ_from_instr =
let check_type_size tenv pname prop texp off typ_from_instr =
L . d_strln ~ color : Orange " check_type_size " ;
L . d_strln ~ color : Orange " check_type_size " ;
L . d_str " off: " ;
L . d_str " off: " ;
Sil . d_offset_list off ;
Predicates . d_offset_list off ;
L . d_ln () ;
L . d_ln () ;
L . d_str " typ_from_instr: " ;
L . d_str " typ_from_instr: " ;
Typ . d_full typ_from_instr ;
Typ . d_full typ_from_instr ;
@ -1345,9 +1340,9 @@ let check_type_size tenv pname prop texp off typ_from_instr =
* that the theorem prover cannot prove the inconsistency of any of the
* that the theorem prover cannot prove the inconsistency of any of the
* new iters in the result . * )
* new iters in the result . * )
let rec iter_rearrange pname tenv lexp typ_from_instr prop iter inst :
let rec iter_rearrange pname tenv lexp typ_from_instr prop iter inst :
Sil . offset list Prop . prop_iter list =
Predicates . offset list Prop . prop_iter list =
let rec root_typ_of_offsets = function
let rec root_typ_of_offsets = function
| Sil . Off_fld ( f , fld_typ ) :: _ -> (
| Predicates . Off_fld ( f , fld_typ ) :: _ -> (
match fld_typ . desc with
match fld_typ . desc with
| Tstruct _ ->
| Tstruct _ ->
(* access through field: get the struct type from the field *)
(* access through field: get the struct type from the field *)
@ -1362,12 +1357,12 @@ let rec iter_rearrange pname tenv lexp typ_from_instr prop iter inst :
fld_typ
fld_typ
| _ ->
| _ ->
typ_from_instr )
typ_from_instr )
| Sil . Off_index _ :: off ->
| Predicates . Off_index _ :: off ->
Typ . mk_array ( root_typ_of_offsets off )
Typ . mk_array ( root_typ_of_offsets off )
| _ ->
| _ ->
typ_from_instr
typ_from_instr
in
in
let typ = root_typ_of_offsets ( Sil . exp_get_offsets lexp ) in
let typ = root_typ_of_offsets ( Predicates . exp_get_offsets lexp ) in
if Config . trace_rearrange then (
if Config . trace_rearrange then (
L . d_increase_indent () ;
L . d_increase_indent () ;
L . d_strln " entering iter_rearrange " ;
L . d_strln " entering iter_rearrange " ;
@ -1414,9 +1409,9 @@ let rec iter_rearrange pname tenv lexp typ_from_instr prop iter inst :
f_many_iters [] iters
f_many_iters [] iters
in
in
let filter = function
let filter = function
| Sil . Hpointsto ( base , _ , _ ) | Sil . Hlseg ( _ , _ , base , _ , _ ) ->
| Predicates . Hpointsto ( base , _ , _ ) | Predicates . Hlseg ( _ , _ , base , _ , _ ) ->
Prover . is_root tenv prop base lexp
Prover . is_root tenv prop base lexp
| Sil . Hdllseg ( _ , _ , first , _ , _ , last , _ ) -> (
| Predicates . Hdllseg ( _ , _ , first , _ , _ , last , _ ) -> (
let result_first = Prover . is_root tenv prop first lexp in
let result_first = Prover . is_root tenv prop first lexp in
match result_first with
match result_first with
| None ->
| None ->
@ -1430,14 +1425,14 @@ let rec iter_rearrange pname tenv lexp typ_from_instr prop iter inst :
[ default_case_iter iter ]
[ default_case_iter iter ]
| Some iter -> (
| Some iter -> (
match Prop . prop_iter_current tenv iter with
match Prop . prop_iter_current tenv iter with
| Sil . Hpointsto ( _ , _ , texp ) , off ->
| Predicates . Hpointsto ( _ , _ , texp ) , off ->
if Config . type_size then check_type_size tenv pname prop texp off typ_from_instr ;
if Config . type_size then check_type_size tenv pname prop texp off typ_from_instr ;
iter_rearrange_ptsto pname tenv prop iter lexp inst
iter_rearrange_ptsto pname tenv prop iter lexp inst
| Sil. Hlseg ( Sil . Lseg_NE , para , e1 , e2 , elist ) , _ ->
| Predicates. Hlseg ( Lseg_NE , para , e1 , e2 , elist ) , _ ->
iter_rearrange_ne_lseg tenv recurse_on_iters iter para e1 e2 elist
iter_rearrange_ne_lseg tenv recurse_on_iters iter para e1 e2 elist
| Sil. Hlseg ( Sil . Lseg_PE , para , e1 , e2 , elist ) , _ ->
| Predicates. Hlseg ( Lseg_PE , para , e1 , e2 , elist ) , _ ->
iter_rearrange_pe_lseg tenv recurse_on_iters default_case_iter iter para e1 e2 elist
iter_rearrange_pe_lseg tenv recurse_on_iters default_case_iter iter para e1 e2 elist
| Sil. Hdllseg ( Sil . Lseg_NE , para_dll , e1 , e2 , e3 , e4 , elist ) , _ -> (
| Predicates. Hdllseg ( Lseg_NE , para_dll , e1 , e2 , e3 , e4 , elist ) , _ -> (
match ( Prover . is_root tenv prop e1 lexp , Prover . is_root tenv prop e4 lexp ) with
match ( Prover . is_root tenv prop e1 lexp , Prover . is_root tenv prop e4 lexp ) with
| None , None ->
| None , None ->
assert false
assert false
@ -1445,7 +1440,7 @@ let rec iter_rearrange pname tenv lexp typ_from_instr prop iter inst :
iter_rearrange_ne_dllseg_first tenv recurse_on_iters iter para_dll e1 e2 e3 e4 elist
iter_rearrange_ne_dllseg_first tenv recurse_on_iters iter para_dll e1 e2 e3 e4 elist
| _ , Some _ ->
| _ , Some _ ->
iter_rearrange_ne_dllseg_last tenv recurse_on_iters iter para_dll e1 e2 e3 e4 elist )
iter_rearrange_ne_dllseg_last tenv recurse_on_iters iter para_dll e1 e2 e3 e4 elist )
| Sil. Hdllseg ( Sil . Lseg_PE , para_dll , e1 , e2 , e3 , e4 , elist ) , _ -> (
| Predicates. Hdllseg ( Lseg_PE , para_dll , e1 , e2 , e3 , e4 , elist ) , _ -> (
match ( Prover . is_root tenv prop e1 lexp , Prover . is_root tenv prop e4 lexp ) with
match ( Prover . is_root tenv prop e1 lexp , Prover . is_root tenv prop e4 lexp ) with
| None , None ->
| None , None ->
assert false
assert false
@ -1474,7 +1469,7 @@ let var_has_annotation pdesc is_annotation pvar =
let attr_has_annot is_annotation tenv prop exp =
let attr_has_annot is_annotation tenv prop exp =
let attr_has_annot = function
let attr_has_annot = function
| Sil . Apred ( ( Aretval ( pname , ret_attr ) | Aundef ( pname , ret_attr , _ , _ ) ) , _ )
| Predicates . Apred ( ( Aretval ( pname , ret_attr ) | Aundef ( pname , ret_attr , _ , _ ) ) , _ )
when is_annotation ret_attr ->
when is_annotation ret_attr ->
Some ( Typ . Procname . to_string pname )
Some ( Typ . Procname . to_string pname )
| _ ->
| _ ->
@ -1494,7 +1489,7 @@ let is_strexp_pt_fld_with_annot tenv obj_str is_annotation typ deref_exp (fld, s
false
false
in
in
match strexp with
match strexp with
| Sil . Eexp ( ( Exp . Var _ as exp ) , _ ) when Exp . equal exp deref_exp ->
| Predicates . Eexp ( ( Exp . Var _ as exp ) , _ ) when Exp . equal exp deref_exp ->
let has_annot = fld_has_annot fld in
let has_annot = fld_has_annot fld in
if has_annot then obj_str := Some ( Typ . Fieldname . to_simplified_string fld ) ;
if has_annot then obj_str := Some ( Typ . Fieldname . to_simplified_string fld ) ;
has_annot
has_annot
@ -1509,7 +1504,7 @@ let is_only_pt_by_fld_or_param_with_annot pdesc tenv prop deref_exp is_annotatio
let obj_str = ref None in
let obj_str = ref None in
let is_pt_by_fld_or_param_with_annot hpred =
let is_pt_by_fld_or_param_with_annot hpred =
match hpred with
match hpred with
| Sil . Hpointsto ( Exp . Lvar pvar , Sil . Eexp ( ( Exp . Var _ as exp ) , _ ) , _ )
| Predicates . Hpointsto ( Exp . Lvar pvar , Eexp ( ( Exp . Var _ as exp ) , _ ) , _ )
when Exp . equal exp deref_exp ->
when Exp . equal exp deref_exp ->
let var_has_annotation = Pvar . is_seed pvar && var_has_annotation pdesc is_annotation pvar in
let var_has_annotation = Pvar . is_seed pvar && var_has_annotation pdesc is_annotation pvar in
if var_has_annotation then obj_str := Some ( Pvar . to_string pvar ) ;
if var_has_annotation then obj_str := Some ( Pvar . to_string pvar ) ;
@ -1517,7 +1512,7 @@ let is_only_pt_by_fld_or_param_with_annot pdesc tenv prop deref_exp is_annotatio
if Option . is_some procname_str_opt then obj_str := procname_str_opt ;
if Option . is_some procname_str_opt then obj_str := procname_str_opt ;
(* it's ok for a local with no annotation to point to deref_exp *)
(* it's ok for a local with no annotation to point to deref_exp *)
var_has_annotation | | Option . is_some procname_str_opt | | Pvar . is_local pvar
var_has_annotation | | Option . is_some procname_str_opt | | Pvar . is_local pvar
| Sil . Hpointsto ( _ , Sil . Estruct ( flds , _ ) , Exp . Sizeof { typ } ) ->
| Predicates . Hpointsto ( _ , Estruct ( flds , _ ) , Exp . Sizeof { typ } ) ->
List . for_all ~ f : ( is_strexp_pt_fld_with_annot tenv obj_str is_annotation typ deref_exp ) flds
List . for_all ~ f : ( is_strexp_pt_fld_with_annot tenv obj_str is_annotation typ deref_exp ) flds
| _ ->
| _ ->
true
true
@ -1648,7 +1643,7 @@ let check_call_to_objc_block_error tenv pdesc prop fun_exp loc =
let get_exp_called () =
let get_exp_called () =
(* Exp called in the block's function call *)
(* Exp called in the block's function call *)
match State . get_instr () with
match State . get_instr () with
| Some ( Sil . Call ( _ , Exp . Var id , _ , _ , _ ) ) ->
| Some ( Sil . Call ( _ , Var id , _ , _ , _ ) ) ->
Errdesc . find_ident_assignment ( State . get_node_exn () ) id
Errdesc . find_ident_assignment ( State . get_node_exn () ) id
| _ ->
| _ ->
None
None
@ -1708,7 +1703,7 @@ let check_call_to_objc_block_error tenv pdesc prop fun_exp loc =
It returns an iterator with [ lexp | -> strexp : typ ] as current predicate
It returns an iterator with [ lexp | -> strexp : typ ] as current predicate
and the path ( an [ offsetlist ] ) which leads to [ lexp ] as the iterator state . * )
and the path ( an [ offsetlist ] ) which leads to [ lexp ] as the iterator state . * )
let rearrange ? ( report_deref_errors = true ) pdesc tenv lexp typ prop loc :
let rearrange ? ( report_deref_errors = true ) pdesc tenv lexp typ prop loc :
Sil . offset list Prop . prop_iter list =
Predicates . offset list Prop . prop_iter list =
let nlexp =
let nlexp =
match Prop . exp_normalize_prop tenv prop lexp with
match Prop . exp_normalize_prop tenv prop lexp with
| Exp . BinOp ( Binop . PlusPI , ep , e ) ->
| Exp . BinOp ( Binop . PlusPI , ep , e ) ->
@ -1718,7 +1713,7 @@ let rearrange ?(report_deref_errors = true) pdesc tenv lexp typ prop loc :
e
e
in
in
let ptr_tested_for_zero = Prover . check_disequal tenv prop ( Exp . root_of_lexp nlexp ) Exp . zero in
let ptr_tested_for_zero = Prover . check_disequal tenv prop ( Exp . root_of_lexp nlexp ) Exp . zero in
let inst = Sil . inst_rearrange ( not ptr_tested_for_zero ) loc ( State . get_path_pos () ) in
let inst = Predicates . inst_rearrange ( not ptr_tested_for_zero ) loc ( State . get_path_pos () ) in
L . d_strln " .... Rearrangement Start .... " ;
L . d_strln " .... Rearrangement Start .... " ;
L . d_str " Exp: " ;
L . d_str " Exp: " ;
Exp . d_exp nlexp ;
Exp . d_exp nlexp ;