@@ -17,32 +17,34 @@ Author: Daniel Kroening, kroening@kroening.com
1717#include " namespace.h" // IWYU pragma: keep
1818#include " std_code.h"
1919
20- template <bool nondet>
2120class expr_initializert
2221{
2322public:
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
3435protected:
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