Skip to content

Commit bbeb694

Browse files
Petr BauchPetr Bauch
authored andcommitted
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 bbeb694

11 files changed

+135
-6
lines changed

src/goto-programs/goto_functions.h

Lines changed: 1 addition & 0 deletions
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

Lines changed: 23 additions & 1 deletion
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

Lines changed: 8 additions & 4 deletions
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

Lines changed: 1 addition & 0 deletions
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 \

unit/goto-programs/goto_program_assume.cpp

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,9 @@ SCENARIO(
1919
symbol_tablet symbol_table;
2020
const typet type1 = signedbv_typet(32);
2121
symbolt symbol;
22+
symbolt fun_symbol;
23+
irep_idt fun_name = "foo";
24+
fun_symbol.name = fun_name;
2225
irep_idt symbol_name = "a";
2326
symbol.name = symbol_name;
2427
symbol_exprt varx(symbol_name, type1);
@@ -31,8 +34,10 @@ SCENARIO(
3134

3235
symbol.type = type1;
3336
symbol_table.insert(symbol);
37+
symbol_table.insert(fun_symbol);
3438
namespacet ns(symbol_table);
3539
instructions.back().make_assertion(x_le_10);
40+
instructions.back().function = fun_name;
3641

3742
WHEN("Instruction has no targets")
3843
{

unit/goto-programs/goto_program_dead.cpp

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,10 @@ SCENARIO(
1919
symbol_tablet symbol_table;
2020
const signedbv_typet type1(32);
2121

22+
symbolt fun_symbol;
23+
irep_idt fun_name = "foo";
24+
fun_symbol.name = fun_name;
25+
2226
symbolt var_symbol;
2327
irep_idt var_symbol_name = "a";
2428
var_symbol.type = type1;
@@ -31,6 +35,8 @@ SCENARIO(
3135
code_deadt removal(var_a);
3236
instructions.back().make_dead();
3337
instructions.back().code = removal;
38+
instructions.back().function = fun_name;
39+
symbol_table.insert(fun_symbol);
3440

3541
WHEN("Removing known symbol")
3642
{

unit/goto-programs/goto_program_declaration.cpp

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,10 @@ SCENARIO(
1919
symbol_tablet symbol_table;
2020
const signedbv_typet type1(32);
2121

22+
symbolt fun_symbol;
23+
irep_idt fun_name = "foo";
24+
fun_symbol.name = fun_name;
25+
2226
symbolt var_symbol;
2327
irep_idt var_symbol_name = "a";
2428
var_symbol.type = type1;
@@ -30,6 +34,8 @@ SCENARIO(
3034
instructions.emplace_back(goto_program_instruction_typet::DECL);
3135
code_declt declaration(var_a);
3236
instructions.back().make_decl(declaration);
37+
instructions.back().function = fun_name;
38+
symbol_table.insert(fun_symbol);
3339

3440
WHEN("Declaring known symbol")
3541
{

unit/goto-programs/goto_program_function_call.cpp

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -34,15 +34,16 @@ SCENARIO(
3434
symbolt fun_symbol;
3535
irep_idt fun_symbol_name = "foo";
3636
fun_symbol.name = fun_symbol_name;
37+
fun_symbol.type = code_type;
3738
symbol_exprt fun_foo(fun_symbol_name, code_type);
3839

3940
goto_functiont goto_function;
4041
auto &instructions = goto_function.body.instructions;
4142
instructions.emplace_back(goto_program_instruction_typet::FUNCTION_CALL);
43+
instructions.back().function = fun_symbol_name;
4244

4345
var_symbol.type = type1;
4446
var_symbol2.type = type2;
45-
fun_symbol.type = type1;
4647
symbol_table.insert(var_symbol);
4748
symbol_table.insert(var_symbol2);
4849
symbol_table.insert(fun_symbol);

unit/goto-programs/goto_program_goto_target.cpp

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,10 @@ SCENARIO(
1818
{
1919
symbol_tablet symbol_table;
2020
const typet type1 = signedbv_typet(32);
21+
symbolt fun_symbol;
22+
irep_idt fun_name = "foo";
23+
fun_symbol.name = fun_name;
24+
2125
symbolt symbol;
2226
irep_idt symbol_name = "a";
2327
symbol.name = symbol_name;
@@ -29,12 +33,15 @@ SCENARIO(
2933
auto &instructions = goto_function.body.instructions;
3034
instructions.emplace_back(goto_program_instruction_typet::ASSERT);
3135
instructions.back().make_assertion(x_le_10);
36+
instructions.back().function = fun_name;
3237

3338
instructions.emplace_back(goto_program_instruction_typet::GOTO);
3439
instructions.back().make_goto(instructions.begin());
40+
instructions.back().function = fun_name;
3541

3642
symbol.type = type1;
3743
symbol_table.insert(symbol);
44+
symbol_table.insert(fun_symbol);
3845
namespacet ns(symbol_table);
3946

4047
WHEN("Target is a target")
Lines changed: 75 additions & 0 deletions
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+
}

0 commit comments

Comments
 (0)