Skip to content

Commit aaf342a

Browse files
Petr BauchPetr Bauch
Petr Bauch
authored and
Petr Bauch
committed
Program table symbol type consistency
Look up the symbol id in symbol table and call base_type_eq on every symbol expression in guard and code whenever relevant. Includes a unit test.
1 parent 907b9cc commit aaf342a

File tree

6 files changed

+109
-5
lines changed

6 files changed

+109
-5
lines changed

src/goto-programs/goto_functions.h

+1
Original file line numberDiff line numberDiff line change
@@ -130,6 +130,7 @@ class goto_functionst
130130
const auto &function_name = entry.first;
131131

132132
DATA_CHECK(
133+
vm,
133134
goto_function.type == ns.lookup(function_name).type,
134135
id2string(function_name) + " type inconsistency\ngoto program type: " +
135136
goto_function.type.id_string() +

src/goto-programs/goto_program.cpp

+23-1
Original file line numberDiff line numberDiff line change
@@ -678,7 +678,8 @@ void goto_programt::instructiont::validate(
678678
validate_full_expr(guard, ns, vm);
679679

680680
const symbolt *table_symbol;
681-
DATA_CHECK_WITH_DIAGNOSTICS(vm,
681+
DATA_CHECK_WITH_DIAGNOSTICS(
682+
vm,
682683
!ns.lookup(function, table_symbol),
683684
id2string(function) + " not found",
684685
source_location);
@@ -691,6 +692,25 @@ void goto_programt::instructiont::validate(
691692
find_symbol_in_namespace(e, source_location, ns, vm);
692693
};
693694

695+
auto &current_source_location = source_location;
696+
auto type_finder =
697+
[&ns, vm, &table_symbol, &current_source_location](const exprt &e) {
698+
if(e.id() == ID_symbol)
699+
{
700+
const auto &goto_symbol_expr = to_symbol_expr(e);
701+
const auto &goto_id = goto_symbol_expr.get_identifier();
702+
703+
if(!ns.lookup(goto_id, table_symbol))
704+
DATA_CHECK_WITH_DIAGNOSTICS(
705+
vm,
706+
base_type_eq(goto_symbol_expr.type(), table_symbol->type, ns),
707+
id2string(goto_id) + " type inconsistency\n" +
708+
"goto program type: " + goto_symbol_expr.type().id_string() +
709+
"\n" + "symbol table type: " + table_symbol->type.id_string(),
710+
current_source_location);
711+
}
712+
};
713+
694714
switch(type)
695715
{
696716
case NO_INSTRUCTION_TYPE:
@@ -723,6 +743,7 @@ void goto_programt::instructiont::validate(
723743
source_location);
724744

725745
guard.visit(expr_symbol_finder);
746+
guard.visit(type_finder);
726747
break;
727748
case OTHER:
728749
break;
@@ -789,6 +810,7 @@ void goto_programt::instructiont::validate(
789810
source_location);
790811

791812
code.visit(expr_symbol_finder);
813+
code.visit(type_finder);
792814
break;
793815
case THROW:
794816
break;

src/util/find_symbols.cpp

+8-4
Original file line numberDiff line numberDiff line change
@@ -232,10 +232,13 @@ void find_typetag_in_namespace(
232232
{
233233
const symbolt *symbol;
234234
if(location.is_nil())
235-
DATA_CHECK(vm,
236-
!ns.lookup(identifier, symbol), id2string(identifier) + " not found");
235+
DATA_CHECK(
236+
vm,
237+
!ns.lookup(identifier, symbol),
238+
id2string(identifier) + " not found");
237239
else
238-
DATA_CHECK_WITH_DIAGNOSTICS(vm,
240+
DATA_CHECK_WITH_DIAGNOSTICS(
241+
vm,
239242
!ns.lookup(identifier, symbol),
240243
id2string(identifier) + " not found",
241244
location);
@@ -252,7 +255,8 @@ void find_symbol_in_namespace(
252255
{
253256
const symbolt *symbol;
254257
auto identifier = to_symbol_expr(src).get_identifier();
255-
DATA_CHECK_WITH_DIAGNOSTICS(vm,
258+
DATA_CHECK_WITH_DIAGNOSTICS(
259+
vm,
256260
!ns.lookup(identifier, symbol),
257261
id2string(identifier) + " not found",
258262
location);

unit/Makefile

+1
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@ SRC += analyses/ai/ai.cpp \
2121
goto-programs/goto_program_declaration.cpp \
2222
goto-programs/goto_program_function_call.cpp \
2323
goto-programs/goto_program_goto_target.cpp \
24+
goto-programs/goto_program_symbol_type_table_consistency.cpp \
2425
goto-programs/goto_program_table_consistency.cpp \
2526
goto-programs/goto_trace_output.cpp \
2627
goto-symex/ssa_equation.cpp \
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,75 @@
1+
/*******************************************************************\
2+
3+
Module: Unit tests for goto_program::validate
4+
5+
Author: Diffblue Ltd.
6+
7+
\*******************************************************************/
8+
9+
#include <goto-programs/goto_function.h>
10+
#include <testing-utils/catch.hpp>
11+
#include <util/arith_tools.h>
12+
13+
SCENARIO(
14+
"Validation of consistent program/table pair (type-wise)",
15+
"[core][goto-programs][validate]")
16+
{
17+
GIVEN("A program with one assertion")
18+
{
19+
symbol_tablet symbol_table;
20+
const typet type1 = signedbv_typet(32);
21+
const typet type2 = signedbv_typet(64);
22+
symbolt symbol;
23+
irep_idt symbol_name = "a";
24+
symbol.name = symbol_name;
25+
symbol_exprt varx(symbol_name, type1);
26+
symbolt function_symbol;
27+
irep_idt function_name = "fun";
28+
function_symbol.name = function_name;
29+
30+
exprt val10 = from_integer(10, type1);
31+
binary_relation_exprt x_le_10(varx, ID_le, val10);
32+
33+
goto_functiont goto_function;
34+
auto &instructions = goto_function.body.instructions;
35+
instructions.emplace_back(goto_program_instruction_typet::ASSERT);
36+
instructions.back().make_assertion(x_le_10);
37+
instructions.back().function = function_symbol.name;
38+
39+
symbol_table.insert(function_symbol);
40+
WHEN("Symbol table has the right symbol type")
41+
{
42+
symbol.type = type1;
43+
symbol_table.insert(symbol);
44+
const namespacet ns(symbol_table);
45+
46+
THEN("The consistency check succeeds")
47+
{
48+
goto_function.validate(ns, validation_modet::INVARIANT);
49+
50+
REQUIRE(true);
51+
}
52+
}
53+
54+
WHEN("Symbol table has the wrong symbol type")
55+
{
56+
symbol.type = type2;
57+
symbol_table.insert(symbol);
58+
const namespacet ns(symbol_table);
59+
60+
THEN("The consistency check fails")
61+
{
62+
bool caught = false;
63+
try
64+
{
65+
goto_function.validate(ns, validation_modet::EXCEPTION);
66+
}
67+
catch(incorrect_goto_program_exceptiont &e)
68+
{
69+
caught = true;
70+
}
71+
REQUIRE(caught);
72+
}
73+
}
74+
}
75+
}

unit/goto-programs/goto_program_table_consistency.cpp

+1
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,7 @@ SCENARIO(
3737
symbol_table.insert(function_symbol);
3838
WHEN("Symbol table has the right symbol")
3939
{
40+
symbol.type = type;
4041
symbol_table.insert(symbol);
4142
const namespacet ns(symbol_table);
4243
THEN("The consistency check succeeds")

0 commit comments

Comments
 (0)