File tree 15 files changed +251
-3
lines changed
cbmc/phi-merge_uninitialized_values
cbmc-java/phi-merge_uninitialized_values
15 files changed +251
-3
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 @@ -174,7 +174,7 @@ ($$$$$$$$$)
174
174
binmode $fh ;
175
175
my $whole_file = <$fh >;
176
176
$whole_file =~ s /\r\n / \n / g ;
177
- my $is_match = $whole_file =~ / $result / ;
177
+ my $is_match = $whole_file =~ / $result /m ;
178
178
$r = ($included ? !$is_match : $is_match );
179
179
}
180
180
else
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 @@ -368,6 +368,8 @@ class goto_symext
368
368
exprt &code,
369
369
const irep_idt &identifier);
370
370
371
+ nondet_symbol_exprt build_symex_nondet (typet &type);
372
+
371
373
// exceptions
372
374
void symex_throw (statet &);
373
375
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 @@ -443,10 +443,22 @@ void goto_symext::phi_function(
443
443
444
444
exprt rhs;
445
445
446
+ // Don't add a conditional to the assignment when:
447
+ // 1. Either guard is false, so we can't follow that branch.
448
+ // 2. Either identifier is of generation zero, and so hasn't been
449
+ // initialized and therefor an invalid target.
446
450
if (dest_state.guard .is_false ())
447
451
rhs=goto_state_rhs;
448
452
else if (goto_state.guard .is_false ())
449
453
rhs=dest_state_rhs;
454
+ else if (goto_state.level2_current_count (l1_identifier) == 0 )
455
+ {
456
+ rhs = dest_state_rhs;
457
+ }
458
+ else if (dest_state.level2 .current_count (l1_identifier) == 0 )
459
+ {
460
+ rhs = goto_state_rhs;
461
+ }
450
462
else
451
463
{
452
464
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