You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Copy file name to clipboardExpand all lines: docs/user-guide/annotating.md
+8Lines changed: 8 additions & 0 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -25,3 +25,11 @@ The following string arguments are supported:
25
25
3. `base.non-ptr`/`base.no-non-ptr` to override the `ana.base.context.non-ptr` option.
26
26
4. `apron.context`/`apron.no-context` to override the `ana.apron.context` option.
27
27
5. `widen`/`no-widen` to override the `ana.context.widen` option.
28
+
29
+
30
+
## Functions
31
+
Goblint-specific functions can be called in the code, where they assist the analyzer but have no runtime effect.
32
+
33
+
* `__goblint_assume_join(id)` is like `pthread_join(id)`, but considers the given thread IDs must-joined even if Goblint cannot, e.g. due to non-uniqueness.
34
+
Notably, this annotation can be used after a threads joining loop to make the assumption that the loop correctly joined all those threads.
35
+
_Misuse of this annotation can cause unsoundness._
M.info ~category:Unsound"Unknown thread ID assume-joined, Apron privatization unsound"; (* TODO: something more sound *)
992
+
st (* cannot find all thread IDs to join them all *)
993
+
)
994
+
else (
995
+
(* fold throws if the thread set is top *)
996
+
let tids' =ConcDomain.ThreadSet.diff tids (ask.f Q.MustJoinedThreads) in(* avoid unnecessary imprecision by force joining already must-joined threads, e.g. 46-apron2/04-other-assume-inprec *)
997
+
let (lmust', l') =ConcDomain.ThreadSet.fold (funtid (lmust, l) ->
998
+
let lmust',l' =G.thread (getg (V.thread tid)) in
999
+
(LMust.union lmust' lmust, L.join l l')
1000
+
) tids' (lmust, l)
1001
+
in
1002
+
{st with priv = (w, lmust', l')}
1003
+
)
1004
+
)
991
1005
else (
992
-
(* elements throws if the thread set is top *)
993
-
let tids =ConcDomain.ThreadSet.elements tids in
994
-
match tids with
995
-
| [tid] ->
996
-
let lmust',l' =G.thread (getg (V.thread tid)) in
997
-
{st with priv = (w, LMust.union lmust' lmust, L.join l l')}
998
-
|_ ->
999
-
(* To match the paper more closely, one would have to join in the non-definite case too *)
1000
-
(* Given how we handle lmust (for initialization), doing this might actually be beneficial given that it grows lmust *)
1001
-
st
1006
+
ifConcDomain.ThreadSet.is_top tids then
1007
+
st (* TODO: why needed? *)
1008
+
else (
1009
+
(* elements throws if the thread set is top *)
1010
+
let tids =ConcDomain.ThreadSet.elements tids in
1011
+
match tids with
1012
+
| [tid] ->
1013
+
let lmust',l' =G.thread (getg (V.thread tid)) in
1014
+
{st with priv = (w, LMust.union lmust' lmust, L.join l l')}
1015
+
|_ ->
1016
+
(* To match the paper more closely, one would have to join in the non-definite case too *)
1017
+
(* Given how we handle lmust (for initialization), doing this might actually be beneficial given that it grows lmust *)
0 commit comments