Skip to content

Commit 2557b9f

Browse files
authored
Merge pull request #1818 from goblint/issue-1722
Fix some questionable invariants in SV-COMP 2025 witnesses
2 parents 5a90691 + 4d8781a commit 2557b9f

File tree

7 files changed

+124
-6
lines changed

7 files changed

+124
-6
lines changed

src/analyses/varEq.ml

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,12 +17,16 @@ struct
1717
struct
1818
include PartitionDomain.ExpPartitions
1919

20+
let is_str_constant = function
21+
| Const (CStr _ | CWStr _) -> true
22+
| _ -> false
23+
2024
let invariant ~scope ss =
2125
fold (fun s a ->
2226
if B.mem MyCFG.unknown_exp s then
2327
a
2428
else (
25-
let s' = B.filter (fun x -> not (InvariantCil.exp_contains_tmp x) && InvariantCil.exp_is_in_scope scope x) s in
29+
let s' = B.filter (fun x -> not (InvariantCil.exp_contains_tmp x) && InvariantCil.exp_is_in_scope scope x && not (is_str_constant x)) s in
2630
if B.cardinal s' >= 2 then (
2731
(* instead of returning quadratically many pairwise equalities from a cluster,
2832
output linear number of equalities with just one expression *)

src/cdomain/value/domains/invariantCil.ml

Lines changed: 13 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -26,15 +26,23 @@ let exp_deep_unroll_types =
2626
let visitor = new exp_deep_unroll_types_visitor in
2727
visitCilExpr visitor
2828

29+
let var_may_be_shadowed scope vi =
30+
let vi_original_name = Cilfacade.find_original_name vi in
31+
let local_may_shadow local =
32+
not (CilType.Varinfo.equal vi local) && (* exclude self-equality by vid because the original names would always equal *)
33+
vi_original_name = Cilfacade.find_original_name local
34+
in
35+
List.exists local_may_shadow scope.sformals || List.exists local_may_shadow scope.slocals
2936

3037
let var_is_in_scope scope vi =
3138
match Cilfacade.find_scope_fundec vi with
32-
| None -> vi.vstorage <> Static (* CIL pulls static locals into globals, but they aren't syntactically in global scope *)
39+
| None ->
40+
vi.vstorage <> Static && (* CIL pulls static locals into globals, but they aren't syntactically in global scope *)
41+
not (var_may_be_shadowed scope vi)
3342
| Some fd ->
34-
if CilType.Fundec.equal fd scope then
35-
GobConfig.get_bool "witness.invariant.all-locals" || (not @@ hasAttribute "goblint_cil_nested" vi.vattr)
36-
else
37-
false
43+
CilType.Fundec.equal fd scope &&
44+
(GobConfig.get_bool "witness.invariant.all-locals" || (not @@ hasAttribute "goblint_cil_nested" vi.vattr)) &&
45+
not (var_may_be_shadowed scope vi) (* TODO: could distinguish non-nested and nested? *)
3846

3947
class exp_is_in_scope_visitor (scope: fundec) (acc: bool ref) = object
4048
inherit nopCilVisitor

src/util/library/libraryFunctions.ml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -647,6 +647,7 @@ let glibc_desc_list: (string * LibraryDesc.t) list = LibraryDsl.[
647647
("ferror_unlocked", unknown [drop "stream" [r_deep; w_deep]]);
648648
("fwrite_unlocked", unknown [drop "buffer" [r]; drop "size" []; drop "count" []; drop "stream" [r_deep; w_deep]]);
649649
("clearerr_unlocked", unknown [drop "stream" [w]]); (* TODO: why only w? *)
650+
("__fpending", unknown [drop "stream" [r_deep]]);
650651
("futimesat", unknown [drop "dirfd" []; drop "pathname" [r]; drop "times" [r]]);
651652
("error", unknown ((drop "status" []) :: (drop "errnum" []) :: (drop "format" [r]) :: (VarArgs (drop' [r]))));
652653
("warn", unknown (drop "format" [r] :: VarArgs (drop' [r])));
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
// CRAM PARAM: --set ana.activated[+] var_eq
2+
int main() {
3+
char text = "foobar";
4+
return 0;
5+
}
Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
$ goblint --set ana.activated[+] var_eq --enable witness.yaml.enabled --enable witness.invariant.other 72-var_eq-str-invariant.c
2+
[Info][Deadcode] Logical lines of code (LLoC) summary:
3+
live: 3
4+
dead: 0
5+
total lines: 3
6+
[Info][Witness] witness generation summary:
7+
location invariants: 0
8+
loop invariants: 0
9+
flow-insensitive invariants: 0
10+
total generation entries: 1
11+
12+
Should not contain invariant with string literal equality:
13+
14+
$ yamlWitnessStrip < witness.yml
15+
- entry_type: invariant_set
16+
content: []
Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
// CRAM PARAM: --set ana.activated[+] var_eq
2+
3+
int foo = 1;
4+
5+
int main() {
6+
int foo = 2; // shadows global
7+
8+
int bar = 3;
9+
{
10+
int bar = 4; // shadows outer block
11+
return 0;
12+
}
13+
}
Lines changed: 71 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,71 @@
1+
$ goblint --set ana.activated[+] var_eq --enable witness.yaml.enabled --enable witness.invariant.other 73-shadowing-invariant.c
2+
[Info][Deadcode] Logical lines of code (LLoC) summary:
3+
live: 5
4+
dead: 0
5+
total lines: 5
6+
[Info][Witness] witness generation summary:
7+
location invariants: 6
8+
loop invariants: 0
9+
flow-insensitive invariants: 0
10+
total generation entries: 1
11+
12+
Should not contain invariants containing shadowed variables.
13+
They can be wrong and contradicting.
14+
15+
$ yamlWitnessStrip < witness.yml
16+
- entry_type: invariant_set
17+
content:
18+
- invariant:
19+
type: location_invariant
20+
location:
21+
file_name: 73-shadowing-invariant.c
22+
line: 8
23+
column: 3
24+
function: main
25+
value: 2 == foo
26+
format: c_expression
27+
- invariant:
28+
type: location_invariant
29+
location:
30+
file_name: 73-shadowing-invariant.c
31+
line: 8
32+
column: 3
33+
function: main
34+
value: foo == 2
35+
format: c_expression
36+
- invariant:
37+
type: location_invariant
38+
location:
39+
file_name: 73-shadowing-invariant.c
40+
line: 10
41+
column: 5
42+
function: main
43+
value: 2 == foo
44+
format: c_expression
45+
- invariant:
46+
type: location_invariant
47+
location:
48+
file_name: 73-shadowing-invariant.c
49+
line: 10
50+
column: 5
51+
function: main
52+
value: foo == 2
53+
format: c_expression
54+
- invariant:
55+
type: location_invariant
56+
location:
57+
file_name: 73-shadowing-invariant.c
58+
line: 11
59+
column: 5
60+
function: main
61+
value: 2 == foo
62+
format: c_expression
63+
- invariant:
64+
type: location_invariant
65+
location:
66+
file_name: 73-shadowing-invariant.c
67+
line: 11
68+
column: 5
69+
function: main
70+
value: foo == 2
71+
format: c_expression

0 commit comments

Comments
 (0)