@@ -14,6 +14,7 @@ Author: Daniel Kroening, kroening@kroening.com
1414#include < ostream>
1515#include < iomanip>
1616
17+ #include < util/expr_iterator.h>
1718#include < util/find_symbols.h>
1819#include < util/std_expr.h>
1920#include < util/validate.h>
@@ -699,6 +700,25 @@ void goto_programt::instructiont::validate(
699700 }
700701 };
701702
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+ };
721+
702722 switch (type)
703723 {
704724 case NO_INSTRUCTION_TYPE:
@@ -729,7 +749,9 @@ void goto_programt::instructiont::validate(
729749 targets.empty (),
730750 " assert instruction should not have a target" ,
731751 source_location);
752+
732753 std::for_each (guard.depth_begin (), guard.depth_end (), expr_symbol_finder);
754+ std::for_each (guard.depth_begin (), guard.depth_end (), type_finder);
733755 break ;
734756 case OTHER:
735757 break ;
@@ -794,7 +816,9 @@ void goto_programt::instructiont::validate(
794816 code.get_statement () == ID_function_call,
795817 " function call instruction should contain a call statement" ,
796818 source_location);
819+
797820 std::for_each (code.depth_begin (), code.depth_end (), expr_symbol_finder);
821+ std::for_each (code.depth_begin (), code.depth_end (), type_finder);
798822 break ;
799823 case THROW:
800824 break ;
0 commit comments