17
17
#include " namespace.h" // IWYU pragma: keep
18
18
#include " std_code.h"
19
19
20
- template <bool nondet>
21
20
class expr_initializert
22
21
{
23
22
public:
24
23
explicit expr_initializert (const namespacet &_ns) : ns(_ns)
25
24
{
26
25
}
27
26
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)
30
31
{
31
- return expr_initializer_rec (type, source_location);
32
+ return expr_initializer_rec (type, source_location, init_expr );
32
33
}
33
34
34
35
protected:
35
36
const namespacet &ns;
36
37
37
38
optionalt<exprt> expr_initializer_rec (
38
39
const typet &type,
39
- const source_locationt &source_location);
40
+ const source_locationt &source_location,
41
+ const exprt &init_expr);
40
42
};
41
43
42
- template <bool nondet>
43
- optionalt<exprt> expr_initializert<nondet>::expr_initializer_rec(
44
+ optionalt<exprt> expr_initializert::expr_initializer_rec (
44
45
const typet &type,
45
- const source_locationt &source_location)
46
+ const source_locationt &source_location,
47
+ const exprt &init_expr)
46
48
{
47
49
const irep_idt &type_id=type.id ();
48
50
@@ -57,9 +59,9 @@ optionalt<exprt> expr_initializert<nondet>::expr_initializer_rec(
57
59
type_id==ID_fixedbv)
58
60
{
59
61
exprt result;
60
- if (nondet )
62
+ if (init_expr. id () == ID_nondet )
61
63
result = side_effect_expr_nondett (type, source_location);
62
- else
64
+ else if (init_expr. is_zero ())
63
65
result = from_integer (0 , type);
64
66
65
67
result.add_source_location ()=source_location;
@@ -69,9 +71,9 @@ optionalt<exprt> expr_initializert<nondet>::expr_initializer_rec(
69
71
type_id==ID_real)
70
72
{
71
73
exprt result;
72
- if (nondet )
74
+ if (init_expr. id () == ID_nondet )
73
75
result = side_effect_expr_nondett (type, source_location);
74
- else
76
+ else if (init_expr. is_zero ())
75
77
result = constant_exprt (ID_0, type);
76
78
77
79
result.add_source_location ()=source_location;
@@ -81,9 +83,9 @@ optionalt<exprt> expr_initializert<nondet>::expr_initializer_rec(
81
83
type_id==ID_verilog_unsignedbv)
82
84
{
83
85
exprt result;
84
- if (nondet )
86
+ if (init_expr. id () == ID_nondet )
85
87
result = side_effect_expr_nondett (type, source_location);
86
- else
88
+ else if (init_expr. is_zero ())
87
89
{
88
90
const std::size_t width = to_bitvector_type (type).get_width ();
89
91
std::string value (width, ' 0' );
@@ -97,12 +99,12 @@ optionalt<exprt> expr_initializert<nondet>::expr_initializer_rec(
97
99
else if (type_id==ID_complex)
98
100
{
99
101
exprt result;
100
- if (nondet )
102
+ if (init_expr. id () == ID_nondet )
101
103
result = side_effect_expr_nondett (type, source_location);
102
- else
104
+ else if (init_expr. is_zero ())
103
105
{
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 );
106
108
if (!sub_zero.has_value ())
107
109
return {};
108
110
@@ -127,8 +129,8 @@ optionalt<exprt> expr_initializert<nondet>::expr_initializer_rec(
127
129
}
128
130
else
129
131
{
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 );
132
134
if (!tmpval.has_value ())
133
135
return {};
134
136
@@ -137,7 +139,7 @@ optionalt<exprt> expr_initializert<nondet>::expr_initializer_rec(
137
139
array_type.size ().id () == ID_infinity || !array_size.has_value () ||
138
140
*array_size > MAX_FLATTENED_ARRAY_SIZE)
139
141
{
140
- if (nondet )
142
+ if (init_expr. id () == ID_nondet )
141
143
return side_effect_expr_nondett (type, source_location);
142
144
143
145
array_of_exprt value (*tmpval, array_type);
@@ -159,8 +161,8 @@ optionalt<exprt> expr_initializert<nondet>::expr_initializer_rec(
159
161
{
160
162
const vector_typet &vector_type=to_vector_type (type);
161
163
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 );
164
166
if (!tmpval.has_value ())
165
167
return {};
166
168
@@ -190,7 +192,8 @@ optionalt<exprt> expr_initializert<nondet>::expr_initializer_rec(
190
192
DATA_INVARIANT (
191
193
c.type ().id () != ID_code, " struct member must not be of code type" );
192
194
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);
194
197
if (!member.has_value ())
195
198
return {};
196
199
@@ -216,8 +219,8 @@ optionalt<exprt> expr_initializert<nondet>::expr_initializer_rec(
216
219
if (!widest_member.has_value ())
217
220
return {};
218
221
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 );
221
224
222
225
if (!component_value.has_value ())
223
226
return {};
@@ -230,7 +233,7 @@ optionalt<exprt> expr_initializert<nondet>::expr_initializer_rec(
230
233
else if (type_id==ID_c_enum_tag)
231
234
{
232
235
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 );
234
237
235
238
if (!result.has_value ())
236
239
return {};
@@ -243,7 +246,7 @@ optionalt<exprt> expr_initializert<nondet>::expr_initializer_rec(
243
246
else if (type_id==ID_struct_tag)
244
247
{
245
248
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 );
247
250
248
251
if (!result.has_value ())
249
252
return {};
@@ -256,7 +259,7 @@ optionalt<exprt> expr_initializert<nondet>::expr_initializer_rec(
256
259
else if (type_id==ID_union_tag)
257
260
{
258
261
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 );
260
263
261
264
if (!result.has_value ())
262
265
return {};
@@ -269,9 +272,9 @@ optionalt<exprt> expr_initializert<nondet>::expr_initializer_rec(
269
272
else if (type_id==ID_string)
270
273
{
271
274
exprt result;
272
- if (nondet )
275
+ if (init_expr. id () == ID_nondet )
273
276
result = side_effect_expr_nondett (type, source_location);
274
- else
277
+ else if (init_expr. is_zero ())
275
278
result = constant_exprt (irep_idt (), type);
276
279
277
280
result.add_source_location ()=source_location;
@@ -292,7 +295,8 @@ optionalt<exprt> zero_initializer(
292
295
const source_locationt &source_location,
293
296
const namespacet &ns)
294
297
{
295
- return expr_initializert<false >(ns)(type, source_location);
298
+ return expr_initializert (ns)(
299
+ type, source_location, constant_exprt (ID_0, char_type ()));
296
300
}
297
301
298
302
// / Create a non-deterministic value for type `type`, with all subtypes
@@ -307,5 +311,5 @@ optionalt<exprt> nondet_initializer(
307
311
const source_locationt &source_location,
308
312
const namespacet &ns)
309
313
{
310
- return expr_initializert< true > (ns)(type, source_location);
314
+ return expr_initializert (ns)(type, source_location, exprt (ID_nondet) );
311
315
}
0 commit comments