Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
33 changes: 26 additions & 7 deletions src/arg/myARG.ml
Original file line number Diff line number Diff line change
Expand Up @@ -156,7 +156,7 @@ struct
| n :: stack ->
let cfgnode = Arg.Node.cfgnode n in
match cfgnode with
| Function _ -> (* TODO: can this be done without cfgnode? *)
| Function cfgnode_fd -> (* TODO: can this be done without cfgnode? *)
begin match stack with
(* | [] -> failwith "StackArg.next: return stack empty" *)
| [] -> [] (* main return *)
Expand All @@ -171,14 +171,33 @@ struct
| _ -> None
)
in
let (entry_lval, entry_args) =
Arg.next call_n
(* filter because infinite loops starting with function call
will have another Neg(1) edge from the head *)
|> List.filter_map (fun (edge, to_n) ->
match edge with
| InlineEntry (lval, _, args) -> Some (lval, args)
| _ -> None
)
|> List.sort_uniq [%ord: CilType.Lval.t option * CilType.Exp.t list] (* TODO: deduplicate unique element in O(n) *)
|> (function
| [lval_args] -> lval_args
| _ -> assert false (* all calls from a node must have same args and lval, even if called function might be different via function pointer *)
)
in
Arg.next n
|> List.filter_map (fun (edge, to_n) ->
if BatList.mem_cmp Arg.Node.compare to_n call_next then (
let to_n' = to_n :: call_stack in
Some (edge, to_n')
)
else
None
match edge with
| InlineReturn (lval, fd, args) ->
assert (CilType.Fundec.equal fd cfgnode_fd); (* fd in return node should be the same as in InlineReturn edge *)
if BatList.mem_cmp Arg.Node.compare to_n call_next && [%eq: CilType.Lval.t option] lval entry_lval && [%eq: CilType.Exp.t list] args entry_args then (
let to_n' = to_n :: call_stack in
Some (edge, to_n')
)
else
None
| _ -> assert false
)
end
| _ ->
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,5 @@ int main()
__VERIFIER_assert(x != 1);
}
}
// TODO: double InlineReturn edge in two first cases?
return 0;
}

Large diffs are not rendered by default.

Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,5 @@ int main()
__VERIFIER_assert(x != 0 && x != 2);
}
}
// TODO: double InlineReturn edge in two first cases?
return 0;
}

Large diffs are not rendered by default.

105 changes: 105 additions & 0 deletions tests/sv-comp/cfg/nondetcall_same_true-unreach-call.expected
Original file line number Diff line number Diff line change
@@ -0,0 +1,105 @@
┌────────────────────────────────────────┐
│ _ │
└────────────────────────────────────────┘
│ Entry main
┌────────────────────────────────────────┐
│ _ │ ·┐
└────────────────────────────────────────┘ :
│ :
│ InlineEntry '()' :
▼ :
┌────────────────────────────────────────┐ :
│ _ │ :
└────────────────────────────────────────┘ :
│ :
│ Entry __VERIFIER_nondet_int :
▼ :
┌────────────────────────────────────────┐ :
│ _ │ : Inlined Proc 'tmp = __VERIFIER_nondet_int()'
└────────────────────────────────────────┘ :
│ :
│ Ret (Some val, __VERIFIER_nondet_int) :
▼ :
┌────────────────────────────────────────┐ :
│ _ │ :
└────────────────────────────────────────┘ :
│ :
│ InlineReturn 'tmp' :
▼ :
┌───┐ Test (tmp,false) ┌────────────────────────────────────────┐ :
│ _ │ ◀───────────────────────────────────────────── │ _ │ ◀┘
└───┘ └────────────────────────────────────────┘
│ │
│ │ Test (tmp,true)
│ ▼
│ ┌────────────────────────────────────────┐
│ │ _ │
│ └────────────────────────────────────────┘
│ │
│ │ Assign 'fun = & foo'
│ ▼
│ Assign 'fun = & foo' ┌────────────────────────────────────────┐
└────────────────────────────────────────────────▶ │ _ │ ·┐
└────────────────────────────────────────┘ :
│ :
│ InlineEntry '(1)' :
▼ :
┌────────────────────────────────────────┐ :
│ _ │ :
└────────────────────────────────────────┘ :
│ :
│ Entry foo :
▼ :
┌────────────────────────────────────────┐ :
┌············································ │ _ │ :
: └────────────────────────────────────────┘ :
: │ :
: │ InlineEntry '(x - 1 < x)' :
: ▼ :
: ┌────────────────────────────────────────┐ :
: │ _ │ :
: └────────────────────────────────────────┘ :
: │ :
: │ Entry __VERIFIER_assert :
: ▼ :
: ┌────────────────────────────────────────┐ :
: │ _ │ :
: └────────────────────────────────────────┘ :
: │ :
: Inlined Proc '__VERIFIER_assert(x - 1 < x)' │ Test (! cond,false) : Inlined Proc '*fun(1)'
: ▼ :
: ┌────────────────────────────────────────┐ :
: │ _ │ :
: └────────────────────────────────────────┘ :
: │ :
: │ Ret (None, __VERIFIER_assert) :
: ▼ :
: ┌────────────────────────────────────────┐ :
: │ _ │ :
: └────────────────────────────────────────┘ :
: │ :
: │ InlineReturn :
: ▼ :
: ┌────────────────────────────────────────┐ :
└···········································▶ │ _ │ :
└────────────────────────────────────────┘ :
│ :
│ Ret (None, foo) :
▼ :
┌────────────────────────────────────────┐ :
│ _ │ :
└────────────────────────────────────────┘ :
│ :
│ InlineReturn :
▼ :
┌────────────────────────────────────────┐ :
│ _ │ ◀┘
└────────────────────────────────────────┘
│ Ret (Some 0, main)
┌────────────────────────────────────────┐
│ _ │
└────────────────────────────────────────┘
Loading
Loading