Go to the documentation of this file.
61 for(
const auto &label :
labels)
75 out <<
"NO INSTRUCTION TYPE SET" <<
'\n';
89 out <<
"(incomplete)";
97 out << (*gt_it)->target_number;
227 out <<
"SKIP" <<
'\n';
231 out <<
"END_FUNCTION" <<
'\n';
235 out <<
"LOCATION" <<
'\n';
245 for(
const auto &ex : exception_list)
246 out <<
" " << ex.id();
249 if(
code().operands().size() == 1)
257 if(
code().get_statement() == ID_exception_landingpad)
260 out <<
"EXCEPTION LANDING PAD (" <<
format(landingpad.catch_expr().type())
261 <<
' ' <<
format(landingpad.catch_expr()) <<
")";
263 else if(
code().get_statement() == ID_push_catch)
265 out <<
"CATCH-PUSH ";
271 targets.size() == exception_list.size(),
272 "unexpected discrepancy between sizes of instruction"
273 "targets and exception list");
274 for(instructiont::targetst::const_iterator gt_it =
targets.begin();
280 out << exception_list[i].id() <<
"->"
281 << (*gt_it)->target_number;
284 else if(
code().get_statement() == ID_pop_catch)
298 out <<
"ATOMIC_BEGIN" <<
'\n';
302 out <<
"ATOMIC_END" <<
'\n';
306 out <<
"START THREAD " <<
get_target()->target_number <<
'\n';
310 out <<
"END THREAD" <<
'\n';
322 if(instruction.is_decl())
325 instruction.code().get_statement() == ID_decl,
326 "expected statement to be declaration statement");
328 instruction.code().operands().size() == 1,
329 "declaration statement expects one operand");
330 decl_identifiers.insert(instruction.decl_symbol().get_identifier());
337 if(src.
id()==ID_dereference)
341 else if(src.
id()==ID_index)
344 dest.push_back(index_expr.index());
347 else if(src.
id()==ID_member)
351 else if(src.
id()==ID_if)
354 dest.push_back(if_expr.cond());
363 std::list<exprt> dest;
365 switch(instruction.
type())
379 dest.push_back(argument);
412 std::list<exprt> dest;
414 switch(instruction.
type())
418 dest.push_back(instruction.
call_lhs());
451 std::list<exprt> &dest)
453 if(src.
id()==ID_symbol)
455 else if(src.
id()==ID_address_of)
459 else if(src.
id()==ID_dereference)
463 dest.push_back(deref);
478 std::list<exprt> dest;
480 for(
const auto &expr : expressions)
488 std::list<exprt> &dest)
505 std::list<exprt> dest;
507 for(
const auto &expr : expressions)
523 return "(NO INSTRUCTION TYPE)";
533 for(goto_programt::instructiont::targetst::const_iterator
572 return "END_FUNCTION";
584 return "ATOMIC_BEGIN";
590 result+=
"START THREAD ";
613 if(i.is_backwards_goto())
630 instruction.output(out);
656 for(
const auto &t : i.targets)
670 i.target_number=++cnt;
672 i.target_number != 0,
"GOTO instruction target cannot be zero");
681 for(
const auto &t : i.targets)
686 t->target_number != 0,
"instruction's number cannot be zero");
689 "GOTO instruction target cannot be nil_target");
702 typedef std::map<const_targett, targett> targets_mappingt;
703 targets_mappingt targets_mapping;
709 for(instructionst::const_iterator
715 targets_mapping[it]=new_instruction;
716 *new_instruction=*it;
723 for(
auto &t : i.targets)
725 targets_mappingt::iterator
726 m_target_it=targets_mapping.find(t);
730 t=m_target_it->second;
743 if(i.is_assert() && !i.condition().is_true())
754 i.incoming_edges.clear();
757 for(instructionst::iterator
765 s->incoming_edges.insert(it);
774 _type == other.
_type &&
775 _code == other.
_code &&
776 guard == other.
guard &&
777 targets.size() == other.
targets.size() &&
789 auto expr_symbol_finder = [&](
const exprt &e) {
793 for(
const auto &identifier : typetags)
797 !ns.
lookup(identifier, symbol),
803 auto ¤t_source_location = source_location();
805 [&ns, vm, ¤t_source_location](
const exprt &e) {
806 if(e.id() == ID_symbol)
809 const auto &goto_id = goto_symbol_expr.get_identifier();
812 if(!ns.
lookup(goto_id, table_symbol))
814 bool symbol_expr_type_matches_symbol_table =
815 goto_symbol_expr.
type() == table_symbol->
type;
818 !symbol_expr_type_matches_symbol_table &&
819 table_symbol->
type.
id() == ID_code)
826 goto_symbol_expr.type().source_location().get_file() !=
830 auto goto_symbol_expr_type =
834 goto_symbol_expr_type.return_type() =
835 table_symbol_type.return_type();
837 symbol_expr_type_matches_symbol_table =
838 goto_symbol_expr_type == table_symbol_type;
843 !symbol_expr_type_matches_symbol_table &&
844 goto_symbol_expr.type().id() == ID_array &&
850 if(table_symbol->
type.
id() == ID_array)
853 symbol_table_array_type.size() =
nil_exprt();
855 symbol_expr_type_matches_symbol_table =
856 goto_symbol_expr.type() == symbol_table_array_type;
862 symbol_expr_type_matches_symbol_table,
863 id2string(goto_id) +
" type inconsistency\n" +
864 "goto program type: " + goto_symbol_expr.type().id_string() +
865 "\n" +
"symbol table type: " + table_symbol->
type.
id_string(),
866 current_source_location);
880 "goto instruction expects at least one target",
885 get_target()->is_target() && get_target()->target_number != 0,
886 "goto target has to be a target",
893 "assume instruction should not have a target",
900 "assert instruction should not have a target",
903 expr_symbol_finder(guard);
904 std::for_each(guard.depth_begin(), guard.depth_end(), type_finder);
925 _code.get_statement() == ID_return,
926 "SET_RETURN_VALUE instruction should contain a return statement",
932 _code.get_statement() == ID_assign,
933 "assign instruction should contain an assign statement");
935 vm, targets.empty(),
"assign instruction should not have a target");
940 _code.get_statement() == ID_decl,
941 "declaration instructions should contain a declaration statement",
946 "declared symbols should be known",
953 _code.get_statement() == ID_dead,
954 "dead instructions should contain a dead statement",
959 "removed symbols should be known",
966 _code.get_statement() == ID_function_call,
967 "function call instruction should contain a call statement",
970 expr_symbol_finder(_code);
971 std::for_each(_code.depth_begin(), _code.depth_end(), type_finder);
988 if(get_other().get_statement() == ID_expression)
991 if(new_expression.has_value())
994 new_other.expression() = *new_expression;
995 set_other(new_other);
1002 auto new_return_value = f(return_value());
1003 if(new_return_value.has_value())
1004 return_value() = *new_return_value;
1010 auto new_assign_lhs = f(assign_lhs());
1011 auto new_assign_rhs = f(assign_rhs());
1012 if(new_assign_lhs.has_value())
1013 assign_lhs_nonconst() = new_assign_lhs.value();
1014 if(new_assign_rhs.has_value())
1015 assign_rhs_nonconst() = new_assign_rhs.value();
1021 auto new_symbol = f(decl_symbol());
1022 if(new_symbol.has_value())
1029 auto new_symbol = f(dead_symbol());
1030 if(new_symbol.has_value())
1037 auto new_lhs = f(
as_const(*this).call_lhs());
1038 if(new_lhs.has_value())
1039 call_lhs() = *new_lhs;
1041 auto new_call_function = f(
as_const(*this).call_function());
1042 if(new_call_function.has_value())
1043 call_function() = *new_call_function;
1046 bool argument_changed =
false;
1048 for(
auto &a : new_arguments)
1051 if(new_a.has_value())
1054 argument_changed =
true;
1058 if(argument_changed)
1059 call_arguments() = std::move(new_arguments);
1079 auto new_condition = f(condition());
1080 if(new_condition.has_value())
1081 condition_nonconst() = new_condition.value();
1087 std::function<
void(
const exprt &)> f)
const
1092 if(get_other().get_statement() == ID_expression)
1115 for(
auto &a : call_arguments())
1146 if(!ins.equals(*other_it))
1150 auto other_target_it = other_it->targets.begin();
1151 for(
const auto &t : ins.targets)
1154 t->location_number - ins.location_number !=
1155 (*other_target_it)->location_number - other_it->location_number)
1175 out <<
"NO_INSTRUCTION_TYPE";
1199 out <<
"START_THREAD";
1202 out <<
"END_THREAD";
1208 out <<
"END_FUNCTION";
1211 out <<
"ATOMIC_BEGIN";
1214 out <<
"ATOMIC_END";
1217 out <<
"SET_RETURN_VALUE";
1223 out <<
"FUNCTION_CALL";
1232 out <<
"INCOMPLETE_GOTO";
#define UNREACHABLE
This should be used to mark dead code.
dstringt has one field, an unsigned integer no which is an index into a static table of strings.
const irep_idt & get_comment() const
#define DATA_CHECK(vm, condition, message)
This macro takes a condition which denotes a well-formedness criterion on goto programs,...
code_expressiont & to_code_expression(codet &code)
bool is_incomplete() const
std::string as_string() const
const goto_instruction_codet & code() const
Get the code represented by this instruction.
void find_type_and_expr_symbols(const exprt &src, find_symbols_sett &dest)
Find identifiers of the sub expressions with id ID_symbol, considering both free and bound variables,...
std::ostream & output(std::ostream &) const
Output this instruction to the given stream.
const goto_instruction_codet & get_other() const
Get the statement for OTHER.
const dereference_exprt & to_dereference_expr(const exprt &expr)
Cast an exprt to a dereference_exprt.
#define CHECK_RETURN(CONDITION)
void compute_loop_numbers()
Compute loop numbers.
const index_exprt & to_index_expr(const exprt &expr)
Cast an exprt to an index_exprt.
const if_exprt & to_if_expr(const exprt &expr)
Cast an exprt to an if_exprt.
const irept & find(const irep_idt &name) const
typet type
Type of symbol.
void update()
Update all indices.
goto_instruction_codet _code
Do not read or modify directly – use code() and code_nonconst() instead.
void copy_from(const goto_programt &src)
Copy a full goto program, preserving targets.
void apply(std::function< void(const exprt &)>) const
Apply given function to all expressions.
void transform(std::function< optionalt< exprt >(exprt)>)
Apply given transformer to all expressions; no return value means no change needed.
Base class for all expressions.
void get_decl_identifiers(decl_identifierst &decl_identifiers) const
get the variables in decl statements
bool has_assertion() const
Does the goto program have an assertion?
std::string as_string(const class namespacet &ns, const irep_idt &function, const goto_programt::instructiont &i)
#define DATA_CHECK_WITH_DIAGNOSTICS(vm, condition, message,...)
std::string to_string(const string_not_contains_constraintt &expr)
Used for debug printing.
targetst targets
The list of successor instructions.
bool is_incomplete_goto() const
std::list< Target > get_successors(Target target) const
Get control-flow successors of a given instruction.
bool is_true() const
Return whether the expression is a constant representing true.
std::list< exprt > expressions_written(const goto_programt::instructiont &instruction)
const symbol_exprt & decl_symbol() const
Get the declared symbol for DECL.
const exprt::operandst & call_arguments() const
Get the arguments of a FUNCTION_CALL.
A namespacet is essentially one or two symbol tables bound together, to allow for symbol lookups in t...
targett add_instruction()
Adds an instruction at the end.
bool lookup(const irep_idt &name, const symbolt *&symbol) const override
See documentation for namespace_baset::lookup().
const code_typet & to_code_type(const typet &type)
Cast a typet to a code_typet.
bool equals(const goto_programt &other) const
Syntactic equality: two goto_programt are equal if, and only if, they have the same number of instruc...
void validate(const namespacet &ns, const validation_modet vm) const
Check that the instruction is well-formed.
const T & as_const(T &value)
Return a reference to the same object but ensures the type is const.
void compute_target_numbers()
Compute the target numbers.
goto_program_instruction_typet type() const
What kind of instruction?
void validate_full_code(const codet &code, const namespacet &ns, const validation_modet vm)
Check that the given code statement is well-formed (full check, including checks of all subexpression...
#define DATA_INVARIANT(CONDITION, REASON)
This condition should be used to document that assumptions that are made on goto_functions,...
const symbol_exprt & dead_symbol() const
Get the symbol for DEAD.
const std::string & id2string(const irep_idt &d)
const source_locationt & source_location() const
std::ostream & operator<<(std::ostream &out, goto_program_instruction_typet t)
Outputs a string representation of a goto_program_instruction_typet
static optionalt< smt_termt > get_identifier(const exprt &expr, const std::unordered_map< exprt, smt_identifier_termt, irep_hash > &expression_handle_identifiers, const std::unordered_map< exprt, smt_identifier_termt, irep_hash > &expression_identifiers)
#define forall_operands(it, expr)
codet representation of a goto statement.
const source_locationt & source_location() const
void objects_read(const exprt &src, std::list< exprt > &dest)
goto_program_instruction_typet _type
bool equals(const instructiont &other) const
Syntactic equality: two instructiont are equal if they have the same type, code, guard,...
std::ostream & output(const namespacet &ns, const irep_idt &identifier, std::ostream &out) const
Output goto program to given stream.
const std::string & id_string() const
const symbol_exprt & to_symbol_expr(const exprt &expr)
Cast an exprt to a symbol_exprt.
const irep_idt & id() const
void objects_written(const exprt &src, std::list< exprt > &dest)
std::vector< exprt > operandst
const exprt & assign_rhs() const
Get the rhs of the assignment for ASSIGN.
const exprt & call_lhs() const
Get the lhs of a FUNCTION_CALL (may be nil)
void compute_incoming_edges()
Compute for each instruction the set of instructions it is a successor of.
nonstd::optional< T > optionalt
void clear()
Clear the goto program.
const exprt & return_value() const
Get the return value of a SET_RETURN_VALUE instruction.
goto_program_instruction_typet
The type of an instruction in a GOTO program.
void compute_location_numbers()
Compute location numbers.
instructionst instructions
The list of instructions in the goto program.
static code_landingpadt & to_code_landingpad(codet &code)
unsigned target_number
A number to identify branch targets.
std::unordered_set< irep_idt > find_symbols_sett
const exprt & assign_lhs() const
Get the lhs of the assignment for ASSIGN.
unsigned location_number
A globally unique number to identify a program location.
std::list< exprt > expressions_read(const goto_programt::instructiont &instruction)
exprt guard
Guard for gotos, assume, assert Use condition() method to access.
const array_typet & to_array_type(const typet &type)
Cast a typet to an array_typet.
A generic container class for the GOTO intermediate representation of one function.
void validate_full_expr(const exprt &expr, const namespacet &ns, const validation_modet vm)
Check that the given expression is well-formed (full check, including checks of all subexpressions an...
const irep_idt & get_file() const
const member_exprt & to_member_expr(const exprt &expr)
Cast an exprt to a member_exprt.
instructionst::const_iterator const_targett
const exprt & condition() const
Get the condition of gotos, assume, assert.
The Boolean constant true.
const irep_idt & get_statement() const
bool is_true(const literalt &l)
std::set< irep_idt > decl_identifierst
static std::string comment(const rw_set_baset::entryt &entry, bool write)
This class represents an instruction in the GOTO intermediate representation.
bool is_target() const
Is this node a branch target?
std::string from_expr(const namespacet &ns, const irep_idt &identifier, const exprt &expr)
static const unsigned nil_target
Uniquely identify an invalid target or location.
const exprt & call_function() const
Get the function that is called for FUNCTION_CALL.
targett get_target() const
Returns the first (and only) successor for the usual case of a single target.
bool get_bool(const irep_idt &name) const
static instructiont make_incomplete_goto(const exprt &_cond, const source_locationt &l=source_locationt::nil())
void parse_lhs_read(const exprt &src, std::list< exprt > &dest)