Skip to content

Commit 36494d8

Browse files
committed
CHC:POCHECK: add proof obligation discharge rules
1 parent a5a596f commit 36494d8

File tree

7 files changed

+145
-50
lines changed

7 files changed

+145
-50
lines changed

CodeHawk/CHC/cchanalyze/cCHFunctionTranslator.ml

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -60,6 +60,10 @@ open CCHExpTranslator
6060
module EU = CCHEngineUtil
6161
module H = Hashtbl
6262

63+
64+
let p2s = CHPrettyUtil.pretty_to_string
65+
66+
6367
let fenv = CCHFileEnvironment.file_environment
6468

6569

@@ -94,8 +98,16 @@ object (self)
9498
let ttyp = fenv#get_type_unrolled vinfo.vtype in
9599
match ttyp with
96100
| TPtr ((TInt _ | TFloat _), _) ->
97-
let (v,vInit,vm,vmInit) =
101+
let (v, vInit, vm, vmInit) =
98102
env#mk_par_deref_init vinfo NoOffset ttyp NUM_VAR_TYPE in
103+
let _ =
104+
log_diagnostics_result
105+
~msg:env#get_functionname
106+
__FILE__ __LINE__
107+
["v: " ^ (p2s v#toPretty);
108+
"vInit: " ^ (p2s vInit#toPretty);
109+
"vm: " ^ (p2s vm#toPretty);
110+
"vmInit: " ^ (p2s vmInit#toPretty)] in
99111
(ASSIGN_NUM (v, NUM_VAR vInit))
100112
:: (ASSIGN_NUM (vm, NUM_VAR vmInit))
101113
:: acc

CodeHawk/CHC/cchanalyze/cCHPOCheckLocallyInitialized.ml

Lines changed: 44 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -78,8 +78,34 @@ object (self)
7878
- check_safe_lval
7979
- check_safe_memlval
8080
- memlval_implies_safe
81+
- memlval_memref_implies_safe
82+
-memlval_memref_basevar_implies_safe
8183
*)
8284

85+
method private memlval_memref_basevar_implies_safe
86+
(invindex: int) (basevar: variable_t) =
87+
let mname = "memlval_memref_basevar_implies_safe" in
88+
if poq#env#is_function_return_value basevar then
89+
let callee = poq#env#get_callvar_callee basevar in
90+
let apilval = Lval (Var (self#vinfo.vname, self#vinfo.vid), NoOffset) in
91+
let pred = PUniquePointer apilval in
92+
let deps = DEnvC ([invindex], [ApiAssumption pred]) in
93+
let msg =
94+
"assumption on the environment that the memory region "
95+
^ " pointed at by the return value from "
96+
^ callee.vname
97+
^ " does not overlap with the memory region pointed at by "
98+
^ self#vinfo.vname in
99+
let site = Some (__FILE__, __LINE__, mname) in
100+
Some (deps, msg, site)
101+
else
102+
begin
103+
poq#set_diagnostic
104+
~site:(Some (__FILE__, __LINE__, mname))
105+
("[memlval:basevar]: " ^ (p2s basevar#toPretty));
106+
None
107+
end
108+
83109
method private memlval_memref_implies_safe
84110
(invindex: int)
85111
(memlval: lval)
@@ -98,6 +124,8 @@ object (self)
98124
^ vinfo.vname in
99125
let site = Some (__FILE__, __LINE__, mname) in
100126
Some (deps, msg, site)
127+
| CBaseVar bvar ->
128+
self#memlval_memref_basevar_implies_safe invindex bvar
101129
| _ ->
102130
begin
103131
poq#set_diagnostic
@@ -339,23 +367,24 @@ object (self)
339367

340368
method private check_violation_memlval (memlval: lval) (memoffset: offset) =
341369
match memlval with
342-
| (Var (vname, vid), NoOffset) when vid > 0 && vinfo.vname = vname ->
343-
let vinfovalues = poq#get_vinfo_offset_values vinfo in
370+
| (Var (_, vid), _) when vid > 0 ->
371+
let lvinfo = poq#env#get_varinfo vid in
372+
let vinfovalues = poq#get_vinfo_offset_values lvinfo in
344373
List.fold_left (fun acc (inv, offset) ->
345374
acc
346-
|| match offset with
347-
| NoOffset ->
348-
begin
349-
match self#memlval_vinv_implies_violation
350-
inv memoffset with
351-
| Some (deps, msg, site) ->
352-
begin
353-
poq#record_violation_result ~site deps msg;
354-
true
355-
end
356-
| _ -> false
357-
end
358-
| _ -> false) false vinfovalues
375+
|| (match offset with
376+
| NoOffset ->
377+
begin
378+
match self#memlval_vinv_implies_violation
379+
inv memoffset with
380+
| Some (deps, msg, site) ->
381+
begin
382+
poq#record_violation_result ~site deps msg;
383+
true
384+
end
385+
| _ -> false
386+
end
387+
| _ -> false)) false vinfovalues
359388
| _ -> false
360389

361390
method private check_violation_lval =

CodeHawk/CHC/cchanalyze/cCHPOCheckOutputParameterInitialized.ml

Lines changed: 10 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -53,12 +53,14 @@ let _fenv = CCHFileEnvironment.file_environment
5353
class outputparameter_initialized_checker_t
5454
(poq: po_query_int)
5555
(vinfo: varinfo)
56-
(_offset: offset)
56+
(offset: offset)
5757
(invs: invariant_int list) =
5858
object (self)
5959

6060
method private vinfo = vinfo
6161

62+
method private offset = offset
63+
6264
method private get_symbol_name (s: symbol_t) =
6365
s#getBaseName
6466
^ (match s#getAttributes with
@@ -147,9 +149,13 @@ object (self)
147149
end
148150
| _ -> false) false invs
149151

152+
method check_violation =
153+
self#check_invs_violation
154+
150155
(* --------------------------------- safe --------------------------------- *)
151156
(* check_safe
152-
- inv_implies_safe
157+
- check_safe_invs
158+
- inv_implies_safe
153159
*)
154160

155161
method private inv_implies_safe (inv: invariant_int) =
@@ -177,7 +183,7 @@ object (self)
177183
None
178184
end
179185

180-
method check_safe =
186+
method private check_safe_invs =
181187
List.fold_left (fun acc inv ->
182188
acc
183189
|| (match self#inv_implies_safe inv with
@@ -188,8 +194,7 @@ object (self)
188194
end
189195
| _ -> false)) false invs
190196

191-
method check_violation =
192-
self#check_invs_violation
197+
method check_safe = self#check_safe_invs
193198

194199
end
195200

CodeHawk/CHC/cchanalyze/cCHPOCheckOutputParameterUnaltered.ml

Lines changed: 72 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -33,8 +33,10 @@ open XprTypes
3333

3434
(* cchlib *)
3535
open CCHBasicTypes
36+
open CCHTypesToPretty
3637

3738
(* cchpre *)
39+
open CCHMemoryBase
3840
open CCHPreTypes
3941

4042
(* cchanalyze *)
@@ -67,11 +69,76 @@ object (self)
6769

6870
(* ------------------------------- safe ----------------------------------- *)
6971
(* check_safe
70-
- check_invs_safe
72+
- check_safe_invs
7173
- inv_implies_safe
7274
- inv_xpr_implies_safe
75+
- check_safe_lval
76+
- check_safe_memlval
77+
- memlval_implies_safe
78+
-memlval_memref_implies_safe
7379
*)
7480

81+
method private memlval_memref_basevar_implies_safe
82+
(_invindex: int) (basevar: variable_t) =
83+
let mname = "memlval_memref_basevar_implies_safe" in
84+
begin
85+
poq#set_diagnostic
86+
~site:(Some (__FILE__, __LINE__, mname))
87+
("[memref-basevar]: " ^ (p2s basevar#toPretty));
88+
None
89+
end
90+
91+
method private memlval_memref_implies_safe
92+
(invindex: int) (memref: memory_reference_int) =
93+
let mname = "memlval_memref_implies_safe" in
94+
match memref#get_base with
95+
| CBaseVar bvar ->
96+
self#memlval_memref_basevar_implies_safe invindex bvar
97+
| _ ->
98+
begin
99+
poq#set_diagnostic
100+
~site:(Some (__FILE__, __LINE__, mname))
101+
("[memref-base]: "
102+
^ (p2s (memory_base_to_pretty memref#get_base)));
103+
None
104+
end
105+
106+
method private memlval_implies_safe (inv: invariant_int) (offset: offset) =
107+
let mname = "memlval_implies_safe" in
108+
match inv#expr with
109+
| Some (XVar v) when poq#env#is_memory_address v ->
110+
let (memref, _) = poq#env#get_memory_address v in
111+
self#memlval_memref_implies_safe inv#index memref
112+
| Some x ->
113+
begin
114+
poq#set_diagnostic
115+
~site:(Some (__FILE__, __LINE__, mname)) ("[xpr]: " ^ (x2s x));
116+
None
117+
end
118+
| _ ->
119+
begin
120+
poq#set_diagnostic
121+
~site:(Some (__FILE__, __LINE__, mname))
122+
("[inv,offset]: "
123+
^ (p2s inv#toPretty)
124+
^ ", "
125+
^ (p2s (offset_to_pretty offset)));
126+
None
127+
end
128+
129+
method private check_safe_lval =
130+
let vinfovalues = poq#get_vinfo_offset_values self#vinfo in
131+
List.fold_left (fun acc (inv, offset) ->
132+
acc
133+
|| (match self#memlval_implies_safe inv offset with
134+
| Some (deps, msg, site) ->
135+
begin
136+
poq#record_safe_result ~site deps msg;
137+
true
138+
end
139+
| _ ->
140+
false)) false vinfovalues
141+
75142
method private inv_xpr_implies_safe (invindex: int) (xpr: xpr_t) =
76143
let mname = "inv_xpr_implies_safe" in
77144
let numv = poq#env#mk_program_var vinfo NoOffset NUM_VAR_TYPE in
@@ -133,7 +200,7 @@ object (self)
133200
None
134201
end
135202

136-
method private check_invs_safe =
203+
method private check_safe_invs =
137204
match invs with
138205
| [] -> false
139206
| _ ->
@@ -147,6 +214,9 @@ object (self)
147214
end
148215
| _ -> false) false invs
149216

217+
method check_safe =
218+
self#check_safe_invs || self#check_safe_lval
219+
150220
(* --------------------------- violation ---------------------------------- *)
151221
(* check_violation
152222
- inv_implies_violation
@@ -177,9 +247,6 @@ object (self)
177247
None
178248
end
179249

180-
method check_safe =
181-
self#check_invs_safe
182-
183250
method check_violation =
184251
List.fold_left (fun acc inv ->
185252
acc

CodeHawk/CHC/cchanalyze/cCHPOQuery.ml

Lines changed: 3 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -378,6 +378,7 @@ object (self)
378378
method get_init_vinfo_mem_invariants
379379
(vinfo: varinfo) (offset: offset): invariant_int list =
380380
let numv = self#env#mk_program_var vinfo NoOffset NUM_VAR_TYPE in
381+
let ctxtinvs = (invio#get_location_invariant cfgcontext)#get_invariants in
381382
List.fold_left (fun acc inv ->
382383
match inv#get_fact with
383384
| NonRelationalFact (v, _) ->
@@ -394,32 +395,13 @@ object (self)
394395
| _ -> acc)
395396
else
396397
acc
397-
| _ -> acc) [] (invio#get_location_invariant cfgcontext)#get_invariants
398+
| _ -> acc) [] ctxtinvs
398399

399400
method set_init_vinfo_mem_diagnostic_invariants
400401
?(site: (string * int * string) option = None)
401402
(vinfo: varinfo)
402403
(offset: offset) =
403-
let numv = self#env#mk_program_var vinfo NoOffset NUM_VAR_TYPE in
404-
let ctxtinvs = (invio#get_location_invariant cfgcontext)#get_invariants in
405-
let invs =
406-
List.fold_left (fun acc inv ->
407-
match inv#get_fact with
408-
| NonRelationalFact (v, _) ->
409-
if self#env#is_memory_variable v then
410-
let (memref, memoffset) = self#env#get_memory_variable v in
411-
(match memref#get_base with
412-
| CBaseVar base when self#env#is_initial_parameter_value base ->
413-
let basevar = self#env#get_initial_value_variable base in
414-
if numv#equal basevar
415-
&& (offset_compare offset memoffset) = 0 then
416-
inv :: acc
417-
else
418-
acc
419-
| _ -> acc)
420-
else
421-
acc
422-
| _ -> acc) [] ctxtinvs in
404+
let invs = self#get_init_vinfo_mem_invariants vinfo offset in
423405
List.iter (fun inv -> po#add_diagnostic_msg ~site (p2s (inv#toPretty))) invs
424406

425407
method set_vinfo_diagnostic_invariants

CodeHawk/CHC/cchlib/cCHVersion.ml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -62,5 +62,5 @@ object (self)
6262
end
6363

6464
let version = new version_info_t
65-
~version:"0.3.0_20251114"
66-
~date:"2025-11-14"
65+
~version:"0.3.0_20251118"
66+
~date:"2025-11-19"

CodeHawk/CHC/cchpre/cCHProofObligation.ml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -660,7 +660,7 @@ let read_xml_explanation (node: xml_element_int) (po: proof_obligation_int)=
660660
if node#hasNamedAttribute "file" then
661661
Some (
662662
cd#get_string (geti "file"),
663-
geti "linenr",
663+
geti "line",
664664
cd#get_string (geti "detail"))
665665
else
666666
None in

0 commit comments

Comments
 (0)