2525 SOFTWARE.
2626 ============================================================================= *)
2727
28+ (* chlib *)
29+ open CHLanguage
30+
31+ (* chutil *)
32+
33+ (* xprlib *)
34+ open XprTypes
35+
2836(* cchlib *)
2937open CCHBasicTypes
38+ open CCHTypesToPretty
39+ open CCHTypesUtil
3040
3141(* cchpre *)
3242open CCHPreTypes
@@ -38,7 +48,7 @@ open CCHAnalysisTypes
3848let x2p = XprToPretty. xpr_formatter#pr_expr
3949let p2s = CHPrettyUtil. pretty_to_string
4050let _x2s x = p2s (x2p x)
41- let _e2s e = p2s (CCHTypesToPretty. exp_to_pretty e)
51+ let e2s e = p2s (CCHTypesToPretty. exp_to_pretty e)
4252
4353
4454let _fenv = CCHFileEnvironment. file_environment
@@ -47,23 +57,171 @@ let _fenv = CCHFileEnvironment.file_environment
4757class locally_initialized_checker_t
4858 (poq : po_query_int )
4959 (vinfo : varinfo )
50- (_lval : lval )
51- (_invs : invariant_int list ) =
60+ (lval : lval )
61+ (invs : invariant_int list ) =
5262object (self )
5363
5464 method private vinfo = vinfo
5565
66+ method private get_symbol_name (s : symbol_t ) =
67+ s#getBaseName
68+ ^ (match s#getAttributes with
69+ | [] -> " "
70+ | l -> " (" ^ (String. concat " " l) ^ " )" )
71+
72+ method private xpr_implies_safe (invindex : int ) (x : xpr_t ) =
73+ if poq#is_api_expression x then
74+ let _ =
75+ poq#set_diagnostic_arg
76+ 2 (" api expression: " ^ (e2s (poq#get_api_expression x))) in
77+ match poq#get_api_expression x with
78+ | Lval (Mem (Lval (Var vpar, NoOffset )), NoOffset )
79+ when not ((fst vpar) = vinfo.vname) ->
80+ let deps = DLocal ([invindex]) in
81+ let msg =
82+ (" value of " ^ (p2s (lval_to_pretty lval))
83+ ^ " is not obtained from dereferencing parameter "
84+ ^ vinfo.vname
85+ ^ " , but from a different parameter: "
86+ ^ (fst vpar)) in
87+ Some (deps, msg)
88+ | _ -> None
89+ else
90+ None
91+
92+ method private inv_implies_safe (inv : invariant_int ) =
93+ match inv#expr with
94+ | Some x -> self#xpr_implies_safe inv#index x
95+ | _ ->
96+ match inv#get_fact with
97+ | NonRelationalFact (_ , FInitializedSet l ) ->
98+ let localAssigns =
99+ List. filter (fun s -> not (s#getBaseName = " parameter" )) l in
100+ (match localAssigns with
101+ | [] -> None
102+ | _ ->
103+ let deps = DLocal [inv#index] in
104+ let msg =
105+ " local assignment(s): "
106+ ^ (String. concat
107+ " _xx_" (List. map self#get_symbol_name localAssigns)) in
108+ Some (deps, msg))
109+ | _ -> None
110+
111+ method private check_invs_safe =
112+ match invs with
113+ | [] -> false
114+ | _ ->
115+ List. fold_left (fun acc inv ->
116+ acc ||
117+ match self#inv_implies_safe inv with
118+ | Some (deps , msg ) ->
119+ begin
120+ poq#record_safe_result deps msg;
121+ true
122+ end
123+ | _ -> false ) false invs
124+
125+ method private xpr_implies_violation (invindex : int ) (x : xpr_t ) =
126+ if poq#is_api_expression x then
127+ let _ =
128+ poq#set_diagnostic_arg
129+ 2 (" api expression: " ^ (e2s (poq#get_api_expression x))) in
130+ match poq#get_api_expression x with
131+ | Lval (Mem (Lval (Var vpar, NoOffset )), NoOffset )
132+ when (fst vpar) = vinfo.vname ->
133+ let deps = DLocal ([invindex]) in
134+ let msg =
135+ (" value of " ^ (p2s (lval_to_pretty lval))
136+ ^ " is obtained from dereferencing parameter "
137+ ^ (fst vpar)) in
138+ Some (deps, msg)
139+
140+ | _ -> None
141+ else
142+ None
143+
144+ method private inv_implies_violation (inv : invariant_int ) =
145+ match inv#expr with
146+ | Some x -> self#xpr_implies_violation inv#index x
147+ | _ -> None
148+
149+ method private vinv_implies_deref_offset_violation
150+ (inv : invariant_int ) (memoffset : offset ) =
151+ match inv#expr with
152+ | Some x when poq#is_api_expression x ->
153+ begin
154+ match poq#get_api_expression x with
155+ | Lval lval ->
156+ if is_constant_offset memoffset then
157+ let memlval = (Mem (Lval lval), memoffset) in
158+ let deps = DLocal ([inv#index]) in
159+ let msg =
160+ " initialized from parameter "
161+ ^ (p2s (lval_to_pretty memlval))
162+ ^ " with offset "
163+ ^ (p2s (offset_to_pretty memoffset)) in
164+ Some (deps, msg)
165+ else
166+ None
167+ | _ ->
168+ None
169+ end
170+ | _ -> None
171+
172+ method private check_lval_deref_violation (memlval : lval ) (memoffset : offset ) =
173+ match memlval with
174+ | (Var (vname , vid ), NoOffset) when vid > 0 && vinfo.vname = vname ->
175+ let vinfovalues = poq#get_vinfo_offset_values vinfo in
176+ List. fold_left (fun acc (inv , offset ) ->
177+ acc
178+ || match offset with
179+ | NoOffset ->
180+ begin
181+ match self#vinv_implies_deref_offset_violation
182+ inv memoffset with
183+ | Some (deps , msg ) ->
184+ begin
185+ poq#record_violation_result deps msg;
186+ true
187+ end
188+ | _ -> false
189+ end
190+ | _ -> false ) false vinfovalues
191+ | _ -> false
192+
193+ method private check_lval_violation =
194+ match lval with
195+ | (Mem (Lval memlval ), memoffset ) ->
196+ self#check_lval_deref_violation memlval memoffset
197+ | _ -> false
198+
199+ method private check_invs_violation =
200+ match invs with
201+ | [] -> false
202+ | _ ->
203+ List. fold_left (fun acc inv ->
204+ acc ||
205+ match self#inv_implies_violation inv with
206+ | Some (deps , msg ) ->
207+ begin
208+ poq#record_violation_result deps msg;
209+ true
210+ end
211+ | _ -> false ) false invs
212+
56213 method check_safe =
57- let _ = poq#set_vinfo_diagnostic_invariants self#vinfo in
58- false
214+ self#check_invs_safe
59215
60- method check_violation = false
216+ method check_violation =
217+ self#check_invs_violation || self#check_lval_violation
61218
62219end
63220
64221
65222let check_locally_initialized (poq :po_query_int ) (vinfo : varinfo ) (lval :lval ) =
66- let invs = poq#get_invariants 1 in
67- let _ = poq#set_diagnostic_invariants 1 in
223+ let invs = poq#get_invariants 2 in
224+ let _ = poq#set_diagnostic_invariants 2 in
225+ let _ = poq#set_init_vinfo_mem_diagnostic_invariants vinfo (snd lval) in
68226 let checker = new locally_initialized_checker_t poq vinfo lval invs in
69227 checker#check_safe || checker#check_violation
0 commit comments