Skip to content

Commit f08e23b

Browse files
authored
Merge pull request #3123 from danpoe/feature/well-formedness-checking
Skeleton for well-formedness checking of goto models [blocks: #3118, #3147, #3188, #3191, #3187, #3193]
2 parents d3d3cdb + d638ea7 commit f08e23b

31 files changed

+1024
-40
lines changed

src/cbmc/cbmc_parse_options.cpp

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -530,6 +530,11 @@ int cbmc_parse_optionst::doit()
530530
if(set_properties())
531531
return CPROVER_EXIT_SET_PROPERTIES_FAILED;
532532

533+
if(cmdline.isset("validate-goto-model"))
534+
{
535+
goto_model.validate(validation_modet::INVARIANT);
536+
}
537+
533538
return bmct::do_language_agnostic_bmc(
534539
path_strategy_chooser, options, goto_model, ui_message_handler);
535540
}
@@ -977,6 +982,8 @@ void cbmc_parse_optionst::help()
977982
" --xml-ui use XML-formatted output\n"
978983
" --xml-interface bi-directional XML interface\n"
979984
" --json-ui use JSON-formatted output\n"
985+
// NOLINTNEXTLINE(whitespace/line_length)
986+
HELP_VALIDATE
980987
HELP_GOTO_TRACE
981988
HELP_FLUSH
982989
" --verbosity # verbosity level\n"

src/cbmc/cbmc_parse_options.h

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,9 +12,10 @@ Author: Daniel Kroening, [email protected]
1212
#ifndef CPROVER_CBMC_CBMC_PARSE_OPTIONS_H
1313
#define CPROVER_CBMC_CBMC_PARSE_OPTIONS_H
1414

15-
#include <util/ui_message.h>
1615
#include <util/parse_options.h>
1716
#include <util/timestamper.h>
17+
#include <util/ui_message.h>
18+
#include <util/validation_interface.h>
1819

1920
#include <langapi/language.h>
2021

@@ -73,6 +74,7 @@ class optionst;
7374
OPT_FLUSH \
7475
"(localize-faults)(localize-faults-method):" \
7576
OPT_GOTO_TRACE \
77+
OPT_VALIDATE \
7678
"(claim):(show-claims)(floatbv)(all-claims)(all-properties)" // legacy, and will eventually disappear // NOLINT(whitespace/line_length)
7779
// clang-format on
7880

src/goto-analyzer/goto_analyzer_parse_options.cpp

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -406,6 +406,11 @@ int goto_analyzer_parse_optionst::doit()
406406
if(process_goto_program(options))
407407
return CPROVER_EXIT_INTERNAL_ERROR;
408408

409+
if(cmdline.isset("validate-goto-model"))
410+
{
411+
goto_model.validate(validation_modet::INVARIANT);
412+
}
413+
409414
// show it?
410415
if(cmdline.isset("show-symbol-table"))
411416
{
@@ -875,6 +880,7 @@ void goto_analyzer_parse_optionst::help()
875880
HELP_GOTO_CHECK
876881
"\n"
877882
"Other options:\n"
883+
HELP_VALIDATE
878884
" --version show version and exit\n"
879885
HELP_FLUSH
880886
HELP_TIMESTAMP

src/goto-analyzer/goto_analyzer_parse_options.h

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -101,9 +101,10 @@ Author: Daniel Kroening, [email protected]
101101
#ifndef CPROVER_GOTO_ANALYZER_GOTO_ANALYZER_PARSE_OPTIONS_H
102102
#define CPROVER_GOTO_ANALYZER_GOTO_ANALYZER_PARSE_OPTIONS_H
103103

104-
#include <util/ui_message.h>
105104
#include <util/parse_options.h>
106105
#include <util/timestamper.h>
106+
#include <util/ui_message.h>
107+
#include <util/validation_interface.h>
107108

108109
#include <langapi/language.h>
109110

@@ -148,6 +149,7 @@ class optionst;
148149
"(show)(verify)(simplify):" \
149150
"(location-sensitive)(concurrent)" \
150151
"(no-simplify-slicing)" \
152+
OPT_VALIDATE \
151153
// clang-format on
152154

153155
class goto_analyzer_parse_optionst:

src/goto-instrument/goto_instrument_parse_options.cpp

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -125,8 +125,27 @@ int goto_instrument_parse_optionst::doit()
125125

126126
get_goto_program();
127127

128+
{
129+
const bool validate_only = cmdline.isset("validate-goto-binary");
130+
131+
if(validate_only || cmdline.isset("validate-goto-model"))
132+
{
133+
goto_model.validate(validation_modet::EXCEPTION);
134+
135+
if(validate_only)
136+
{
137+
return CPROVER_EXIT_SUCCESS;
138+
}
139+
}
140+
}
141+
128142
instrument_goto_program();
129143

144+
if(cmdline.isset("validate-goto-model"))
145+
{
146+
goto_model.validate(validation_modet::INVARIANT);
147+
}
148+
130149
{
131150
bool unwind_given=cmdline.isset("unwind");
132151
bool unwindset_given=cmdline.isset("unwindset");
@@ -1572,6 +1591,10 @@ void goto_instrument_parse_optionst::help()
15721591
" --show-local-safe-pointers show pointer expressions that are trivially dominated by a not-null check\n" // NOLINT(*)
15731592
" --show-safe-dereferences show pointer expressions that are trivially dominated by a not-null check\n" // NOLINT(*)
15741593
" *and* used as a dereference operand\n" // NOLINT(*)
1594+
HELP_VALIDATE
1595+
// NOLINTNEXTLINE(whitespace/line_length)
1596+
" --validate-goto-binary check the well-formedness of the passed in goto\n"
1597+
" binary and then exit\n"
15751598
"\n"
15761599
"Safety checks:\n"
15771600
" --no-assertions ignore user assertions\n"

src/goto-instrument/goto_instrument_parse_options.h

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,9 +12,10 @@ Author: Daniel Kroening, [email protected]
1212
#ifndef CPROVER_GOTO_INSTRUMENT_GOTO_INSTRUMENT_PARSE_OPTIONS_H
1313
#define CPROVER_GOTO_INSTRUMENT_GOTO_INSTRUMENT_PARSE_OPTIONS_H
1414

15-
#include <util/ui_message.h>
1615
#include <util/parse_options.h>
1716
#include <util/timestamper.h>
17+
#include <util/ui_message.h>
18+
#include <util/validation_interface.h>
1819

1920
#include <goto-programs/class_hierarchy.h>
2021
#include <goto-programs/goto_functions.h>
@@ -101,6 +102,8 @@ Author: Daniel Kroening, [email protected]
101102
OPT_GOTO_PROGRAM_STATS \
102103
"(show-local-safe-pointers)(show-safe-dereferences)" \
103104
OPT_REPLACE_CALLS \
105+
"(validate-goto-binary)" \
106+
OPT_VALIDATE \
104107
// empty last line
105108

106109
// clang-format on

src/goto-programs/goto_function.h

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -110,6 +110,16 @@ class goto_functiont
110110
parameter_identifiers = std::move(other.parameter_identifiers);
111111
return *this;
112112
}
113+
114+
/// Check that the goto function is well-formed
115+
///
116+
/// The validation mode indicates whether well-formedness check failures are
117+
/// reported via DATA_INVARIANT violations or exceptions.
118+
void validate(const namespacet &ns, const validation_modet vm) const
119+
{
120+
body.validate(ns, vm);
121+
validate_full_type(type, ns, vm);
122+
}
113123
};
114124

115125
void get_local_identifiers(const goto_functiont &, std::set<irep_idt> &dest);

src/goto-programs/goto_functions.h

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -117,6 +117,19 @@ class goto_functionst
117117

118118
std::vector<function_mapt::const_iterator> sorted() const;
119119
std::vector<function_mapt::iterator> sorted();
120+
121+
/// Check that the goto functions are well-formed
122+
///
123+
/// The validation mode indicates whether well-formedness check failures are
124+
/// reported via DATA_INVARIANT violations or exceptions.
125+
void validate(const namespacet &ns, const validation_modet vm) const
126+
{
127+
for(const auto &entry : function_map)
128+
{
129+
const goto_functiont &goto_function = entry.second;
130+
goto_function.validate(ns, vm);
131+
}
132+
}
120133
};
121134

122135
#define Forall_goto_functions(it, functions) \

src/goto-programs/goto_model.h

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -89,6 +89,18 @@ class goto_modelt : public abstract_goto_modelt
8989
return goto_functions.function_map.find(id) !=
9090
goto_functions.function_map.end();
9191
}
92+
93+
/// Check that the goto model is well-formed
94+
///
95+
/// The validation mode indicates whether well-formedness check failures are
96+
/// reported via DATA_INVARIANT violations or exceptions.
97+
void validate(const validation_modet vm) const
98+
{
99+
symbol_table.validate();
100+
101+
const namespacet ns(symbol_table);
102+
goto_functions.validate(ns, vm);
103+
}
92104
};
93105

94106
/// Class providing the abstract GOTO model interface onto an unrelated

src/goto-programs/goto_program.cpp

Lines changed: 57 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@ Author: Daniel Kroening, [email protected]
1515
#include <iomanip>
1616

1717
#include <util/std_expr.h>
18+
#include <util/validate.h>
1819

1920
#include <langapi/language_util.h>
2021

@@ -668,6 +669,62 @@ bool goto_programt::instructiont::equals(const instructiont &other) const
668669
// clang-format on
669670
}
670671

672+
void goto_programt::instructiont::validate(
673+
const namespacet &ns,
674+
const validation_modet vm) const
675+
{
676+
validate_full_code(code, ns, vm);
677+
validate_full_expr(guard, ns, vm);
678+
679+
switch(type)
680+
{
681+
case NO_INSTRUCTION_TYPE:
682+
break;
683+
case GOTO:
684+
break;
685+
case ASSUME:
686+
break;
687+
case ASSERT:
688+
break;
689+
case OTHER:
690+
break;
691+
case SKIP:
692+
break;
693+
case START_THREAD:
694+
break;
695+
case END_THREAD:
696+
break;
697+
case LOCATION:
698+
break;
699+
case END_FUNCTION:
700+
break;
701+
case ATOMIC_BEGIN:
702+
break;
703+
case ATOMIC_END:
704+
break;
705+
case RETURN:
706+
break;
707+
case ASSIGN:
708+
DATA_CHECK(
709+
code.get_statement() == ID_assign,
710+
"assign instruction should contain an assign statement");
711+
DATA_CHECK(targets.empty(), "assign instruction should not have a target");
712+
break;
713+
case DECL:
714+
break;
715+
case DEAD:
716+
break;
717+
case FUNCTION_CALL:
718+
break;
719+
case THROW:
720+
break;
721+
case CATCH:
722+
break;
723+
case INCOMPLETE_GOTO:
724+
break;
725+
}
726+
}
727+
671728
bool goto_programt::equals(const goto_programt &other) const
672729
{
673730
if(instructions.size() != other.instructions.size())

0 commit comments

Comments
 (0)