@@ -14,6 +14,8 @@ Author: Daniel Kroening, kroening@kroening.com
1414#include < ostream>
1515#include < iomanip>
1616
17+ #include < util/expr_iterator.h>
18+ #include < util/find_symbols.h>
1719#include < util/std_expr.h>
1820#include < util/validate.h>
1921
@@ -677,6 +679,45 @@ void goto_programt::instructiont::validate(
677679 validate_full_expr (guard, ns, vm);
678680
679681 const symbolt *table_symbol;
682+ DATA_CHECK_WITH_DIAGNOSTICS (
683+ vm,
684+ !ns.lookup (function, table_symbol),
685+ id2string (function) + " not found" ,
686+ source_location);
687+
688+ auto expr_symbol_finder = [&](const exprt &e) {
689+ find_symbols_sett typetags;
690+ find_type_symbols (e.type (), typetags);
691+ find_symbols (e, typetags);
692+ const symbolt *symbol;
693+ for (const auto &identifier : typetags)
694+ {
695+ DATA_CHECK_WITH_DIAGNOSTICS (
696+ vm,
697+ !ns.lookup (identifier, symbol),
698+ id2string (identifier) + " not found" ,
699+ source_location);
700+ }
701+ };
702+
703+ auto ¤t_source_location = source_location;
704+ auto type_finder =
705+ [&ns, vm, &table_symbol, ¤t_source_location](const exprt &e) {
706+ if (e.id () == ID_symbol)
707+ {
708+ const auto &goto_symbol_expr = to_symbol_expr (e);
709+ const auto &goto_id = goto_symbol_expr.get_identifier ();
710+
711+ if (!ns.lookup (goto_id, table_symbol))
712+ DATA_CHECK_WITH_DIAGNOSTICS (
713+ vm,
714+ base_type_eq (goto_symbol_expr.type (), table_symbol->type , ns),
715+ id2string (goto_id) + " type inconsistency\n " +
716+ " goto program type: " + goto_symbol_expr.type ().id_string () +
717+ " \n " + " symbol table type: " + table_symbol->type .id_string (),
718+ current_source_location);
719+ }
720+ };
680721
681722 switch (type)
682723 {
@@ -708,6 +749,9 @@ void goto_programt::instructiont::validate(
708749 targets.empty (),
709750 " assert instruction should not have a target" ,
710751 source_location);
752+
753+ std::for_each (guard.depth_begin (), guard.depth_end (), expr_symbol_finder);
754+ std::for_each (guard.depth_begin (), guard.depth_end (), type_finder);
711755 break ;
712756 case OTHER:
713757 break ;
@@ -772,6 +816,9 @@ void goto_programt::instructiont::validate(
772816 code.get_statement () == ID_function_call,
773817 " function call instruction should contain a call statement" ,
774818 source_location);
819+
820+ std::for_each (code.depth_begin (), code.depth_end (), expr_symbol_finder);
821+ std::for_each (code.depth_begin (), code.depth_end (), type_finder);
775822 break ;
776823 case THROW:
777824 break ;
0 commit comments