Skip to content

Commit 6c6e5ca

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 51aa20e commit 6c6e5ca

File tree

4 files changed

+99
-2
lines changed

4 files changed

+99
-2
lines changed

src/goto-programs/goto_program.cpp

Lines changed: 22 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -677,9 +677,9 @@ void goto_programt::instructiont::validate(
677677
validate_full_code(code, ns, vm);
678678
validate_full_expr(guard, ns, vm);
679679

680-
const symbolt *symbol;
680+
const symbolt *table_symbol;
681681
DATA_CHECK_WITH_DIAGNOSTICS(
682-
!ns.lookup(function, symbol),
682+
!ns.lookup(function, table_symbol),
683683
id2string(function) + " not found",
684684
source_location);
685685

@@ -691,6 +691,24 @@ void goto_programt::instructiont::validate(
691691
find_symbol_in_namespace(e, source_location, ns, vm);
692692
};
693693

694+
auto &current_source_location = source_location;
695+
auto type_finder =
696+
[&ns, vm, &table_symbol, &current_source_location](const exprt &e) {
697+
if(e.id() == ID_symbol)
698+
{
699+
const auto &goto_symbol_expr = to_symbol_expr(e);
700+
const auto &goto_id = goto_symbol_expr.get_identifier();
701+
702+
if(!ns.lookup(goto_id, table_symbol))
703+
DATA_CHECK_WITH_DIAGNOSTICS(
704+
base_type_eq(goto_symbol_expr.type(), table_symbol->type, ns),
705+
id2string(goto_id) + " type inconsistency\n" +
706+
"goto program type: " + goto_symbol_expr.type().id_string() +
707+
"\n" + "symbol table type: " + table_symbol->type.id_string(),
708+
current_source_location);
709+
}
710+
};
711+
694712
switch(type)
695713
{
696714
case NO_INSTRUCTION_TYPE:
@@ -701,6 +719,7 @@ void goto_programt::instructiont::validate(
701719
break;
702720
case ASSERT:
703721
guard.visit(expr_symbol_finder);
722+
guard.visit(type_finder);
704723
break;
705724
case OTHER:
706725
break;
@@ -732,6 +751,7 @@ void goto_programt::instructiont::validate(
732751
break;
733752
case FUNCTION_CALL:
734753
code.visit(expr_symbol_finder);
754+
code.visit(type_finder);
735755
break;
736756
case THROW:
737757
break;

unit/Makefile

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@ SRC += analyses/ai/ai.cpp \
1616
analyses/does_remove_const/is_type_at_least_as_const_as.cpp \
1717
compound_block_locations.cpp \
1818
goto-programs/goto_model_function_type_consistency.cpp \
19+
goto-programs/goto_program_symbol_type_table_consistency.cpp \
1920
goto-programs/goto_program_table_consistency.cpp \
2021
goto-programs/goto_trace_output.cpp \
2122
interpreter/interpreter.cpp \
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+
}

unit/goto-programs/goto_program_table_consistency.cpp

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