File tree 14 files changed +244
-2
lines changed
cbmc/phi-merge_uninitialized_values
cbmc-java/phi-merge_uninitialized_values
14 files changed +244
-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 local ;
17
+
18
+ public int localUninitialized (Boolean trigger ) {
19
+ if (trigger ) {
20
+ local = new Ephemeral (42 );
21
+ } else {
22
+ local = new Aetherial (50 );
23
+ }
24
+
25
+ assert local .val == 42 ;
26
+ return local .val ;
27
+ }
28
+
29
+ private static Ephemeral staticLocal ;
30
+
31
+ public int staticLocalUninitialized (Boolean trigger ) {
32
+ if (trigger ) {
33
+ staticLocal = new Ephemeral (42 );
34
+ } else {
35
+ staticLocal = new Aetherial (76 );
36
+ }
37
+
38
+ assert staticLocal .val == 76 ;
39
+ return staticLocal .val ;
40
+ }
41
+
42
+ class Ephemeral {
43
+ Ephemeral (int value ) {
44
+ val = value ;
45
+ }
46
+
47
+ int val ;
48
+ }
49
+
50
+ class Aetherial extends Ephemeral {
51
+ Aetherial (int value ) {
52
+ super (value );
53
+ }
54
+ }
55
+ }
56
+
Original file line number Diff line number Diff line change
1
+ CORE
2
+ PhiMergeUninitialized.class
3
+ --function PhiMergeUninitialized.localUninitialized --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:
12
+
13
+ (guard ? dynamic_object2@3#1 : dynamic_object3@3#0)
14
+
15
+ First regex deals with the form : variable#0), second deals with ? variable#0 :
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:
12
+
13
+ (guard ? dynamic_object2@3#1 : dynamic_object3@3#0)
14
+
15
+ First regex deals with the form : variable#0), second deals with ? variable#0 :
Original file line number Diff line number Diff line change
1
+ CORE
2
+ PhiMergeUninitialized.class
3
+ --function PhiMergeUninitialized.staticLocalUninitialized --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:
12
+
13
+ (guard ? dynamic_object2@3#1 : dynamic_object3@3#0)
14
+
15
+ First regex deals with the form : variable#0), second deals with ? variable#0 :
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:
12
+
13
+ (guard ? dynamic_object2@3#1 : dynamic_object3@3#0)
14
+
15
+ First regex deals with the form : variable#0), second deals with ? variable#0 :
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:
12
+
13
+ (guard ? dynamic_object2@3#1 : dynamic_object3@3#0)
14
+
15
+ First regex deals with the form : variable#0), second deals with ? variable#0 :
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:
12
+
13
+ (guard ? dynamic_object2@3#1 : dynamic_object3@3#0)
14
+
15
+ First regex deals with the form : variable#0), second deals with ? variable#0 :
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:
12
+
13
+ (guard ? dynamic_object2@3#1 : dynamic_object3@3#0)
14
+
15
+ First regex deals with the form : variable#0), second deals with ? variable#0 :
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
+ obj = (int * )malloc (sizeof (int ));
8
+ if (trigger )
9
+ {
10
+ * obj = 42 ;
11
+ }
12
+ else
13
+ {
14
+ * obj = 76 ;
15
+ }
16
+
17
+ assert (* obj == 42 );
18
+ }
19
+
20
+ int global ;
21
+ void globalUninitialized (int trigger )
22
+ {
23
+ if (trigger )
24
+ {
25
+ global = 44 ;
26
+ }
27
+ else
28
+ {
29
+ global = 20 ;
30
+ }
31
+
32
+ assert (global == 44 );
33
+ }
34
+
35
+ void staticLocalUninitialized (int trigger )
36
+ {
37
+ static int staticLocal ;
38
+ if (trigger )
39
+ {
40
+ staticLocal = 43 ;
41
+ }
42
+
43
+ assert (staticLocal == 43 );
44
+ }
45
+
46
+ void localUninitialized (int trigger )
47
+ {
48
+ int local ;
49
+ if (trigger )
50
+ {
51
+ local = 24 ;
52
+ }
53
+
54
+ assert (local == 24 );
55
+ }
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 initialized and therefor
431
+ // 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