Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add special function for rand() to improve precision #1107

Merged
merged 4 commits into from
Jul 14, 2023
Merged
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
6 changes: 6 additions & 0 deletions src/analyses/apron/relationAnalysis.apron.ml
Original file line number Diff line number Diff line change
Expand Up @@ -507,6 +507,12 @@ struct
| Unknown, "__goblint_assume_join" ->
let id = List.hd args in
Priv.thread_join ~force:true ask ctx.global id st
| Rand, _ ->
(match r with
| Some lv ->
let st = invalidate_one ask ctx st lv in
assert_fn {ctx with local = st} (BinOp (Ge, Lval lv, zero, intType)) true
| None -> st)
| _, _ ->
let lvallist e =
let s = ask.f (Queries.MayPointTo e) in
Expand Down
7 changes: 7 additions & 0 deletions src/analyses/base.ml
Original file line number Diff line number Diff line change
Expand Up @@ -2345,6 +2345,13 @@ struct
let rv = ensure_not_zero @@ eval_rv ask ctx.global ctx.local value in
let t = Cilfacade.typeOf value in
set ~ctx ~t_override:t ask ctx.global ctx.local (AD.of_var !longjmp_return) t rv (* Not raising Deadcode here, deadcode is raised at a higher level! *)
| Rand, _ ->
begin match lv with
| Some x ->
let result:value = (Int (ID.starting IInt Z.zero)) in
set ~ctx (Analyses.ask_of_ctx ctx) gs st (eval_lv (Analyses.ask_of_ctx ctx) ctx.global st x) (Cilfacade.typeOfLval x) result
| None -> st
end
michael-schwarz marked this conversation as resolved.
Show resolved Hide resolved
| _, _ ->
let st =
special_unknown_invalidate ctx (Analyses.ask_of_ctx ctx) gs st f args
Expand Down
1 change: 1 addition & 0 deletions src/analyses/libraryDesc.ml
Original file line number Diff line number Diff line change
Expand Up @@ -72,6 +72,7 @@ type special =
| Identity of Cil.exp (** Identity function. Some compiler optimization annotation functions map to this. *)
| Setjmp of { env: Cil.exp; }
| Longjmp of { env: Cil.exp; value: Cil.exp; }
| Rand
| Unknown (** Anything not belonging to other types. *) (* TODO: rename to Other? *)


Expand Down
2 changes: 1 addition & 1 deletion src/analyses/libraryFunctions.ml
Original file line number Diff line number Diff line change
Expand Up @@ -70,6 +70,7 @@ let c_descs_list: (string * LibraryDesc.t) list = LibraryDsl.[
("_setjmp", special [__ "env" [w]] @@ fun env -> Setjmp { env }); (* only has one underscore *)
("setjmp", special [__ "env" [w]] @@ fun env -> Setjmp { env });
("longjmp", special [__ "env" [r]; __ "value" []] @@ fun env value -> Longjmp { env; value });
("rand", special [] Rand);
]

(** C POSIX library functions.
Expand Down Expand Up @@ -872,7 +873,6 @@ let invalidate_actions = [
"sendto", writes [2;4]; (*keep [2;4]*)
"recvfrom", writes [4;5]; (*keep [4;5]*)
"srand", readsAll; (*safe*)
"rand", readsAll; (*safe*)
"gethostname", writesAll; (*unsafe*)
"fork", readsAll; (*safe*)
"setrlimit", readsAll; (*safe*)
Expand Down
12 changes: 12 additions & 0 deletions tests/regression/01-cpa/74-rand.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
//PARAM: --enable ana.int.interval
#include <stdio.h>
#include <stdlib.h>
#include <goblint.h>

int main () {
int r = rand();

__goblint_check(r >= 0);

return 0;
}
11 changes: 11 additions & 0 deletions tests/regression/46-apron2/57-rand.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
// SKIP PARAM: --disable ana.int.def_exc --enable ana.int.congruence --set ana.activated[+] apron --set ana.base.privatization none --set ana.relation.privatization top
// Strange int domains, I know: The ranges of def_exc are already able to prove this assertion, meaning it is no longer about apron also knowing this.
// Disabling all int domains leads to all queries returning top though, meaning the assertion is not proven.
// Congruence offers support for constants, but does not contain any poor man's intervals. => That's why we use it here.
#include <goblint.h>
#include <stdlib.h>

int main() {
int i = rand();
__goblint_check(i >= 0);
}
Loading