File tree 14 files changed +250
-2
lines changed
cbmc/phi-merge_uninitialized_values
cbmc-java/phi-merge_uninitialized_values
14 files changed +250
-2
lines changed Original file line number Diff line number Diff line change
1
+ public class PhiMergeUninitialized {
2
+
3
+ public int dynamicAllocationUninitialized (Boolean trigger ) {
4
+
5
+ Ephemeral obj ;
6
+ if (trigger ) {
7
+ obj = new Ephemeral (42 );
8
+ } else {
9
+ obj = new Aetherial (20 );
10
+ }
11
+
12
+ assert obj .val == 20 ;
13
+ return obj .val ;
14
+ }
15
+
16
+ private Ephemeral field ;
17
+
18
+ public int fieldUninitialized (Boolean trigger ) {
19
+ if (trigger ) {
20
+ field = new Ephemeral (42 );
21
+ }
22
+
23
+ assert field .val == 42 ;
24
+ return field .val ;
25
+ }
26
+
27
+ private static Ephemeral staticField ;
28
+
29
+ public int staticFieldUninitialized (Boolean trigger ) {
30
+ if (trigger ) {
31
+ staticField = new Ephemeral (42 );
32
+ } else {
33
+ staticField = new Aetherial (76 );
34
+ }
35
+
36
+ assert staticField .val == 76 ;
37
+ return staticField .val ;
38
+ }
39
+
40
+ class Ephemeral {
41
+ Ephemeral (int value ) {
42
+ val = value ;
43
+ }
44
+
45
+ int val ;
46
+ }
47
+
48
+ class Aetherial extends Ephemeral {
49
+ Aetherial (int value ) {
50
+ super (value );
51
+ }
52
+ }
53
+ }
54
+
Original file line number Diff line number Diff line change
1
+ CORE
2
+ PhiMergeUninitialized.class
3
+ --function PhiMergeUninitialized.fieldUninitialized --show-vcc
4
+ activate-multi-line-match
5
+ ^EXIT=0$
6
+ ^SIGNAL=0$
7
+ --
8
+ ^.*:\s+(dynamic_object|new_tmp)[0-9]+(@[0-9]+)?#0\)
9
+ ^.*\?\s+(dynamic_object|new_tmp)[0-9]+(@[0-9]+)?#0\s+:
10
+ --
11
+ These regexes are making sure that a variable of generation 0 dosen't appear in a phi merge, so the below
12
+ statement:
13
+
14
+ (guard ? dynamic_object2@3#1 : dynamic_object3@3#0)
15
+
16
+ Should not appear. First regex deals with when the gen zero is the latter position, second when it's in the former.
Original file line number Diff line number Diff line change
1
+ CORE
2
+ PhiMergeUninitialized.class
3
+ --function PhiMergeUninitialized.dynamicAllocationUninitialized --show-vcc
4
+ activate-multi-line-match
5
+ ^EXIT=0$
6
+ ^SIGNAL=0$
7
+ --
8
+ ^.*:\s+(dynamic_object|new_tmp)[0-9]+(@[0-9]+)?#0\)
9
+ ^.*\?\s+(dynamic_object|new_tmp)[0-9]+(@[0-9]+)?#0\s+:
10
+ --
11
+ These regexes are making sure that a variable of generation 0 dosen't appear in a phi merge, so the below
12
+ statement:
13
+
14
+ (guard ? dynamic_object2@3#1 : dynamic_object3@3#0)
15
+
16
+ Should not appear. First regex deals with when the gen zero is the latter position, second when it's in the former.
Original file line number Diff line number Diff line change
1
+ CORE
2
+ PhiMergeUninitialized.class
3
+ --function PhiMergeUninitialized.staticFieldUninitialized --show-vcc
4
+ activate-multi-line-match
5
+ ^EXIT=0$
6
+ ^SIGNAL=0$
7
+ --
8
+ ^.*:\s+(dynamic_object|new_tmp)[0-9]+(@[0-9]+)?#0\)
9
+ ^.*\?\s+(dynamic_object|new_tmp)[0-9]+(@[0-9]+)?#0\s+:
10
+ --
11
+ These regexes are making sure that a variable of generation 0 dosen't appear in a phi merge, so the below
12
+ statement:
13
+
14
+ (guard ? dynamic_object2@3#1 : dynamic_object3@3#0)
15
+
16
+ Should not appear. First regex deals with when the gen zero is the latter position, second when it's in the former.
Original file line number Diff line number Diff line change
1
+ CORE
2
+ test.c
3
+ --function dynamicAllocationUninitialized --show-vcc
4
+ activate-multi-line-match
5
+ ^EXIT=0$
6
+ ^SIGNAL=0$
7
+ --
8
+ ^.*:\s+dynamic_object[0-9]+(@[0-9]+)?#0\)
9
+ ^.*\?\s+dynamic_object[0-9]+(@[0-9]+)?#0\s+:
10
+ --
11
+ These regexes are making sure that a variable of generation 0 dosen't appear in a phi merge, so the below
12
+ statement:
13
+
14
+ (guard ? dynamic_object2@3#1 : dynamic_object3@3#0)
15
+
16
+ Should not appear. First regex deals with when the gen zero is the latter position, second when it's in the former.
Original file line number Diff line number Diff line change
1
+ CORE
2
+ test.c
3
+ --function globalUninitialized --show-vcc
4
+ activate-multi-line-match
5
+ ^EXIT=0$
6
+ ^SIGNAL=0$
7
+ --
8
+ ^.*:\s+global(@[0-9]+)?#0\)
9
+ ^.*\?\s+global(@[0-9]+)?#0\s+:
10
+ --
11
+ These regexes are making sure that a variable of generation 0 dosen't appear in a phi merge, so the below
12
+ statement:
13
+
14
+ (guard ? global#1 : global#0)
15
+
16
+ Should not appear. First regex deals with when the gen zero is the latter position, second when it's in the former.
Original file line number Diff line number Diff line change
1
+ CORE
2
+ test.c
3
+ --function localUninitialized --show-vcc
4
+ activate-multi-line-match
5
+ ^EXIT=0$
6
+ ^SIGNAL=0$
7
+ --
8
+ ^.*:\s+local(@[0-9]+)?#0\)
9
+ ^.*\?\s+local(@[0-9]+)?#0\s+:
10
+ --
11
+ These regexes are making sure that a variable of generation 0 dosen't appear in a phi merge, so the below
12
+ statement:
13
+
14
+ (guard ? local#1 : local#0)
15
+
16
+ Should not appear. First regex deals with when the gen zero is the latter position, second when it's in the former.
Original file line number Diff line number Diff line change
1
+ CORE
2
+ test.c
3
+ --function staticLocalUninitialized --show-vcc
4
+ activate-multi-line-match
5
+ ^EXIT=0$
6
+ ^SIGNAL=0$
7
+ --
8
+ ^.*:\s+staticLocal(@[0-9]+)?#0\)
9
+ ^.*\?\s+staticLocal(@[0-9]+)?#0\s+:
10
+ --
11
+ These regexes are making sure that a variable of generation 0 dosen't appear in a phi merge, so the below
12
+ statement:
13
+
14
+ (guard ? staticLocal#1 : dynamic_object#0)
15
+
16
+ Should not appear. First regex deals with when the gen zero is the latter position, second when it's in the former.
Original file line number Diff line number Diff line change
1
+ #include <assert.h>
2
+ #include <stdlib.h>
3
+
4
+ void dynamicAllocationUninitialized (int trigger )
5
+ {
6
+ int * obj ;
7
+ if (trigger )
8
+ {
9
+ obj = (int * )malloc (sizeof (int ));
10
+ * obj = 42 ;
11
+ }
12
+ else
13
+ {
14
+ obj = (int * )malloc (sizeof (int ));
15
+ * obj = 76 ;
16
+ }
17
+
18
+ assert (* obj == 42 );
19
+ }
20
+
21
+ int global ;
22
+ void globalUninitialized (int trigger )
23
+ {
24
+ if (trigger )
25
+ {
26
+ global = 44 ;
27
+ }
28
+ else
29
+ {
30
+ global = 20 ;
31
+ }
32
+
33
+ assert (global == 44 );
34
+ }
35
+
36
+ void staticLocalUninitialized (int trigger )
37
+ {
38
+ static int staticLocal ;
39
+ if (trigger )
40
+ {
41
+ staticLocal = 43 ;
42
+ }
43
+
44
+ assert (staticLocal == 43 );
45
+ }
46
+
47
+ void localUninitialized (int trigger )
48
+ {
49
+ int local ;
50
+ if (trigger )
51
+ {
52
+ local = 24 ;
53
+ }
54
+
55
+ assert (local == 24 );
56
+ }
Original file line number Diff line number Diff line change @@ -22,13 +22,19 @@ void goto_symext::do_simplify(exprt &expr)
22
22
simplify (expr, ns);
23
23
}
24
24
25
+ nondet_symbol_exprt goto_symext::build_symex_nondet (typet &type)
26
+ {
27
+ irep_idt identifier = " symex::nondet" + std::to_string (nondet_count++);
28
+ nondet_symbol_exprt new_expr (identifier, type);
29
+ return new_expr;
30
+ }
31
+
25
32
void goto_symext::replace_nondet (exprt &expr)
26
33
{
27
34
if (expr.id ()==ID_side_effect &&
28
35
expr.get (ID_statement)==ID_nondet)
29
36
{
30
- irep_idt identifier=" symex::nondet" +std::to_string (nondet_count++);
31
- nondet_symbol_exprt new_expr (identifier, expr.type ());
37
+ nondet_symbol_exprt new_expr = build_symex_nondet (expr.type ());
32
38
new_expr.add_source_location ()=expr.source_location ();
33
39
expr.swap (new_expr);
34
40
}
Original file line number Diff line number Diff line change @@ -376,6 +376,8 @@ class goto_symext
376
376
exprt &code,
377
377
const irep_idt &identifier);
378
378
379
+ nondet_symbol_exprt build_symex_nondet (typet &type);
380
+
379
381
// exceptions
380
382
void symex_throw (statet &);
381
383
void symex_catch (statet &);
Original file line number Diff line number Diff line change @@ -184,6 +184,12 @@ void goto_symext::symex_allocate(
184
184
else
185
185
throw " failed to zero initialize dynamic object" ;
186
186
}
187
+ else
188
+ {
189
+ exprt nondet = build_symex_nondet (object_type);
190
+ code_assignt assignment (value_symbol.symbol_expr (), nondet);
191
+ symex_assign (state, assignment);
192
+ }
187
193
188
194
exprt rhs;
189
195
Original file line number Diff line number Diff line change @@ -425,10 +425,22 @@ void goto_symext::phi_function(
425
425
426
426
exprt rhs;
427
427
428
+ // Don't add a conditional to the assignment when:
429
+ // 1. Either guard is false, so we can't follow that branch.
430
+ // 2. Either identifier is of generation zero, and so hasn't been
431
+ // initialized and therefor an invalid target.
428
432
if (dest_state.guard .is_false ())
429
433
rhs=goto_state_rhs;
430
434
else if (goto_state.guard .is_false ())
431
435
rhs=dest_state_rhs;
436
+ else if (goto_state.level2_current_count (l1_identifier) == 0 )
437
+ {
438
+ rhs = dest_state_rhs;
439
+ }
440
+ else if (dest_state.level2 .current_count (l1_identifier) == 0 )
441
+ {
442
+ rhs = goto_state_rhs;
443
+ }
432
444
else
433
445
{
434
446
rhs=if_exprt (diff_guard.as_expr (), goto_state_rhs, dest_state_rhs);
You can’t perform that action at this time.
0 commit comments