Skip to content

Commit 3fd60ec

Browse files
authored
Merge pull request #1236 from goblint/issue-1235
Use inlined ARG edges for unambiguous stacked ARG function return
2 parents 5f4f94b + cb32b12 commit 3fd60ec

6 files changed

Lines changed: 96 additions & 36 deletions

File tree

src/analyses/memLeak.ml

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -14,9 +14,10 @@ struct
1414
let name () = "memLeak"
1515

1616
module D = ToppedVarInfoSet
17-
module C = Lattice.Unit
17+
module C = D
18+
module P = IdentityP (D)
1819

19-
let context _ _ = ()
20+
let context _ d = d
2021

2122
(* HELPER FUNCTIONS *)
2223
let warn_for_multi_threaded ctx =

src/witness/myARG.ml

Lines changed: 16 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -141,7 +141,7 @@ struct
141141
let equal_node_context _ _ = failwith "StackNode: equal_node_context"
142142
end
143143

144-
module Stack (Cfg:CfgForward) (Arg: S):
144+
module Stack (Arg: S with module Edge = InlineEdge):
145145
S with module Node = StackNode (Arg.Node) and module Edge = Arg.Edge =
146146
struct
147147
module Node = StackNode (Arg.Node)
@@ -156,45 +156,30 @@ struct
156156
| n :: stack ->
157157
let cfgnode = Arg.Node.cfgnode n in
158158
match cfgnode with
159-
| Function _ -> (* TODO: can this be done without Cfg? *)
159+
| Function _ -> (* TODO: can this be done without cfgnode? *)
160160
begin match stack with
161161
(* | [] -> failwith "StackArg.next: return stack empty" *)
162162
| [] -> [] (* main return *)
163163
| call_n :: call_stack ->
164-
let call_cfgnode = Arg.Node.cfgnode call_n in
165164
let call_next =
166-
Cfg.next call_cfgnode
165+
Arg.next call_n
167166
(* filter because infinite loops starting with function call
168167
will have another Neg(1) edge from the head *)
169-
|> List.filter (fun (locedges, to_node) ->
170-
List.exists (function
171-
| (_, Proc _) -> true
172-
| (_, _) -> false
173-
) locedges
168+
|> List.filter_map (fun (edge, to_n) ->
169+
match edge with
170+
| InlinedEdge _ -> Some to_n
171+
| _ -> None
174172
)
175173
in
176-
begin match call_next with
177-
| [] -> failwith "StackArg.next: call next empty"
178-
| [(_, return_node)] ->
179-
begin match Arg.Node.move_opt call_n return_node with
180-
(* TODO: Is it possible to have a calling node without a returning node? *)
181-
(* | None -> [] *)
182-
| None -> failwith "StackArg.next: no return node"
183-
| Some return_n ->
184-
(* TODO: Instead of next & filter, construct unique return_n directly. Currently edge missing. *)
185-
Arg.next n
186-
|> List.filter (fun (edge, to_n) ->
187-
(* let to_cfgnode = Arg.Node.cfgnode to_n in
188-
MyCFG.Node.equal to_cfgnode return_node *)
189-
Arg.Node.equal_node_context to_n return_n
190-
)
191-
|> List.map (fun (edge, to_n) ->
192-
let to_n' = to_n :: call_stack in
193-
(edge, to_n')
194-
)
195-
end
196-
| _ :: _ :: _ -> failwith "StackArg.next: call next ambiguous"
197-
end
174+
Arg.next n
175+
|> List.filter_map (fun (edge, to_n) ->
176+
if BatList.mem_cmp Arg.Node.compare to_n call_next then (
177+
let to_n' = to_n :: call_stack in
178+
Some (edge, to_n')
179+
)
180+
else
181+
None
182+
)
198183
end
199184
| _ ->
200185
let+ (edge, to_n) = Arg.next n in

src/witness/svcomp.ml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -76,9 +76,9 @@ sig
7676
val is_sink: Arg.Node.t -> bool
7777
end
7878

79-
module StackTaskResult (Cfg:MyCFG.CfgForward) (TaskResult: TaskResult) =
79+
module StackTaskResult (TaskResult: TaskResult with module Arg.Edge = MyARG.InlineEdge) =
8080
struct
81-
module Arg = MyARG.Stack (Cfg) (TaskResult.Arg)
81+
module Arg = MyARG.Stack (TaskResult.Arg)
8282

8383
let result = TaskResult.result
8484

src/witness/witness.ml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ let write_file filename (module Task:Task) (module TaskResult:WitnessTaskResult)
1414

1515
let module TaskResult =
1616
(val if get_bool "witness.graphml.stack" then
17-
(module StackTaskResult (Task.Cfg) (TaskResult) : WitnessTaskResult)
17+
(module StackTaskResult (TaskResult) : WitnessTaskResult)
1818
else
1919
(module TaskResult)
2020
)
Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
// PARAM: --enable ana.sv-comp.enabled --enable ana.sv-comp.functions --enable witness.graphml.enabled --set ana.specification 'CHECK( init(main()), LTL(G valid-memtrack) )' --set ana.activated[+] memLeak --set ana.path_sens[+] memLeak --set ana.malloc.unique_address_count 1
2+
struct _twoIntsStruct {
3+
int intOne ;
4+
int intTwo ;
5+
};
6+
7+
typedef struct _twoIntsStruct twoIntsStruct;
8+
9+
void printStructLine(twoIntsStruct const *structTwoIntsStruct)
10+
{
11+
return;
12+
}
13+
14+
15+
int main(int argc, char **argv)
16+
{
17+
twoIntsStruct *data;
18+
int tmp_1;
19+
20+
21+
if (tmp_1 != 0) {
22+
twoIntsStruct *dataBuffer = malloc(800UL);
23+
data = dataBuffer;
24+
}
25+
else {
26+
27+
twoIntsStruct *dataBuffer_0 = malloc(800UL);
28+
data = dataBuffer_0;
29+
}
30+
31+
printStructLine((twoIntsStruct const *)data);
32+
free((void *)data);
33+
34+
return;
35+
}
Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
// PARAM: --enable ana.sv-comp.enabled --enable ana.sv-comp.functions --enable witness.graphml.enabled --set ana.specification 'CHECK( init(main()), LTL(G valid-memtrack) )' --set ana.activated[+] memLeak --set ana.path_sens[+] memLeak --set ana.malloc.unique_address_count 1
2+
struct _twoIntsStruct {
3+
int intOne ;
4+
int intTwo ;
5+
};
6+
7+
typedef struct _twoIntsStruct twoIntsStruct;
8+
9+
void printStructLine(twoIntsStruct const *structTwoIntsStruct)
10+
{
11+
return;
12+
}
13+
14+
twoIntsStruct *foo() {
15+
twoIntsStruct *data;
16+
int tmp_1;
17+
18+
if (tmp_1 != 0) {
19+
twoIntsStruct *dataBuffer = malloc(800UL);
20+
data = dataBuffer;
21+
}
22+
else {
23+
24+
twoIntsStruct *dataBuffer_0 = malloc(800UL);
25+
data = dataBuffer_0;
26+
}
27+
return data;
28+
}
29+
30+
int main(int argc, char **argv)
31+
{
32+
twoIntsStruct *data;
33+
data = foo();
34+
35+
printStructLine((twoIntsStruct const *)data);
36+
free((void *)data);
37+
38+
return;
39+
}

0 commit comments

Comments
 (0)