File tree Expand file tree Collapse file tree 5 files changed +67
-6
lines changed Expand file tree Collapse file tree 5 files changed +67
-6
lines changed Original file line number Diff line number Diff line change
1
+ int main ()
2
+ {
3
+ // create a union type of non-constant, non-zero size
4
+ unsigned x ;
5
+ __CPROVER_assume (x > 0 );
6
+ union U
7
+ {
8
+ unsigned A [x ];
9
+ };
10
+ // create an integer of arbitrary value
11
+ int i , i_before ;
12
+ i_before = i ;
13
+ // initialize a union of non-zero size from the integer
14
+ union U u = * ((union U * )& i );
15
+ // reading back an integer out of the union should yield the same value for
16
+ // the integer as it had before
17
+ i = u .A [0 ];
18
+ __CPROVER_assert (i == i_before , "going through union works" );
19
+ }
Original file line number Diff line number Diff line change
1
+ CORE
2
+ main.c
3
+
4
+ ^EXIT=0$
5
+ ^SIGNAL=0$
6
+ ^VERIFICATION SUCCESSFUL$
7
+ --
8
+ ^warning: ignoring
9
+ --
10
+ Value sets did not properly track pointers through unions. Thus derferencing
11
+ yields __CPROVER_memory, which results in a spurious verification failure.
Original file line number Diff line number Diff line change @@ -517,7 +517,31 @@ void boolbvt::set_to(const exprt &expr, bool value)
517
517
518
518
bool boolbvt::is_unbounded_array (const typet &type) const
519
519
{
520
- if (type.id ()!=ID_array)
520
+ if (type.id () == ID_struct_tag)
521
+ return is_unbounded_array (ns.follow_tag (to_struct_tag_type (type)));
522
+ else if (type.id () == ID_union_tag)
523
+ return is_unbounded_array (ns.follow_tag (to_union_tag_type (type)));
524
+ else if (type.id () == ID_struct)
525
+ {
526
+ for (const auto &component : to_struct_type (type).components ())
527
+ {
528
+ if (is_unbounded_array (component.type ()))
529
+ return true ;
530
+ }
531
+
532
+ return false ;
533
+ }
534
+ else if (type.id () == ID_union)
535
+ {
536
+ for (const auto &component : to_union_type (type).components ())
537
+ {
538
+ if (is_unbounded_array (component.type ()))
539
+ return true ;
540
+ }
541
+
542
+ return false ;
543
+ }
544
+ else if (type.id () != ID_array)
521
545
return false ;
522
546
523
547
if (unbounded_array==unbounded_arrayt::U_ALL)
Original file line number Diff line number Diff line change @@ -34,14 +34,18 @@ bvt map_bv(const endianness_mapt &map, const bvt &src)
34
34
35
35
bvt boolbvt::convert_byte_extract (const byte_extract_exprt &expr)
36
36
{
37
+ const auto &width_opt = bv_width.get_width_opt (expr.type ());
38
+
37
39
// array logic does not handle byte operators, thus lower when operating on
38
40
// unbounded arrays
39
- if (is_unbounded_array (expr.op ().type ()))
41
+ if (
42
+ is_unbounded_array (expr.op ().type ()) || is_unbounded_array (expr.type ()) ||
43
+ !width_opt.has_value ())
40
44
{
41
45
return convert_bv (lower_byte_extract (expr, ns));
42
46
}
43
47
44
- const std::size_t width = boolbv_width (expr. type ()) ;
48
+ const std::size_t width = *width_opt ;
45
49
46
50
// special treatment for bit-fields and big-endian:
47
51
// we need byte granularity
Original file line number Diff line number Diff line change 10
10
11
11
bvt boolbvt::convert_union (const union_exprt &expr)
12
12
{
13
- std:: size_t width= boolbv_width (expr.type ());
13
+ const auto &width_opt = bv_width. get_width_opt (expr.type ());
14
14
15
15
const bvt &op_bv=convert_bv (expr.op ());
16
16
17
17
INVARIANT (
18
- op_bv.size () <= width ,
18
+ !width_opt. has_value () || op_bv.size () <= *width_opt ,
19
19
" operand bitvector width shall not be larger than the width indicated by "
20
20
" the union type" );
21
21
22
22
bvt bv;
23
- bv.resize (width);
23
+ if (width_opt.has_value ())
24
+ bv.resize (*width_opt);
25
+ else
26
+ bv.resize (op_bv.size ());
24
27
25
28
endianness_mapt map_u = endianness_map (expr.type ());
26
29
endianness_mapt map_op = endianness_map (expr.op ().type ());
You can’t perform that action at this time.
0 commit comments