Skip to content

Commit cc3708c

Browse files
peterschrammelEnrico Steffinlongo
authored and
Enrico Steffinlongo
committed
Refactor expr_initializer to take initialization expression
We can now pass in 0 and nondet, and can then extend it to take more general initialization expressions.
1 parent 5650fb9 commit cc3708c

File tree

1 file changed

+37
-33
lines changed

1 file changed

+37
-33
lines changed

src/util/expr_initializer.cpp

Lines changed: 37 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -17,32 +17,34 @@ Author: Daniel Kroening, [email protected]
1717
#include "namespace.h" // IWYU pragma: keep
1818
#include "std_code.h"
1919

20-
template <bool nondet>
2120
class expr_initializert
2221
{
2322
public:
2423
explicit expr_initializert(const namespacet &_ns) : ns(_ns)
2524
{
2625
}
2726

28-
optionalt<exprt>
29-
operator()(const typet &type, const source_locationt &source_location)
27+
optionalt<exprt> operator()(
28+
const typet &type,
29+
const source_locationt &source_location,
30+
const exprt &init_expr)
3031
{
31-
return expr_initializer_rec(type, source_location);
32+
return expr_initializer_rec(type, source_location, init_expr);
3233
}
3334

3435
protected:
3536
const namespacet &ns;
3637

3738
optionalt<exprt> expr_initializer_rec(
3839
const typet &type,
39-
const source_locationt &source_location);
40+
const source_locationt &source_location,
41+
const exprt &init_expr);
4042
};
4143

42-
template <bool nondet>
43-
optionalt<exprt> expr_initializert<nondet>::expr_initializer_rec(
44+
optionalt<exprt> expr_initializert::expr_initializer_rec(
4445
const typet &type,
45-
const source_locationt &source_location)
46+
const source_locationt &source_location,
47+
const exprt &init_expr)
4648
{
4749
const irep_idt &type_id=type.id();
4850

@@ -57,9 +59,9 @@ optionalt<exprt> expr_initializert<nondet>::expr_initializer_rec(
5759
type_id==ID_fixedbv)
5860
{
5961
exprt result;
60-
if(nondet)
62+
if(init_expr.id() == ID_nondet)
6163
result = side_effect_expr_nondett(type, source_location);
62-
else
64+
else if(init_expr.is_zero())
6365
result = from_integer(0, type);
6466

6567
result.add_source_location()=source_location;
@@ -69,9 +71,9 @@ optionalt<exprt> expr_initializert<nondet>::expr_initializer_rec(
6971
type_id==ID_real)
7072
{
7173
exprt result;
72-
if(nondet)
74+
if(init_expr.id() == ID_nondet)
7375
result = side_effect_expr_nondett(type, source_location);
74-
else
76+
else if(init_expr.is_zero())
7577
result = constant_exprt(ID_0, type);
7678

7779
result.add_source_location()=source_location;
@@ -81,9 +83,9 @@ optionalt<exprt> expr_initializert<nondet>::expr_initializer_rec(
8183
type_id==ID_verilog_unsignedbv)
8284
{
8385
exprt result;
84-
if(nondet)
86+
if(init_expr.id() == ID_nondet)
8587
result = side_effect_expr_nondett(type, source_location);
86-
else
88+
else if(init_expr.is_zero())
8789
{
8890
const std::size_t width = to_bitvector_type(type).get_width();
8991
std::string value(width, '0');
@@ -97,12 +99,12 @@ optionalt<exprt> expr_initializert<nondet>::expr_initializer_rec(
9799
else if(type_id==ID_complex)
98100
{
99101
exprt result;
100-
if(nondet)
102+
if(init_expr.id() == ID_nondet)
101103
result = side_effect_expr_nondett(type, source_location);
102-
else
104+
else if(init_expr.is_zero())
103105
{
104-
auto sub_zero =
105-
expr_initializer_rec(to_complex_type(type).subtype(), source_location);
106+
auto sub_zero = expr_initializer_rec(
107+
to_complex_type(type).subtype(), source_location, init_expr);
106108
if(!sub_zero.has_value())
107109
return {};
108110

@@ -127,8 +129,8 @@ optionalt<exprt> expr_initializert<nondet>::expr_initializer_rec(
127129
}
128130
else
129131
{
130-
auto tmpval =
131-
expr_initializer_rec(array_type.element_type(), source_location);
132+
auto tmpval = expr_initializer_rec(
133+
array_type.element_type(), source_location, init_expr);
132134
if(!tmpval.has_value())
133135
return {};
134136

@@ -137,7 +139,7 @@ optionalt<exprt> expr_initializert<nondet>::expr_initializer_rec(
137139
array_type.size().id() == ID_infinity || !array_size.has_value() ||
138140
*array_size > MAX_FLATTENED_ARRAY_SIZE)
139141
{
140-
if(nondet)
142+
if(init_expr.id() == ID_nondet)
141143
return side_effect_expr_nondett(type, source_location);
142144

143145
array_of_exprt value(*tmpval, array_type);
@@ -159,8 +161,8 @@ optionalt<exprt> expr_initializert<nondet>::expr_initializer_rec(
159161
{
160162
const vector_typet &vector_type=to_vector_type(type);
161163

162-
auto tmpval =
163-
expr_initializer_rec(vector_type.element_type(), source_location);
164+
auto tmpval = expr_initializer_rec(
165+
vector_type.element_type(), source_location, init_expr);
164166
if(!tmpval.has_value())
165167
return {};
166168

@@ -190,7 +192,8 @@ optionalt<exprt> expr_initializert<nondet>::expr_initializer_rec(
190192
DATA_INVARIANT(
191193
c.type().id() != ID_code, "struct member must not be of code type");
192194

193-
const auto member = expr_initializer_rec(c.type(), source_location);
195+
const auto member =
196+
expr_initializer_rec(c.type(), source_location, init_expr);
194197
if(!member.has_value())
195198
return {};
196199

@@ -216,8 +219,8 @@ optionalt<exprt> expr_initializert<nondet>::expr_initializer_rec(
216219
if(!widest_member.has_value())
217220
return {};
218221

219-
auto component_value =
220-
expr_initializer_rec(widest_member->first.type(), source_location);
222+
auto component_value = expr_initializer_rec(
223+
widest_member->first.type(), source_location, init_expr);
221224

222225
if(!component_value.has_value())
223226
return {};
@@ -230,7 +233,7 @@ optionalt<exprt> expr_initializert<nondet>::expr_initializer_rec(
230233
else if(type_id==ID_c_enum_tag)
231234
{
232235
auto result = expr_initializer_rec(
233-
ns.follow_tag(to_c_enum_tag_type(type)), source_location);
236+
ns.follow_tag(to_c_enum_tag_type(type)), source_location, init_expr);
234237

235238
if(!result.has_value())
236239
return {};
@@ -243,7 +246,7 @@ optionalt<exprt> expr_initializert<nondet>::expr_initializer_rec(
243246
else if(type_id==ID_struct_tag)
244247
{
245248
auto result = expr_initializer_rec(
246-
ns.follow_tag(to_struct_tag_type(type)), source_location);
249+
ns.follow_tag(to_struct_tag_type(type)), source_location, init_expr);
247250

248251
if(!result.has_value())
249252
return {};
@@ -256,7 +259,7 @@ optionalt<exprt> expr_initializert<nondet>::expr_initializer_rec(
256259
else if(type_id==ID_union_tag)
257260
{
258261
auto result = expr_initializer_rec(
259-
ns.follow_tag(to_union_tag_type(type)), source_location);
262+
ns.follow_tag(to_union_tag_type(type)), source_location, init_expr);
260263

261264
if(!result.has_value())
262265
return {};
@@ -269,9 +272,9 @@ optionalt<exprt> expr_initializert<nondet>::expr_initializer_rec(
269272
else if(type_id==ID_string)
270273
{
271274
exprt result;
272-
if(nondet)
275+
if(init_expr.id() == ID_nondet)
273276
result = side_effect_expr_nondett(type, source_location);
274-
else
277+
else if(init_expr.is_zero())
275278
result = constant_exprt(irep_idt(), type);
276279

277280
result.add_source_location()=source_location;
@@ -292,7 +295,8 @@ optionalt<exprt> zero_initializer(
292295
const source_locationt &source_location,
293296
const namespacet &ns)
294297
{
295-
return expr_initializert<false>(ns)(type, source_location);
298+
return expr_initializert(ns)(
299+
type, source_location, constant_exprt(ID_0, char_type()));
296300
}
297301

298302
/// Create a non-deterministic value for type `type`, with all subtypes
@@ -307,5 +311,5 @@ optionalt<exprt> nondet_initializer(
307311
const source_locationt &source_location,
308312
const namespacet &ns)
309313
{
310-
return expr_initializert<true>(ns)(type, source_location);
314+
return expr_initializert(ns)(type, source_location, exprt(ID_nondet));
311315
}

0 commit comments

Comments
 (0)