Skip to content

Commit 7f998c4

Browse files
authored
Merge pull request diffblue#5867 from tautschnig/dump-c-bool-constant
dump-c: fix output of _Bool-typed constants
2 parents cf88f82 + 6779f39 commit 7f998c4

File tree

7 files changed

+78
-43
lines changed

7 files changed

+78
-43
lines changed
Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
#include <assert.h>
2+
3+
int main()
4+
{
5+
_Bool v;
6+
v = 1;
7+
assert(v == 1);
8+
}
Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
CORE
2+
main.c
3+
--dump-c
4+
VERIFICATION SUCCESSFUL
5+
^EXIT=0$
6+
^SIGNAL=0$
7+
--
8+
^warning: ignoring
9+
--
10+
Dump-c previously always generated 0 for _Bool or __CPROVER_bool-typed
11+
constants. This test ensures that the value "1" (in v = 1) is correctly
12+
generated, instead of a spurious (v = (__CPROVER_bool)0).

regression/goto-instrument/dump-union2/main.c

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ union U10 {
1212
};
1313

1414
union U10 g_2110 = {.f0 = 53747};
15+
union U10 g_1256 = {-6L};
1516

1617
union U6 {
1718
signed f0 : 3;

src/goto-instrument/dump_c.cpp

Lines changed: 49 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -20,8 +20,8 @@ Author: Daniel Kroening, [email protected]
2020
#include <util/replace_symbol.h>
2121
#include <util/string_utils.h>
2222

23-
#include <ansi-c/ansi_c_language.h>
24-
#include <cpp/cpp_language.h>
23+
#include <ansi-c/expr2c.h>
24+
#include <cpp/expr2cpp.h>
2525

2626
#include <linking/static_lifetime_init.h>
2727

@@ -526,7 +526,7 @@ void dump_ct::convert_compound(
526526
if(t.get_width()<=config.ansi_c.long_long_int_width)
527527
struct_body << "long long int " << comp_name
528528
<< " : " << t.get_width();
529-
else if(language->id()=="cpp")
529+
else if(mode == ID_cpp)
530530
struct_body << "__signedbv<" << t.get_width() << "> "
531531
<< comp_name;
532532
else
@@ -538,7 +538,7 @@ void dump_ct::convert_compound(
538538
if(t.get_width()<=config.ansi_c.long_long_int_width)
539539
struct_body << "unsigned long long " << comp_name
540540
<< " : " << t.get_width();
541-
else if(language->id()=="cpp")
541+
else if(mode == ID_cpp)
542542
struct_body << "__unsignedbv<" << t.get_width() << "> "
543543
<< comp_name;
544544
else
@@ -573,7 +573,7 @@ void dump_ct::convert_compound(
573573
os << type_to_string(unresolved_clean);
574574
if(!base_decls.str().empty())
575575
{
576-
PRECONDITION(language->id()=="cpp");
576+
PRECONDITION(mode == ID_cpp);
577577
os << ": " << base_decls.str();
578578
}
579579
os << '\n';
@@ -1469,11 +1469,18 @@ void dump_ct::cleanup_expr(exprt &expr)
14691469
}
14701470
}
14711471

1472+
optionalt<exprt> clean_init;
14721473
if(
14731474
ns.follow(bu.type()).id() == ID_union &&
1474-
bu.source_location().get_function().empty() &&
1475-
bu.op() == zero_initializer(bu.op().type(), source_locationt{}, ns)
1476-
.value_or(nil_exprt{}))
1475+
bu.source_location().get_function().empty())
1476+
{
1477+
clean_init = zero_initializer(bu.op().type(), source_locationt{}, ns)
1478+
.value_or(nil_exprt{});
1479+
if(clean_init->id() != ID_struct || clean_init->has_operands())
1480+
cleanup_expr(*clean_init);
1481+
}
1482+
1483+
if(clean_init.has_value() && bu.op() == *clean_init)
14771484
{
14781485
const union_typet &union_type = to_union_type(ns.follow(bu.type()));
14791486

@@ -1521,22 +1528,49 @@ void dump_ct::cleanup_type(typet &type)
15211528
!type.get(ID_tag).empty());
15221529
}
15231530

1531+
static expr2c_configurationt expr2c_configuration()
1532+
{
1533+
// future TODO: with C++20 we can actually use designated initializers as
1534+
// commented out below
1535+
static expr2c_configurationt configuration{
1536+
/* .include_struct_padding_components = */ true,
1537+
/* .print_struct_body_in_type = */ true,
1538+
/* .include_array_size = */ true,
1539+
/* .true_string = */ "1",
1540+
/* .false_string = */ "0",
1541+
/* .use_library_macros = */ true,
1542+
/* .print_enum_int_value = */ false,
1543+
/* .expand_typedef = */ false};
1544+
1545+
return configuration;
1546+
}
1547+
15241548
std::string dump_ct::type_to_string(const typet &type)
15251549
{
15261550
std::string ret;
15271551
typet t=type;
15281552
cleanup_type(t);
1529-
language->from_type(t, ret, ns);
1530-
return ret;
1553+
1554+
if(mode == ID_C)
1555+
return type2c(t, ns, expr2c_configuration());
1556+
else if(mode == ID_cpp)
1557+
return type2cpp(t, ns);
1558+
else
1559+
UNREACHABLE;
15311560
}
15321561

15331562
std::string dump_ct::expr_to_string(const exprt &expr)
15341563
{
15351564
std::string ret;
15361565
exprt e=expr;
15371566
cleanup_expr(e);
1538-
language->from_expr(e, ret, ns);
1539-
return ret;
1567+
1568+
if(mode == ID_C)
1569+
return expr2c(e, ns, expr2c_configuration());
1570+
else if(mode == ID_cpp)
1571+
return expr2cpp(e, ns);
1572+
else
1573+
UNREACHABLE;
15401574
}
15411575

15421576
void dump_c(
@@ -1548,12 +1582,7 @@ void dump_c(
15481582
std::ostream &out)
15491583
{
15501584
dump_ct goto2c(
1551-
src,
1552-
use_system_headers,
1553-
use_all_headers,
1554-
include_harness,
1555-
ns,
1556-
new_ansi_c_language);
1585+
src, use_system_headers, use_all_headers, include_harness, ns, ID_C);
15571586
out << goto2c;
15581587
}
15591588

@@ -1566,12 +1595,7 @@ void dump_cpp(
15661595
std::ostream &out)
15671596
{
15681597
dump_ct goto2cpp(
1569-
src,
1570-
use_system_headers,
1571-
use_all_headers,
1572-
include_harness,
1573-
ns,
1574-
new_cpp_language);
1598+
src, use_system_headers, use_all_headers, include_harness, ns, ID_cpp);
15751599
out << goto2cpp;
15761600
}
15771601

@@ -1616,7 +1640,7 @@ void dump_c_type_header(
16161640
use_all_headers,
16171641
include_harness,
16181642
new_ns,
1619-
new_ansi_c_language,
1643+
ID_C,
16201644
dump_c_configurationt::type_header_configuration);
16211645
out << goto2c;
16221646
}

src/goto-instrument/dump_c_class.h

Lines changed: 5 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -14,10 +14,6 @@ Author: Daniel Kroening, [email protected]
1414

1515
#include <set>
1616
#include <string>
17-
#include <memory> // unique_ptr
18-
19-
#include <langapi/language.h>
20-
#include <langapi/mode.h>
2117

2218
#include <goto-programs/system_library_symbols.h>
2319

@@ -116,13 +112,13 @@ class dump_ct
116112
const bool use_all_headers,
117113
const bool include_harness,
118114
const namespacet &_ns,
119-
language_factoryt factory,
115+
const irep_idt &mode,
120116
const dump_c_configurationt config)
121117
: goto_functions(_goto_functions),
122118
copied_symbol_table(_ns.get_symbol_table()),
123119
ns(copied_symbol_table),
124120
dump_c_config(config),
125-
language(factory()),
121+
mode(mode),
126122
harness(include_harness),
127123
system_symbols(use_system_headers)
128124
{
@@ -135,14 +131,14 @@ class dump_ct
135131
const bool use_all_headers,
136132
const bool include_harness,
137133
const namespacet &_ns,
138-
language_factoryt factory)
134+
const irep_idt &mode)
139135
: dump_ct(
140136
_goto_functions,
141137
use_system_headers,
142138
use_all_headers,
143139
include_harness,
144140
_ns,
145-
factory,
141+
mode,
146142
dump_c_configurationt::default_configuration)
147143
{
148144
}
@@ -156,7 +152,7 @@ class dump_ct
156152
symbol_tablet copied_symbol_table;
157153
const namespacet ns;
158154
const dump_c_configurationt dump_c_config;
159-
std::unique_ptr<languaget> language;
155+
const irep_idt mode;
160156
const bool harness;
161157

162158
typedef std::unordered_set<irep_idt> convertedt;

src/goto-instrument/goto_program2code.cpp

Lines changed: 0 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1893,14 +1893,6 @@ void goto_program2codet::cleanup_expr(exprt &expr, bool no_typecast)
18931893
}
18941894
else if(expr.type().id()==ID_pointer)
18951895
add_local_types(expr.type());
1896-
else if(expr.type().id()==ID_bool ||
1897-
expr.type().id()==ID_c_bool)
1898-
{
1899-
expr = typecast_exprt(
1900-
from_integer(
1901-
expr.is_true() ? 1 : 0, signedbv_typet(config.ansi_c.int_width)),
1902-
bool_typet());
1903-
}
19041896

19051897
const irept &c_sizeof_type=expr.find(ID_C_c_sizeof_type);
19061898

src/util/expr.cpp

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -146,7 +146,9 @@ bool exprt::is_one() const
146146
CHECK_RETURN(false);
147147
return rat_value.is_one();
148148
}
149-
else if(type_id==ID_unsignedbv || type_id==ID_signedbv)
149+
else if(
150+
type_id == ID_unsignedbv || type_id == ID_signedbv ||
151+
type_id == ID_c_bool || type_id == ID_c_bit_field)
150152
{
151153
const auto width = to_bitvector_type(type()).get_width();
152154
mp_integer int_value =

0 commit comments

Comments
 (0)