Skip to content

Commit db4f25c

Browse files
committed
dump-c: rewrite byte_updates of unions to union expressions
C does not have byte_update expressions.
1 parent a835405 commit db4f25c

File tree

2 files changed

+62
-0
lines changed

2 files changed

+62
-0
lines changed

regression/cbmc/Union_Initialization5/main.c

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,10 @@
11
#include <assert.h>
22

3+
union U_ok {
4+
int x;
5+
int y;
6+
} u_ok = {.x = 1, .y = 2};
7+
38
#ifndef _MSC_VER
49
union U {
510
int x;
@@ -8,11 +13,13 @@ union U {
813

914
int main()
1015
{
16+
assert(u_ok.y == 2);
1117
// the excess initializer (2) is ignored
1218
assert(u.x == 1);
1319
}
1420
#else
1521
int main()
1622
{
23+
assert(u_ok.y == 2);
1724
}
1825
#endif

src/goto-instrument/dump_c.cpp

Lines changed: 55 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ Author: Daniel Kroening, [email protected]
1111

1212
#include "dump_c.h"
1313

14+
#include <util/byte_operators.h>
1415
#include <util/config.h>
1516
#include <util/find_symbols.h>
1617
#include <util/get_base_name.h>
@@ -1413,6 +1414,60 @@ void dump_ct::cleanup_expr(exprt &expr)
14131414
}
14141415
#endif
14151416
}
1417+
else if(
1418+
expr.id() == ID_byte_update_little_endian ||
1419+
expr.id() == ID_byte_update_big_endian)
1420+
{
1421+
const byte_update_exprt &bu = to_byte_update_expr(expr);
1422+
1423+
if(bu.op().id() == ID_union && bu.offset().is_zero())
1424+
{
1425+
const union_exprt &union_expr = to_union_expr(bu.op());
1426+
const union_typet &union_type =
1427+
to_union_type(ns.follow(union_expr.type()));
1428+
1429+
for(const auto &comp : union_type.components())
1430+
{
1431+
if(bu.value().type() == comp.type())
1432+
{
1433+
exprt member1{ID_member};
1434+
member1.set(ID_component_name, union_expr.get_component_name());
1435+
exprt designated_initializer1{ID_designated_initializer};
1436+
designated_initializer1.add_to_operands(union_expr.op());
1437+
designated_initializer1.add(ID_designator).move_to_sub(member1);
1438+
1439+
exprt member2{ID_member};
1440+
member2.set(ID_component_name, comp.get_name());
1441+
exprt designated_initializer2{ID_designated_initializer};
1442+
designated_initializer2.add_to_operands(bu.value());
1443+
designated_initializer2.add(ID_designator).move_to_sub(member2);
1444+
1445+
binary_exprt initializer_list{std::move(designated_initializer1),
1446+
ID_initializer_list,
1447+
std::move(designated_initializer2)};
1448+
expr.swap(initializer_list);
1449+
break;
1450+
}
1451+
}
1452+
}
1453+
else if(
1454+
bu.op().id() == ID_side_effect &&
1455+
to_side_effect_expr(bu.op()).get_statement() == ID_nondet &&
1456+
ns.follow(bu.op().type()).id() == ID_union && bu.offset().is_zero())
1457+
{
1458+
const union_typet &union_type = to_union_type(ns.follow(bu.op().type()));
1459+
1460+
for(const auto &comp : union_type.components())
1461+
{
1462+
if(bu.value().type() == comp.type())
1463+
{
1464+
union_exprt union_expr{comp.get_name(), bu.value(), bu.op().type()};
1465+
expr.swap(union_expr);
1466+
break;
1467+
}
1468+
}
1469+
}
1470+
}
14161471
}
14171472

14181473
void dump_ct::cleanup_type(typet &type)

0 commit comments

Comments
 (0)