Skip to content

Commit 37e570b

Browse files
Petr BauchPetr Bauch
Petr Bauch
authored and
Petr Bauch
committed
Well-formedness check for goto instructions
Check that targets are well-formed and consistent.
1 parent 71d9cf1 commit 37e570b

File tree

4 files changed

+84
-5
lines changed

4 files changed

+84
-5
lines changed

src/goto-programs/goto_program.cpp

+9
Original file line numberDiff line numberDiff line change
@@ -683,6 +683,15 @@ void goto_programt::instructiont::validate(
683683
case NO_INSTRUCTION_TYPE:
684684
break;
685685
case GOTO:
686+
DATA_CHECK_WITH_DIAGNOSTICS(
687+
has_target(),
688+
"goto instruction expects at least one target",
689+
source_location);
690+
//get_target checks that targets.size()==1
691+
DATA_CHECK_WITH_DIAGNOSTICS(
692+
get_target()->is_target() && get_target()->target_number != 0,
693+
"goto target has to be a target",
694+
source_location);
686695
break;
687696
case ASSUME:
688697
DATA_CHECK_WITH_DIAGNOSTICS(

src/util/std_code.h

+6-4
Original file line numberDiff line numberDiff line change
@@ -1081,8 +1081,9 @@ class code_function_callt:public codet
10811081
return op2().operands();
10821082
}
10831083

1084-
static void check(const codet& code,
1085-
const validation_modet vm = validation_modet::INVARIANT)
1084+
static void check(
1085+
const codet &code,
1086+
const validation_modet vm = validation_modet::INVARIANT)
10861087
{
10871088
DATA_CHECK(
10881089
code.operands().size() == 3,
@@ -1180,8 +1181,9 @@ class code_returnt:public codet
11801181
return return_value().is_not_nil();
11811182
}
11821183

1183-
static void check(const codet &code,
1184-
const validation_modet vm = validation_modet::INVARIANT)
1184+
static void check(
1185+
const codet &code,
1186+
const validation_modet vm = validation_modet::INVARIANT)
11851187
{
11861188
DATA_CHECK(code.operands().size() == 1, "return must have one operand");
11871189
}

unit/Makefile

+2-1
Original file line numberDiff line numberDiff line change
@@ -16,9 +16,10 @@ 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_trace_output.cpp \
19-
goto-programs/goto_program_declaration.cpp \
2019
goto-programs/goto_program_assume.cpp \
20+
goto-programs/goto_program_goto_target.cpp \
2121
goto-programs/goto_program_function_call.cpp \
22+
goto-programs/goto_program_declaration.cpp \
2223
interpreter/interpreter.cpp \
2324
json/json_parser.cpp \
2425
path_strategies.cpp \
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,67 @@
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 well-formed goto codes",
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+
symbolt symbol;
22+
irep_idt symbol_name = "a";
23+
symbol.name = symbol_name;
24+
symbol_exprt varx(symbol_name, type1);
25+
exprt val10 = from_integer(10, type1);
26+
binary_relation_exprt x_le_10(varx, ID_le, val10);
27+
28+
goto_functiont goto_function;
29+
auto &instructions = goto_function.body.instructions;
30+
instructions.emplace_back(goto_program_instruction_typet::ASSERT);
31+
instructions.back().make_assertion(x_le_10);
32+
33+
instructions.emplace_back(goto_program_instruction_typet::GOTO);
34+
instructions.back().make_goto(instructions.begin());
35+
36+
symbol.type = type1;
37+
symbol_table.insert(symbol);
38+
namespacet ns(symbol_table);
39+
40+
WHEN("Target is a target")
41+
{
42+
instructions.front().target_number = 1;
43+
THEN("The consistency check succeeds")
44+
{
45+
goto_function.body.validate(ns, validation_modet::INVARIANT);
46+
REQUIRE(true);
47+
}
48+
}
49+
50+
WHEN("Target is not a target")
51+
{
52+
THEN("The consistency check fails")
53+
{
54+
bool caught = false;
55+
try
56+
{
57+
goto_function.body.validate(ns, validation_modet::EXCEPTION);
58+
}
59+
catch(incorrect_goto_program_exceptiont &e)
60+
{
61+
caught = true;
62+
}
63+
REQUIRE(caught);
64+
}
65+
}
66+
}
67+
}

0 commit comments

Comments
 (0)