Skip to content

Commit 953c96f

Browse files
committed
CHC:POCHECK: add diagnoatic messages
1 parent dc96c4c commit 953c96f

File tree

4 files changed

+142
-35
lines changed

4 files changed

+142
-35
lines changed

CodeHawk/CHC/cchanalyze/cCHPOCheckInitialized.ml

Lines changed: 83 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -153,6 +153,8 @@ object (self)
153153
(* ----------------------------- safe ------------------------------------- *)
154154
(* check_safe
155155
- inv_implies_safe
156+
- inv_xpr_implies_safe
157+
- inv_bounded_xpr_implies_safe
156158
- check_safe_command_line_argument
157159
- check_safe_lval
158160
- check_safe_memlval
@@ -162,6 +164,29 @@ object (self)
162164
- memlval_vinv_memref_basevar_implies_safe
163165
*)
164166

167+
method private inv_xpr_implies_safe (invindex: int) (x: xpr_t) =
168+
let deps = DLocal [invindex] in
169+
let msg =
170+
"variable "
171+
^ (p2s (lval_to_pretty lval))
172+
^ " has the value "
173+
^ (x2s x) in
174+
let site = Some (__FILE__, __LINE__, "inv_xpr_implies_safe") in
175+
Some (deps, msg, site)
176+
177+
method private inv_bounded_xpr_implies_safe
178+
(invindex: int) (lb: xpr_t) (ub: xpr_t) =
179+
let deps = DLocal [invindex] in
180+
let msg =
181+
"variable "
182+
^ (p2s (lval_to_pretty lval))
183+
^ " is bounded by LB: "
184+
^ (x2s lb)
185+
^ " and UB: "
186+
^ (x2s ub) in
187+
let site = Some (__FILE__, __LINE__, "inv_bounded_xpr_implies_safe") in
188+
Some (deps, msg, site)
189+
165190
method private inv_implies_safe (inv: invariant_int) =
166191
let mname = "inv_implies_safe" in
167192
match inv#get_fact with
@@ -177,9 +202,16 @@ object (self)
177202
(String.concat
178203
"_xx_" (List.map self#get_symbol_name localAssigns)) in
179204
let site = Some (__FILE__, __LINE__, mname) in
180-
Some (deps,msg, site)
205+
Some (deps, msg, site)
181206
end
182-
| _ -> None
207+
| _ ->
208+
match inv#expr with
209+
| Some x -> self#inv_xpr_implies_safe inv#index x
210+
| _ ->
211+
match (inv#lower_bound_xpr, inv#upper_bound_xpr) with
212+
| (Some lb, Some ub) ->
213+
self#inv_bounded_xpr_implies_safe inv#index lb ub
214+
| _ -> None
183215

184216
method private check_safe_functionpointer (vinfo: varinfo) =
185217
let vinfovalues = poq#get_vinfo_offset_values vinfo in
@@ -231,6 +263,37 @@ object (self)
231263
false
232264
end) false vinfovalues
233265

266+
method private memlval_vinv_memref_stackvar_implies_safe
267+
(invindex: int) (vinfo: varinfo) =
268+
let mname = "memlval_vinv_memref_stackvar_implies_safe" in
269+
let vinfovalues = poq#get_vinfo_offset_values vinfo in
270+
List.fold_left (fun acc (vinv, voffset) ->
271+
match acc with
272+
| Some _ -> acc
273+
| _ ->
274+
match vinv#get_fact, voffset with
275+
| NonRelationalFact (_, FInitializedSet l), NoOffset ->
276+
(match l with
277+
| [] -> None
278+
| _ ->
279+
let deps = DLocal [invindex; vinv#index] in
280+
let msg =
281+
"local assignment(s) to "
282+
^ vinfo.vname
283+
^ ": "
284+
^ (String.concat
285+
"_xx_" (List.map self#get_symbol_name l)) in
286+
let site = Some (__FILE__, __LINE__, mname) in
287+
Some (deps, msg, site))
288+
| _ ->
289+
begin
290+
poq#set_diagnostic
291+
~site:(Some (__FILE__, __LINE__, mname))
292+
("[" ^ vinfo.vname ^ "]: " ^ (p2s vinv#toPretty));
293+
None
294+
end
295+
) None vinfovalues
296+
234297
method private memlval_vinv_memref_basevar_implies_safe
235298
(invindex: int) (v: variable_t) (memoffset: offset) =
236299
let mname = "memlval_vinv_memref_basevar_implies_safe" in
@@ -366,8 +429,13 @@ object (self)
366429
1
367430
("stack variable: "
368431
^ vinfo.vname
432+
^ " with offset "
369433
^ (p2s (offset_to_pretty voffset))) in
370-
None
434+
(match (voffset, memoffset) with
435+
| (NoOffset, NoOffset) ->
436+
self#memlval_vinv_memref_stackvar_implies_safe invindex vinfo
437+
| _ -> None)
438+
371439
| CBaseVar v ->
372440
(try
373441
self#memlval_vinv_memref_basevar_implies_safe invindex v memoffset
@@ -458,7 +526,7 @@ object (self)
458526
let _ =
459527
poq#set_diagnostic
460528
~site:(Some (__FILE__, __LINE__, mname))
461-
("[offset]: " ^ (p2s (offset_to_pretty memoffset))) in
529+
("[mem-offset]: " ^ (p2s (offset_to_pretty memoffset))) in
462530
List.fold_left (fun acc (inv, offset) ->
463531
acc ||
464532
match offset with
@@ -566,7 +634,7 @@ object (self)
566634
(* ----------------------- delegation ------------------------------------- *)
567635
(* check_delegation
568636
- check_delegation_lval
569-
- memlval_implies_delegation
637+
- check_delegation_memlval
570638
- memlval_vinv_implies_delegation
571639
- memlval_var_implies_delegation
572640
@@ -587,11 +655,11 @@ object (self)
587655
| Lval apilval ->
588656
let pred = PInitialized apilval in
589657
let deps = DEnvC ([invindex], [ApiAssumption pred]) in
590-
let site = Some (__FILE__, __LINE__, mname) in
591658
let msg =
592659
"condition "
593660
^ (p2s (po_predicate_to_pretty pred))
594661
^ " delegated to the api" in
662+
let site = Some (__FILE__, __LINE__, mname) in
595663
Some (deps, msg, site)
596664
| _ -> None
597665
else
@@ -677,11 +745,11 @@ object (self)
677745
let memlval = (Mem (Lval lval),memoffset) in
678746
let pred = PInitialized memlval in
679747
let deps = DEnvC ([inv#index], [ApiAssumption pred]) in
680-
let site = Some (__FILE__, __LINE__, mname) in
681748
let msg =
682749
"condition "
683750
^ (p2s (po_predicate_to_pretty pred))
684751
^ " delegated to the api (vinv)" in
752+
let site = Some (__FILE__, __LINE__, mname) in
685753
Some (deps, msg, site)
686754
else
687755
self#memlval_var_implies_delegation inv#index lval memoffset
@@ -694,7 +762,7 @@ object (self)
694762
end
695763
| _ -> None
696764

697-
method private memlval_implies_delegation (memlval: lval) (memoffset: offset) =
765+
method private check_delegation_memlval (memlval: lval) (memoffset: offset) =
698766
match memlval with
699767
| (Var (_vname, vid), NoOffset) when vid > 0 ->
700768
let vinfo = poq#env#get_varinfo vid in
@@ -719,7 +787,7 @@ object (self)
719787
method private check_delegation_lval =
720788
match lval with
721789
| (Mem (Lval memlval), memoffset) ->
722-
self#memlval_implies_delegation memlval memoffset
790+
self#check_delegation_memlval memlval memoffset
723791
| (Mem
724792
(BinOp
725793
(_,
@@ -746,7 +814,12 @@ end
746814

747815

748816
let check_initialized (poq:po_query_int) (lval:lval) =
749-
let invs = poq#get_invariants 1 in
817+
let f_priority (inv: invariant_int) =
818+
match inv#get_fact with
819+
| NonRelationalFact (_, FInitializedSet _) -> true
820+
| _ -> false in
821+
let invs =
822+
CCHInvariantFact.prioritize_invariants f_priority (poq#get_invariants 1) in
750823
let _ = poq#set_diagnostic_invariants 1 in
751824
let checker = new initialized_checker_t poq lval invs in
752825
checker#check_safe || checker#check_violation || checker#check_delegation

CodeHawk/CHC/cchanalyze/cCHPOCheckLocallyInitialized.ml

Lines changed: 56 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -69,11 +69,21 @@ object (self)
6969
| [] -> ""
7070
| l -> "(" ^ (String.concat "" l) ^ ")")
7171

72+
(* --------------------------- safe --------------------------------------- *)
73+
(* check_safe
74+
- check_safe_invs
75+
- inv_implies_safe
76+
- xpr_implies_safe
77+
*)
78+
7279
method private xpr_implies_safe (invindex: int) (x: xpr_t) =
80+
let mname = "xpr_implies_safe" in
7381
if poq#is_api_expression x then
7482
let _ =
7583
poq#set_diagnostic_arg
76-
2 ("api expression: " ^ (e2s (poq#get_api_expression x))) in
84+
~site:(Some (__FILE__, __LINE__, mname))
85+
2
86+
("api expression: " ^ (e2s (poq#get_api_expression x))) in
7787
match poq#get_api_expression x with
7888
| Lval (Mem (Lval (Var vpar, NoOffset)), NoOffset)
7989
when not ((fst vpar) = vinfo.vname) ->
@@ -84,12 +94,14 @@ object (self)
8494
^ vinfo.vname
8595
^ ", but from a different parameter: "
8696
^ (fst vpar)) in
87-
Some (deps, msg)
97+
let site = Some (__FILE__, __LINE__, mname) in
98+
Some (deps, msg, site)
8899
| _ -> None
89100
else
90101
None
91102

92103
method private inv_implies_safe (inv: invariant_int) =
104+
let mname = "inv_implies_safe" in
93105
match inv#expr with
94106
| Some x -> self#xpr_implies_safe inv#index x
95107
| _ ->
@@ -105,28 +117,43 @@ object (self)
105117
"local assignment(s): "
106118
^ (String.concat
107119
"_xx_" (List.map self#get_symbol_name localAssigns)) in
108-
Some (deps, msg))
120+
let site = Some (__FILE__, __LINE__, mname) in
121+
Some (deps, msg, site))
109122
| _ -> None
110123

111-
method private check_invs_safe =
124+
method private check_safe_invs =
112125
match invs with
113126
| [] -> false
114127
| _ ->
115128
List.fold_left (fun acc inv ->
116129
acc ||
117130
match self#inv_implies_safe inv with
118-
| Some (deps, msg) ->
131+
| Some (deps, msg, site) ->
119132
begin
120-
poq#record_safe_result deps msg;
133+
poq#record_safe_result ~site deps msg;
121134
true
122135
end
123136
| _ -> false) false invs
124137

138+
(* --------------------------- violation ---------------------------------- *)
139+
(* check_violation
140+
- check_violation_invs
141+
- inv_implies_violation
142+
- xpr_implies_violation
143+
144+
- check_violation_lval
145+
- check_violation_memlval
146+
- memlval_vinv_implies_violation
147+
*)
148+
125149
method private xpr_implies_violation (invindex: int) (x: xpr_t) =
150+
let mname = "xpr_implies_violation" in
126151
if poq#is_api_expression x then
127152
let _ =
128153
poq#set_diagnostic_arg
129-
2 ("api expression: " ^ (e2s (poq#get_api_expression x))) in
154+
~site:(Some (__FILE__, __LINE__, mname))
155+
2
156+
("api expression: " ^ (e2s (poq#get_api_expression x))) in
130157
match poq#get_api_expression x with
131158
| Lval (Mem (Lval (Var vpar, NoOffset)), NoOffset)
132159
when (fst vpar) = vinfo.vname ->
@@ -135,8 +162,8 @@ object (self)
135162
("value of " ^ (p2s (lval_to_pretty lval))
136163
^ " is obtained from dereferencing parameter "
137164
^ (fst vpar)) in
138-
Some (deps, msg)
139-
165+
let site = Some (__FILE__, __LINE__, mname) in
166+
Some (deps, msg, site)
140167
| _ -> None
141168
else
142169
None
@@ -146,8 +173,9 @@ object (self)
146173
| Some x -> self#xpr_implies_violation inv#index x
147174
| _ -> None
148175

149-
method private vinv_implies_deref_offset_violation
176+
method private memlval_vinv_implies_violation
150177
(inv: invariant_int) (memoffset: offset) =
178+
let mname = "memlval_vinv_implies_violation" in
151179
match inv#expr with
152180
| Some x when poq#is_api_expression x ->
153181
begin
@@ -161,15 +189,16 @@ object (self)
161189
^ (p2s (lval_to_pretty memlval))
162190
^ " with offset "
163191
^ (p2s (offset_to_pretty memoffset)) in
164-
Some (deps, msg)
192+
let site = Some (__FILE__, __LINE__, mname) in
193+
Some (deps, msg, site)
165194
else
166195
None
167196
| _ ->
168197
None
169198
end
170199
| _ -> None
171200

172-
method private check_lval_deref_violation (memlval: lval) (memoffset: offset) =
201+
method private check_violation_memlval (memlval: lval) (memoffset: offset) =
173202
match memlval with
174203
| (Var (vname, vid), NoOffset) when vid > 0 && vinfo.vname = vname ->
175204
let vinfovalues = poq#get_vinfo_offset_values vinfo in
@@ -178,50 +207,54 @@ object (self)
178207
|| match offset with
179208
| NoOffset ->
180209
begin
181-
match self#vinv_implies_deref_offset_violation
210+
match self#memlval_vinv_implies_violation
182211
inv memoffset with
183-
| Some (deps, msg) ->
212+
| Some (deps, msg, site) ->
184213
begin
185-
poq#record_violation_result deps msg;
214+
poq#record_violation_result ~site deps msg;
186215
true
187216
end
188217
| _ -> false
189218
end
190219
| _ -> false) false vinfovalues
191220
| _ -> false
192221

193-
method private check_lval_violation =
222+
method private check_violation_lval =
194223
match lval with
195224
| (Mem (Lval memlval), memoffset) ->
196-
self#check_lval_deref_violation memlval memoffset
225+
self#check_violation_memlval memlval memoffset
197226
| _ -> false
198227

199-
method private check_invs_violation =
228+
method private check_violation_invs =
200229
match invs with
201230
| [] -> false
202231
| _ ->
203232
List.fold_left (fun acc inv ->
204233
acc ||
205234
match self#inv_implies_violation inv with
206-
| Some (deps, msg) ->
235+
| Some (deps, msg, site) ->
207236
begin
208-
poq#record_violation_result deps msg;
237+
poq#record_violation_result ~site deps msg;
209238
true
210239
end
211240
| _ -> false) false invs
212241

213242
method check_safe =
214-
self#check_invs_safe
243+
self#check_safe_invs
215244

216245
method check_violation =
217-
self#check_invs_violation || self#check_lval_violation
246+
self#check_violation_invs || self#check_violation_lval
218247

219248
end
220249

221250

222251
let check_locally_initialized (poq:po_query_int) (vinfo: varinfo) (lval:lval) =
223252
let invs = poq#get_invariants 2 in
224253
let _ = poq#set_diagnostic_invariants 2 in
225-
let _ = poq#set_init_vinfo_mem_diagnostic_invariants vinfo (snd lval) in
254+
let _ =
255+
poq#set_init_vinfo_mem_diagnostic_invariants
256+
~site:(Some (__FILE__, __LINE__, "check_locally_initialized"))
257+
vinfo
258+
(snd lval) in
226259
let checker = new locally_initialized_checker_t poq vinfo lval invs in
227260
checker#check_safe || checker#check_violation

CodeHawk/CHC/cchanalyze/cCHPOQuery.ml

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -398,7 +398,8 @@ object (self)
398398

399399
method set_init_vinfo_mem_diagnostic_invariants
400400
?(site: (string * int * string) option = None)
401-
(vinfo: varinfo) (offset: offset) =
401+
(vinfo: varinfo)
402+
(offset: offset) =
402403
let numv = self#env#mk_program_var vinfo NoOffset NUM_VAR_TYPE in
403404
let ctxtinvs = (invio#get_location_invariant cfgcontext)#get_invariants in
404405
let invs =

CodeHawk/CHC/cchcmdline/cCHVersion.ml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -63,4 +63,4 @@ end
6363

6464
let version = new version_info_t
6565
~version:"0.3.0"
66-
~date:"2025-10-28"
66+
~date:"2025-11-12"

0 commit comments

Comments
 (0)