Skip to content

Commit a5f34a2

Browse files
Add no-context attribute and ana.context.no_fun option for per-function context-insensitivity
Agent-Logs-Url: https://github.com/goblint/analyzer/sessions/5d5147c1-4b56-47f6-b7ef-01b3c007d358 Co-authored-by: michael-schwarz <13812333+michael-schwarz@users.noreply.github.com>
1 parent af5e662 commit a5f34a2

6 files changed

Lines changed: 71 additions & 8 deletions

File tree

docs/user-guide/annotating.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@ The following string arguments are supported:
2626
4. `base.non-ptr`/`base.no-non-ptr` to override the `ana.base.context.non-ptr` option.
2727
5. `relation.context`/`relation.no-context` to override the `ana.relation.context` option.
2828
6. `widen`/`no-widen` to override the `ana.context.widen` option.
29+
7. `no-context` to disable context-sensitivity for this function entirely (for all analyses).
2930
3031
### Apron attributes
3132
The Apron library can be set to only track variables with the attribute `goblint_apron_track`

src/analyses/mCP.ml

Lines changed: 16 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -237,13 +237,22 @@ struct
237237
and context man fd x =
238238
let man'' = outer_man "context_computation" man in
239239
let x = spec_list x in
240-
filter_map (fun (n,(module S:MCPSpec),d) ->
241-
if Set.is_empty !act_cont_sens || not (Set.mem n !act_cont_sens) then (*n is insensitive*)
242-
None
243-
else
244-
let man' : (S.D.t, S.G.t, S.C.t, S.V.t) man = inner_man "context_computation" man'' n d in
245-
Some (n, Obj.repr @@ S.context man' fd (Obj.obj d))
246-
) x
240+
(* Check if this function should be analyzed context-insensitively *)
241+
let no_ctx =
242+
ContextUtil.has_attribute "goblint_context" "no-context" fd.svar.vattr
243+
|| ContextUtil.has_option "goblint_context" "no-context" fd
244+
|| List.mem fd.svar.vname (get_string_list "ana.context.no_fun")
245+
in
246+
if no_ctx then
247+
[] (* context-insensitive: return empty context list *)
248+
else
249+
filter_map (fun (n,(module S:MCPSpec),d) ->
250+
if Set.is_empty !act_cont_sens || not (Set.mem n !act_cont_sens) then (*n is insensitive*)
251+
None
252+
else
253+
let man' : (S.D.t, S.G.t, S.C.t, S.V.t) man = inner_man "context_computation" man'' n d in
254+
Some (n, Obj.repr @@ S.context man' fd (Obj.obj d))
255+
) x
247256

248257
and branch (man:(D.t, G.t, C.t, V.t) man) (e:exp) (tv:bool) =
249258
let spawns = ref [] in

src/config/options.schema.json

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1073,6 +1073,13 @@
10731073
"description": "Length of the call string that should be used as context for the call_string and/or call_site analyses. In case the value is zero, the analysis is context-insensitive. For a negative value, an infinite call string is used! For this option to have an effect, one of the analyses in `callstring.ml` must be activated.",
10741074
"type": "integer",
10751075
"default": 2
1076+
},
1077+
"no_fun": {
1078+
"title": "ana.context.no_fun",
1079+
"description": "List of functions to be analyzed context-insensitively (regardless of other context options).",
1080+
"type": "array",
1081+
"items": { "type": "string" },
1082+
"default": []
10761083
}
10771084
},
10781085
"additionalProperties": false
@@ -1821,7 +1828,7 @@
18211828
"type": "array",
18221829
"items": {
18231830
"type": "string",
1824-
"enum": ["base.no-non-ptr", "base.non-ptr", "base.no-int", "base.int", "base.no-interval", "base.no-interval_set", "base.no-bitfield", "base.interval", "base.interval_set", "base.bitfield", "relation.no-context", "relation.context", "no-widen", "widen"]
1831+
"enum": ["base.no-non-ptr", "base.non-ptr", "base.no-int", "base.int", "base.no-interval", "base.no-interval_set", "base.no-bitfield", "base.interval", "base.interval_set", "base.bitfield", "relation.no-context", "relation.context", "no-widen", "widen", "no-context"]
18251832
},
18261833
"default": []
18271834
}
Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
// PARAM: --enable ana.int.interval --disable ana.context.widen
2+
#include <goblint.h>
3+
4+
int f(int x) __attribute__((goblint_context("no-context"))); // attributes are not permitted in a function definition
5+
int f(int x) {
6+
if (x)
7+
return f(x+1);
8+
else
9+
return x;
10+
}
11+
12+
int main () {
13+
int a = f(1);
14+
__goblint_check(!a); // UNKNOWN (intended: context-insensitive due to no-context attribute)
15+
return 0;
16+
}
Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
// PARAM: --enable ana.int.interval --disable ana.context.widen --set ana.context.no_fun[+] f
2+
#include <goblint.h>
3+
4+
int f(int x) {
5+
if (x)
6+
return f(x+1);
7+
else
8+
return x;
9+
}
10+
11+
int main () {
12+
int a = f(1);
13+
__goblint_check(!a); // UNKNOWN (intended: context-insensitive due to ana.context.no_fun option)
14+
return 0;
15+
}
Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
// PARAM: --enable ana.int.interval --disable ana.context.widen --set annotation.goblint_context.f[+] no-context
2+
#include <goblint.h>
3+
4+
int f(int x) {
5+
if (x)
6+
return f(x+1);
7+
else
8+
return x;
9+
}
10+
11+
int main () {
12+
int a = f(1);
13+
__goblint_check(!a); // UNKNOWN (intended: context-insensitive due to annotation option)
14+
return 0;
15+
}

0 commit comments

Comments
 (0)