File tree 8 files changed +78
-16
lines changed
8 files changed +78
-16
lines changed Original file line number Diff line number Diff line change @@ -650,19 +650,14 @@ void dump_ct::cleanup_decl(
650
650
std::list<irep_idt> &local_static,
651
651
std::list<irep_idt> &local_type_decls)
652
652
{
653
- exprt value=nil_exprt ();
654
-
655
- if (decl.operands ().size ()==2 )
656
- {
657
- value=decl.op1 ();
658
- decl.operands ().resize (1 );
659
- }
660
-
661
653
goto_programt tmp;
662
654
tmp.add (goto_programt::make_decl (decl.symbol ()));
663
655
664
- if (value.is_not_nil ())
665
- tmp.add (goto_programt::make_assignment (decl.symbol (), value));
656
+ if (optionalt<exprt> value = decl.initial_value ())
657
+ {
658
+ decl.set_initial_value ({});
659
+ tmp.add (goto_programt::make_assignment (decl.symbol (), std::move (*value)));
660
+ }
666
661
667
662
tmp.add (goto_programt::make_end_function ());
668
663
Original file line number Diff line number Diff line change @@ -477,7 +477,7 @@ goto_programt::const_targett goto_program2codet::convert_decl(
477
477
{
478
478
if (next->is_assign ())
479
479
{
480
- d.copy_to_operands ( next->get_assign ().rhs ());
480
+ d.set_initial_value ({ next->get_assign ().rhs ()} );
481
481
}
482
482
else
483
483
{
Original file line number Diff line number Diff line change @@ -199,13 +199,21 @@ class goto_programt
199
199
const code_declt &get_decl () const
200
200
{
201
201
PRECONDITION (is_decl ());
202
- return to_code_decl (code);
202
+ const auto &decl = expr_checked_cast<code_declt>(code);
203
+ INVARIANT (
204
+ !decl.initial_value (),
205
+ " code_declt in goto program may not contain initialization." );
206
+ return decl;
203
207
}
204
208
205
209
// / Set the declaration for DECL
206
210
void set_decl (code_declt c)
207
211
{
208
212
PRECONDITION (is_decl ());
213
+ INVARIANT (
214
+ !c.initial_value (),
215
+ " Initialization must be separated from code_declt before adding to "
216
+ " goto_instructiont." );
209
217
code = std::move (c);
210
218
}
211
219
Original file line number Diff line number Diff line change @@ -226,6 +226,7 @@ exprt wp_decl(
226
226
const exprt &post,
227
227
const namespacet &ns)
228
228
{
229
+ PRECONDITION (!code.initial_value ());
229
230
// Model decl(var) as var = nondet()
230
231
const exprt &var = code.symbol ();
231
232
side_effect_expr_nondett nondet (var.type (), source_locationt ());
Original file line number Diff line number Diff line change @@ -422,11 +422,14 @@ void format_expr_configt::setup()
422
422
{
423
423
return os << " dead " << format (to_code_dead (code).symbol ()) << " ;" ;
424
424
}
425
- else if (statement == ID_decl )
425
+ else if (const auto decl = expr_try_dynamic_cast<code_declt>(code) )
426
426
{
427
- const auto &declaration_symb = to_code_decl (code).symbol ();
428
- return os << " decl " << format (declaration_symb.type ()) << " "
429
- << format (declaration_symb) << " ;" ;
427
+ const auto &declaration_symb = decl->symbol ();
428
+ os << " decl " << format (declaration_symb.type ()) << " "
429
+ << format (declaration_symb);
430
+ if (const optionalt<exprt> initial_value = decl->initial_value ())
431
+ os << " = " << format (*initial_value);
432
+ return os << " ;" ;
430
433
}
431
434
else if (statement == ID_function_call)
432
435
{
Original file line number Diff line number Diff line change @@ -420,6 +420,38 @@ class code_declt:public codet
420
420
return symbol ().get_identifier ();
421
421
}
422
422
423
+ // / Returns the initial value to which the declared variable is initialized,
424
+ // / or empty in the case where no initialisation is included.
425
+ // / \note: Initial values may be present in the front end but they must be
426
+ // / separated into a separate assignment when used in a `goto_instructiont`.
427
+ optionalt<exprt> initial_value () const
428
+ {
429
+ if (operands ().size () < 2 )
430
+ return {};
431
+ return {op1 ()};
432
+ }
433
+
434
+ // / Sets the value to which this declaration initializes the declared
435
+ // / variable. Empty optional maybe passed to remove existing initialisation.
436
+ // / \note: Initial values may be present in the front end but they must be
437
+ // / separated into a separate assignment when used in a `goto_instructiont`.
438
+ void set_initial_value (optionalt<exprt> initial_value)
439
+ {
440
+ if (!initial_value)
441
+ {
442
+ operands ().resize (1 );
443
+ }
444
+ else if (operands ().size () < 2 )
445
+ {
446
+ PRECONDITION (operands ().size () == 1 );
447
+ add_to_operands (std::move (*initial_value));
448
+ }
449
+ else
450
+ {
451
+ op1 () = std::move (*initial_value);
452
+ }
453
+ }
454
+
423
455
static void check (
424
456
const codet &code,
425
457
const validation_modet vm = validation_modet::INVARIANT)
Original file line number Diff line number Diff line change @@ -90,6 +90,7 @@ SRC += analyses/ai/ai.cpp \
90
90
util/expr.cpp \
91
91
util/expr_iterator.cpp \
92
92
util/file_util.cpp \
93
+ util/format.cpp \
93
94
util/format_number_range.cpp \
94
95
util/get_base_name.cpp \
95
96
util/graph.cpp \
Original file line number Diff line number Diff line change
1
+ /* ******************************************************************\
2
+
3
+ Module: Unit tests for `format` function.
4
+
5
+ Author: DiffBlue Limited.
6
+
7
+ \*******************************************************************/
8
+
9
+ #include < util/format.h>
10
+ #include < util/format_expr.h>
11
+ #include < util/std_code.h>
12
+
13
+ #include < testing-utils/use_catch.h>
14
+
15
+ TEST_CASE (" Format a declaration statement." , " [core][util][format]" )
16
+ {
17
+ const signedbv_typet int_type{32 };
18
+ code_declt declaration{symbol_exprt{" foo" , int_type}};
19
+ REQUIRE (format_to_string (declaration) == " decl signedbv[32] foo;" );
20
+ declaration.set_initial_value ({int_type.zero_expr ()});
21
+ REQUIRE (format_to_string (declaration) == " decl signedbv[32] foo = 0;" );
22
+ }
You can’t perform that action at this time.
0 commit comments