Skip to content

Commit d0212b9

Browse files
committed
Helper functions to simplify manipulating symbols
and storing the in the symbol table (and one for `free`).
1 parent 3674dcc commit d0212b9

File tree

2 files changed

+214
-0
lines changed

2 files changed

+214
-0
lines changed

src/goto-harness/recursive_initialization.cpp

Lines changed: 153 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -428,6 +428,25 @@ std::string recursive_initialization_configt::to_string() const
428428

429429
recursive_initializationt::array_convertert
430430
recursive_initializationt::default_array_member_initialization()
431+
irep_idt recursive_initializationt::get_fresh_global_name(
432+
const std::string &symbol_name,
433+
const exprt &initial_value) const
434+
{
435+
symbolt &fresh_symbol = get_fresh_aux_symbol(
436+
signed_int_type(),
437+
CPROVER_PREFIX,
438+
symbol_name,
439+
source_locationt{},
440+
initialization_config.mode,
441+
goto_model.symbol_table);
442+
fresh_symbol.is_static_lifetime = true;
443+
fresh_symbol.is_lvalue = true;
444+
fresh_symbol.value = initial_value;
445+
return fresh_symbol.name;
446+
}
447+
448+
symbol_exprt recursive_initializationt::get_fresh_global_symexpr(
449+
const std::string &symbol_name) const
431450
{
432451
return [this](
433452
const exprt &array,
@@ -437,6 +456,140 @@ recursive_initializationt::default_array_member_initialization()
437456
const recursion_sett &known_tags,
438457
code_blockt &body) {
439458
PRECONDITION(array.type().id() == ID_array);
459+
symbolt &fresh_symbol = get_fresh_aux_symbol(
460+
signed_int_type(),
461+
CPROVER_PREFIX,
462+
symbol_name,
463+
source_locationt{},
464+
initialization_config.mode,
465+
goto_model.symbol_table);
466+
fresh_symbol.is_static_lifetime = true;
467+
fresh_symbol.is_lvalue = true;
468+
fresh_symbol.value = from_integer(0, signed_int_type());
469+
return fresh_symbol.symbol_expr();
470+
}
471+
472+
symbol_exprt recursive_initializationt::get_fresh_local_symexpr(
473+
const std::string &symbol_name) const
474+
{
475+
symbolt &fresh_symbol = get_fresh_aux_symbol(
476+
signed_int_type(),
477+
CPROVER_PREFIX,
478+
symbol_name,
479+
source_locationt{},
480+
initialization_config.mode,
481+
goto_model.symbol_table);
482+
fresh_symbol.is_lvalue = true;
483+
fresh_symbol.value = from_integer(0, signed_int_type());
484+
return fresh_symbol.symbol_expr();
485+
}
486+
487+
symbol_exprt recursive_initializationt::get_fresh_local_typed_symexpr(
488+
const std::string &symbol_name,
489+
const typet &type,
490+
const exprt &init_value) const
491+
{
492+
symbolt &fresh_symbol = get_fresh_aux_symbol(
493+
type,
494+
CPROVER_PREFIX,
495+
symbol_name,
496+
source_locationt{},
497+
initialization_config.mode,
498+
goto_model.symbol_table);
499+
fresh_symbol.is_lvalue = true;
500+
fresh_symbol.value = init_value;
501+
return fresh_symbol.symbol_expr();
502+
}
503+
504+
const symbolt &recursive_initializationt::get_fresh_fun_symbol(
505+
const std::string &fun_name,
506+
const typet &fun_type)
507+
{
508+
irep_idt fresh_name(fun_name);
509+
510+
get_new_name(fresh_name, namespacet{goto_model.symbol_table}, '_');
511+
512+
// create the function symbol
513+
symbolt function_symbol{};
514+
function_symbol.name = function_symbol.base_name =
515+
function_symbol.pretty_name = fresh_name;
516+
517+
function_symbol.is_lvalue = true;
518+
function_symbol.mode = initialization_config.mode;
519+
function_symbol.type = fun_type;
520+
521+
auto r = goto_model.symbol_table.insert(function_symbol);
522+
CHECK_RETURN(r.second);
523+
return *goto_model.symbol_table.lookup(fresh_name);
524+
}
525+
526+
symbolt &recursive_initializationt::get_fresh_param_symbol(
527+
const std::string &symbol_name,
528+
const typet &symbol_type)
529+
{
530+
symbolt &param_symbol = get_fresh_aux_symbol(
531+
symbol_type,
532+
CPROVER_PREFIX,
533+
symbol_name,
534+
source_locationt{},
535+
initialization_config.mode,
536+
goto_model.symbol_table);
537+
param_symbol.is_parameter = true;
538+
param_symbol.is_lvalue = true;
539+
540+
return param_symbol;
541+
}
542+
543+
symbol_exprt
544+
recursive_initializationt::get_symbol_expr(const irep_idt &symbol_name) const
545+
{
546+
auto maybe_symbol = goto_model.symbol_table.lookup(symbol_name);
547+
CHECK_RETURN(maybe_symbol != nullptr);
548+
return maybe_symbol->symbol_expr();
549+
}
550+
551+
std::string recursive_initializationt::type2id(const typet &type) const
552+
{
553+
if(type.id() == ID_struct_tag)
554+
{
555+
auto st_tag = id2string(to_struct_tag_type(type).get_identifier());
556+
std::replace(st_tag.begin(), st_tag.end(), '-', '_');
557+
return st_tag;
558+
}
559+
else if(type.id() == ID_pointer)
560+
return "ptr_" + type2id(type.subtype());
561+
else if(type.id() == ID_array)
562+
{
563+
const auto array_size =
564+
numeric_cast_v<std::size_t>(to_constant_expr(to_array_type(type).size()));
565+
return "arr_" + type2id(type.subtype()) + "_" + std::to_string(array_size);
566+
}
567+
else if(type == char_type())
568+
return "char";
569+
else if(type.id() == ID_signedbv)
570+
return "int";
571+
else if(type.id() == ID_unsignedbv)
572+
return "uint";
573+
else
574+
return "";
575+
}
576+
577+
symbol_exprt recursive_initializationt::get_free_function()
578+
{
579+
auto free_sym = goto_model.symbol_table.lookup("free");
580+
if(free_sym == nullptr)
581+
{
582+
symbolt new_free_sym;
583+
new_free_sym.type = code_typet{code_typet{
584+
{code_typet::parametert{pointer_type(empty_typet{})}}, empty_typet{}}};
585+
new_free_sym.name = new_free_sym.pretty_name = new_free_sym.base_name =
586+
"free";
587+
new_free_sym.mode = initialization_config.mode;
588+
goto_model.symbol_table.insert(new_free_sym);
589+
return new_free_sym.symbol_expr();
590+
}
591+
return free_sym->symbol_expr();
592+
}
440593
initialize(
441594
index_exprt{array, from_integer(current_index, size_type())},
442595
depth,

src/goto-harness/recursive_initialization.h

Lines changed: 61 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -72,6 +72,11 @@ class recursive_initializationt
7272
const recursion_sett &known_tags,
7373
code_blockt &body);
7474

75+
/// Get the `free` function as symbol expression, and inserts it into the
76+
/// goto-model if it doesn't exist already.
77+
/// \return the symbol expression for the `free` function
78+
symbol_exprt get_free_function();
79+
7580
bool is_initialization_allowed(const symbolt &symbol)
7681
{
7782
return (
@@ -139,6 +144,62 @@ class recursive_initializationt
139144
optionalt<irep_idt>
140145
get_associated_size_variable(const irep_idt &array_name) const;
141146
bool should_be_treated_as_cstring(const irep_idt &pointer_name) const;
147+
148+
/// Construct a new global symbol of type `int` and set it's value to \p
149+
/// initial_value.
150+
/// \param symbol_name: the base name for the new symbol
151+
/// \param initial_value: the value the symbol should be initialised with
152+
/// \return unique name assigned to the new symbol (may differ from \p
153+
/// symbol_name)
154+
irep_idt get_fresh_global_name(
155+
const std::string &symbol_name,
156+
const exprt &initial_value) const;
157+
158+
/// Construct a new global symbol of type `int` initialised to 0.
159+
/// \param symbol_name: the base name for the new symbol
160+
/// \return the symbol expression associated with the new symbol
161+
symbol_exprt get_fresh_global_symexpr(const std::string &symbol_name) const;
162+
163+
/// Construct a new local symbol of type `int` initialised to 0.
164+
/// \param symbol_name: the base name for the new symbol
165+
/// \return the symbol expression associated with the new symbol
166+
symbol_exprt get_fresh_local_symexpr(const std::string &symbol_name) const;
167+
168+
/// Construct a new local symbol of type \p type initialised to \p init_value.
169+
/// \param symbol_name: the base name for the new symbol
170+
/// \param type: type for the new symbol
171+
/// \param init_value: expression the symbol should be initialised with
172+
/// \return the symbol expression associated with the new symbol
173+
symbol_exprt get_fresh_local_typed_symexpr(
174+
const std::string &symbol_name,
175+
const typet &type,
176+
const exprt &init_value) const;
177+
178+
/// Construct a new function symbol of type \p fun_type.
179+
/// \param fun_name: the base name for the new symbol
180+
/// \param fun_type: type for the new symbol
181+
/// \return the new symbol
182+
const symbolt &
183+
get_fresh_fun_symbol(const std::string &fun_name, const typet &fun_type);
184+
185+
/// Construct a new parameter symbol of type \p param_type.
186+
/// \param param_name: the base name for the new parameter
187+
/// \param param_type: type for the new symbol
188+
/// \return the new symbol
189+
symbolt &get_fresh_param_symbol(
190+
const std::string &param_name,
191+
const typet &param_type);
192+
193+
/// Recover the symbol expression from symbol table.
194+
/// \param symbol_name: the name of the symbol to get
195+
/// \return symbol expression of the symbol with given name
196+
symbol_exprt get_symbol_expr(const irep_idt &symbol_name) const;
197+
198+
/// Simple pretty-printer for \ref typet. Produces strings that can decorate
199+
/// variable names in C.
200+
/// \param type: type to be pretty-printed
201+
/// \return a string without white characters, quotes, etc.
202+
std::string type2id(const typet &type) const;
142203
};
143204

144205
#endif // CPROVER_GOTO_HARNESS_RECURSIVE_INITIALIZATION_H

0 commit comments

Comments
 (0)