Skip to content

Commit 83fb9f0

Browse files
Petr BauchPetr Bauch
Petr Bauch
authored and
Petr Bauch
committed
Initial attempt at introducing well-formedness checking for SSA
Follows the #3123 skeleton with additional checks in SSA_stept.
1 parent 87bb3ed commit 83fb9f0

8 files changed

+88
-1
lines changed

src/cbmc/bmc.cpp

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -638,6 +638,10 @@ void bmct::perform_symbolic_execution(
638638
goto_symext::get_goto_functiont get_goto_function)
639639
{
640640
symex.symex_from_entry_point_of(get_goto_function, symex_symbol_table);
641+
if(options.get_bool_option("validate-ssa-equation"))
642+
{
643+
symex.validate(ns, validation_modet::INVARIANT);
644+
}
641645
INVARIANT(
642646
options.get_bool_option("paths") || path_storage.empty(),
643647
"Branch points were saved even though we should have been "

src/cbmc/cbmc_parse_options.cpp

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -536,6 +536,11 @@ int cbmc_parse_optionst::doit()
536536
goto_model.validate(ns, validation_modet::INVARIANT);
537537
}
538538

539+
if(cmdline.isset("validate-ssa-equation"))
540+
{
541+
options.set_option("validate-ssa-equation", true);
542+
}
543+
539544
return bmct::do_language_agnostic_bmc(
540545
path_strategy_chooser, options, goto_model, ui_message_handler);
541546
}
@@ -986,6 +991,9 @@ void cbmc_parse_optionst::help()
986991
// NOLINTNEXTLINE(whitespace/line_length)
987992
" --validate-goto-model enable additional well-formedness checks on the\n"
988993
" goto program\n"
994+
// NOLINTNEXTLINE(whitespace/line_length)
995+
" --validate-ssa-equation enable additional well-formedness checks on the\n"
996+
" SSA equation\n"
989997
HELP_GOTO_TRACE
990998
HELP_FLUSH
991999
" --verbosity # verbosity level\n"

src/cbmc/cbmc_parse_options.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -74,6 +74,7 @@ class optionst;
7474
"(localize-faults)(localize-faults-method):" \
7575
OPT_GOTO_TRACE \
7676
"(validate-goto-model)" \
77+
"(validate-ssa-equation)" \
7778
"(claim):(show-claims)(floatbv)(all-claims)(all-properties)" // legacy, and will eventually disappear // NOLINT(whitespace/line_length)
7879
// clang-format on
7980

src/goto-symex/goto_symex.h

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -512,6 +512,11 @@ class goto_symext
512512
"attempting to read remaining_vccs");
513513
return _remaining_vccs;
514514
}
515+
516+
void validate(const namespacet &ns, const validation_modet vm) const
517+
{
518+
target.validate(ns, vm);
519+
}
515520
};
516521

517522
#endif // CPROVER_GOTO_SYMEX_GOTO_SYMEX_H

src/goto-symex/symex_target_equation.cpp

Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -976,3 +976,48 @@ void symex_target_equationt::SSA_stept::output(std::ostream &out) const
976976

977977
out << "Guard: " << format(guard) << '\n';
978978
}
979+
980+
void symex_target_equationt::SSA_stept::validate(
981+
const namespacet &ns,
982+
const validation_modet vm) const
983+
{
984+
validate_expr_full_pick(guard, ns, vm);
985+
986+
switch(type)
987+
{
988+
case goto_trace_stept::typet::ASSERT:
989+
case goto_trace_stept::typet::ASSUME:
990+
case goto_trace_stept::typet::GOTO:
991+
case goto_trace_stept::typet::CONSTRAINT:
992+
validate_expr_full_pick(cond_expr, ns, vm);
993+
break;
994+
case goto_trace_stept::typet::ASSIGNMENT:
995+
case goto_trace_stept::typet::DECL:
996+
validate_expr_full_pick(ssa_lhs, ns, vm);
997+
validate_expr_full_pick(ssa_full_lhs, ns, vm);
998+
validate_expr_full_pick(original_full_lhs, ns, vm);
999+
validate_expr_full_pick(ssa_rhs, ns, vm);
1000+
break;
1001+
case goto_trace_stept::typet::INPUT:
1002+
case goto_trace_stept::typet::OUTPUT:
1003+
for(const auto &expr : io_args)
1004+
validate_expr_full_pick(expr, ns, vm);
1005+
for(const auto &expr : converted_io_args)
1006+
validate_expr_full_pick(expr, ns, vm);
1007+
break;
1008+
case goto_trace_stept::typet::FUNCTION_CALL:
1009+
for(const auto &expr : ssa_function_arguments)
1010+
validate_expr_full_pick(expr, ns, vm);
1011+
for(const auto &expr : converted_function_arguments)
1012+
validate_expr_full_pick(expr, ns, vm);
1013+
case goto_trace_stept::typet::FUNCTION_RETURN:
1014+
{
1015+
const symbolt *symbol;
1016+
DATA_CHECK(
1017+
!ns.lookup(function_identifier, symbol), "unknown function identifier");
1018+
}
1019+
break;
1020+
default:
1021+
break;
1022+
}
1023+
}

src/goto-symex/symex_target_equation.h

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,8 +15,8 @@ Author: Daniel Kroening, [email protected]
1515
#include <list>
1616
#include <iosfwd>
1717

18-
#include <util/invariant.h>
1918
#include <util/merge_irep.h>
19+
#include <util/validate.h>
2020

2121
#include <goto-programs/goto_program.h>
2222
#include <goto-programs/goto_trace.h>
@@ -268,6 +268,8 @@ class symex_target_equationt:public symex_targett
268268
std::ostream &out) const;
269269

270270
void output(std::ostream &out) const;
271+
272+
void validate(const namespacet &ns, const validation_modet vm) const;
271273
};
272274

273275
std::size_t count_assertions() const
@@ -324,6 +326,12 @@ class symex_target_equationt:public symex_targett
324326
return false;
325327
}
326328

329+
void validate(const namespacet &ns, const validation_modet vm) const
330+
{
331+
for(const SSA_stept &step : SSA_steps)
332+
step.validate(ns, vm);
333+
}
334+
327335
protected:
328336
// for enforcing sharing in the expressions stored
329337
merge_irept merge_irep;

src/util/ssa_expr.h

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -139,6 +139,21 @@ class ssa_exprt:public symbol_exprt
139139
/* Used to determine whether or not an identifier can be built
140140
* before trying and getting an exception */
141141
static bool can_build_identifier(const exprt &src);
142+
143+
void check(const validation_modet vm = validation_modet::INVARIANT) const
144+
{
145+
DATA_CHECK(!has_operands(), "SSA expression do not have operands");
146+
DATA_CHECK(id() == ID_symbol, "SSA expression symbols are symbols");
147+
DATA_CHECK(get_bool(ID_C_SSA_symbol), "wrong SSA expression ID");
148+
}
149+
150+
void validate(
151+
const namespacet &ns,
152+
const validation_modet vm = validation_modet::INVARIANT) const
153+
{
154+
check(vm);
155+
validate_expr_full_pick(get_original_expr(), ns, vm);
156+
}
142157
};
143158

144159
/*! \brief Cast a generic exprt to an \ref ssa_exprt

src/util/validate.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@ Author: Daniel Poetzl
1414
#include "exception_utils.h"
1515
#include "invariant.h"
1616
#include "irep.h"
17+
#include "namespace.h"
1718

1819
enum class validation_modet
1920
{

0 commit comments

Comments
 (0)