@@ -30,8 +30,20 @@ struct
30
30
| [] -> fail " ^::"
31
31
end
32
32
33
+ type access =
34
+ | Access of LibraryDesc.Access .t
35
+ | If of (unit -> bool ) * access
36
+
37
+ let rec eval_access = function
38
+ | Access acc -> Some acc
39
+ | If (p , access ) ->
40
+ if p () then
41
+ eval_access access
42
+ else
43
+ None
44
+
33
45
type ('k, 'l, 'r) arg_desc = {
34
- accesses : Access .t list ;
46
+ accesses : access list ;
35
47
match_arg : (Cil .exp , 'k , 'r ) Pattern .t ;
36
48
match_var_args : (Cil .exp list , 'l , 'r ) Pattern .t ;
37
49
}
@@ -51,15 +63,21 @@ let rec accs: type k r. (k, r) args_desc -> Accesses.t = fun args_desc args ->
51
63
match args_desc, args with
52
64
| [] , [] -> []
53
65
| VarArgs arg_desc , args ->
54
- List. map (fun acc ->
55
- (acc, args)
66
+ List. filter_map (fun access ->
67
+ match eval_access access with
68
+ | Some acc -> Some (acc, args)
69
+ | None -> None
56
70
) arg_desc.accesses
57
71
| arg_desc :: args_desc , arg :: args ->
58
72
let accs'' = accs args_desc args in
59
- List. fold_left (fun (accs'' : (Access.t * Cil.exp list) list ) (acc : Access.t ) ->
60
- match List. assoc_opt acc accs'' with
61
- | Some args -> (acc, arg :: args) :: List. remove_assoc acc accs''
62
- | None -> (acc, [arg]) :: accs''
73
+ List. fold_left (fun (accs'' : (Access.t * Cil.exp list) list ) (access : access ) ->
74
+ match eval_access access with
75
+ | Some acc ->
76
+ begin match List. assoc_opt acc accs'' with
77
+ | Some args -> (acc, arg :: args) :: List. remove_assoc acc accs''
78
+ | None -> (acc, [arg]) :: accs''
79
+ end
80
+ | None -> accs''
63
81
) accs'' arg_desc.accesses
64
82
| _ , _ -> invalid_arg " accs"
65
83
@@ -94,13 +112,15 @@ let drop (_name: string) accesses = { empty_drop_desc with accesses; }
94
112
let drop' accesses = { empty_drop_desc with accesses; }
95
113
96
114
97
- let r = Access. { kind = Read ; deep = false ; }
98
- let r_deep = Access. { kind = Read ; deep = true ; }
99
- let w = Access. { kind = Write ; deep = false ; }
100
- let w_deep = Access. { kind = Write ; deep = true ; }
101
- let f = Access. { kind = Free ; deep = false ; }
102
- let f_deep = Access. { kind = Free ; deep = true ; }
103
- let s = Access. { kind = Spawn ; deep = false ; }
104
- let s_deep = Access. { kind = Spawn ; deep = true ; }
105
- let c = Access. { kind = Spawn ; deep = false ; } (* TODO: Sound, but very imprecise hack for calls to function pointers given as arguments. *)
106
- let c_deep = Access. { kind = Spawn ; deep = true ; }
115
+ let r = Access { kind = Read ; deep = false ; }
116
+ let r_deep = Access { kind = Read ; deep = true ; }
117
+ let w = Access { kind = Write ; deep = false ; }
118
+ let w_deep = Access { kind = Write ; deep = true ; }
119
+ let f = Access { kind = Free ; deep = false ; }
120
+ let f_deep = Access { kind = Free ; deep = true ; }
121
+ let s = Access { kind = Spawn ; deep = false ; }
122
+ let s_deep = Access { kind = Spawn ; deep = true ; }
123
+ let c = Access { kind = Spawn ; deep = false ; } (* TODO: Sound, but very imprecise hack for calls to function pointers given as arguments. *)
124
+ let c_deep = Access { kind = Spawn ; deep = true ; }
125
+
126
+ let if_ p access = If (p, access)
0 commit comments