Skip to content

Commit ea8c694

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 b0d1a47 commit ea8c694

8 files changed

+107
-2
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: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -395,6 +395,11 @@ void cbmc_parse_optionst::get_command_line_options(optionst &options)
395395
"symex-coverage-report",
396396
cmdline.get_value("symex-coverage-report"));
397397

398+
if(cmdline.isset("validate-ssa-equation"))
399+
{
400+
options.set_option("validate-ssa-equation", true);
401+
}
402+
398403
PARSE_OPTIONS_GOTO_TRACE(cmdline, options);
399404
}
400405

src/goto-symex/goto_symex.h

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -518,6 +518,11 @@ class goto_symext
518518
"attempting to read remaining_vccs");
519519
return _remaining_vccs;
520520
}
521+
522+
void validate(const namespacet &ns, const validation_modet vm) const
523+
{
524+
target.validate(ns, vm);
525+
}
521526
};
522527

523528
#endif // CPROVER_GOTO_SYMEX_GOTO_SYMEX_H

src/goto-symex/symex_target_equation.cpp

Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -974,3 +974,57 @@ void symex_target_equationt::SSA_stept::output(std::ostream &out) const
974974

975975
out << "Guard: " << format(guard) << '\n';
976976
}
977+
978+
/// Check that the SSA step is well-formed
979+
/// \param ns namespace to lookup identifiers
980+
/// \param vm validation mode to be used for reporting failures
981+
void symex_target_equationt::SSA_stept::validate(
982+
const namespacet &ns,
983+
const validation_modet vm) const
984+
{
985+
validate_full_expr(guard, ns, vm);
986+
987+
switch(type)
988+
{
989+
case goto_trace_stept::typet::ASSERT:
990+
case goto_trace_stept::typet::ASSUME:
991+
case goto_trace_stept::typet::GOTO:
992+
case goto_trace_stept::typet::CONSTRAINT:
993+
validate_full_expr(cond_expr, ns, vm);
994+
break;
995+
case goto_trace_stept::typet::ASSIGNMENT:
996+
case goto_trace_stept::typet::DECL:
997+
validate_full_expr(ssa_lhs, ns, vm);
998+
validate_full_expr(ssa_full_lhs, ns, vm);
999+
validate_full_expr(original_full_lhs, ns, vm);
1000+
validate_full_expr(ssa_rhs, ns, vm);
1001+
base_type_eq(ssa_lhs.get_original_expr(), ssa_rhs, ns);
1002+
break;
1003+
case goto_trace_stept::typet::INPUT:
1004+
case goto_trace_stept::typet::OUTPUT:
1005+
for(const auto &expr : io_args)
1006+
validate_full_expr(expr, ns, vm);
1007+
break;
1008+
case goto_trace_stept::typet::FUNCTION_CALL:
1009+
for(const auto &expr : ssa_function_arguments)
1010+
validate_full_expr(expr, ns, vm);
1011+
case goto_trace_stept::typet::FUNCTION_RETURN:
1012+
{
1013+
const symbolt *symbol;
1014+
DATA_CHECK(
1015+
called_function.empty() || !ns.lookup(called_function, symbol),
1016+
"unknown function identifier " + id2string(called_function));
1017+
}
1018+
break;
1019+
case goto_trace_stept::typet::NONE:
1020+
case goto_trace_stept::typet::LOCATION:
1021+
case goto_trace_stept::typet::DEAD:
1022+
case goto_trace_stept::typet::SHARED_READ:
1023+
case goto_trace_stept::typet::SHARED_WRITE:
1024+
case goto_trace_stept::typet::SPAWN:
1025+
case goto_trace_stept::typet::MEMORY_BARRIER:
1026+
case goto_trace_stept::typet::ATOMIC_BEGIN:
1027+
case goto_trace_stept::typet::ATOMIC_END:
1028+
break;
1029+
}
1030+
}

src/goto-symex/symex_target_equation.h

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -267,6 +267,8 @@ class symex_target_equationt:public symex_targett
267267
std::ostream &out) const;
268268

269269
void output(std::ostream &out) const;
270+
271+
void validate(const namespacet &ns, const validation_modet vm) const;
270272
};
271273

272274
std::size_t count_assertions() const
@@ -323,6 +325,12 @@ class symex_target_equationt:public symex_targett
323325
return false;
324326
}
325327

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

src/util/ssa_expr.h

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -139,6 +139,25 @@ 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+
static void check(
144+
const exprt &expr,
145+
const validation_modet vm = validation_modet::INVARIANT)
146+
{
147+
DATA_CHECK(!expr.has_operands(), "SSA expression should not have operands");
148+
DATA_CHECK(expr.id() == ID_symbol, "SSA expression symbols are symbols");
149+
DATA_CHECK(expr.get_bool(ID_C_SSA_symbol), "wrong SSA expression ID");
150+
}
151+
152+
static void validate(
153+
const exprt &expr,
154+
const namespacet &ns,
155+
const validation_modet vm = validation_modet::INVARIANT)
156+
{
157+
check(expr, vm);
158+
validate_full_expr(
159+
static_cast<const exprt &>(expr.find(ID_expression)), ns, vm);
160+
}
142161
};
143162

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

src/util/validate_expressions.cpp

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@ Author: Daniel Poetzl
1515

1616
#include "expr.h"
1717
#include "namespace.h"
18+
#include "ssa_expr.h"
1819
#include "std_expr.h"
1920
#include "validate.h"
2021

@@ -32,6 +33,10 @@ void call_on_expr(const exprt &expr, Args &&... args)
3233
{
3334
CALL_ON_EXPR(plus_exprt);
3435
}
36+
else if(expr.get_bool(ID_C_SSA_symbol))
37+
{
38+
CALL_ON_EXPR(ssa_exprt);
39+
}
3540
else
3641
{
3742
#ifdef REPORT_UNIMPLEMENTED_EXPRESSION_CHECKS

src/util/validation_interface.h

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -9,11 +9,16 @@ Author: Daniel Poetzl
99
#ifndef CPROVER_UTIL_VALIDATION_INTERFACE_H
1010
#define CPROVER_UTIL_VALIDATION_INTERFACE_H
1111

12-
#define OPT_VALIDATE "(validate-goto-model)"
12+
#define OPT_VALIDATE \
13+
"(validate-goto-model)" \
14+
"(validate-ssa-equation)"
1315

1416
#define HELP_VALIDATE \
1517
" --validate-goto-model enable additional well-formedness checks on " \
1618
"the\n" \
17-
" goto program\n"
19+
" goto program\n" \
20+
" --validate-ssa-equation enable additional well-formedness checks on " \
21+
"the\n" \
22+
" SSA representation\n"
1823

1924
#endif /* CPROVER_UTIL_VALIDATION_INTERFACE_H */

0 commit comments

Comments
 (0)