Skip to content

Commit 967804f

Browse files
Petr BauchPetr Bauch
Petr Bauch
authored and
Petr Bauch
committed
Add well-formedness test for assume/assert
Two simple tests are added: 1) targets are empty, 2) the guard evaluates to a Boolean. The second test is a case-analysis of the expression id.
1 parent 29b76b4 commit 967804f

File tree

2 files changed

+86
-18
lines changed

2 files changed

+86
-18
lines changed

src/goto-programs/goto_program.cpp

Lines changed: 85 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -668,6 +668,91 @@ bool goto_programt::instructiont::equals(const instructiont &other) const
668668
// clang-format on
669669
}
670670

671+
void goto_programt::instructiont::validate(
672+
const namespacet &ns,
673+
const validation_modet vm) const
674+
{
675+
validate_code_full_pick(code, ns, vm);
676+
validate_expr_full_pick(guard, ns, vm);
677+
678+
auto evaluates_to_boolean = [](const exprt &e) -> bool {
679+
//typecast to Boolean
680+
if(e.id() == ID_typecast)
681+
return e.type().id() == ID_bool;
682+
683+
//Boolean constants
684+
if(e.id() == ID_true || e.id() == ID_false)
685+
return true;
686+
if(e.id() == ID_constant && e.type().id() == ID_bool)
687+
return true;
688+
689+
//Symbols
690+
if(e.id() == ID_symbol)
691+
{
692+
if(e.type().id() == ID_code) //function call
693+
return to_code_type(e.type()).return_type().id() == ID_bool;
694+
else //Boolean variable
695+
return e.type().id() == ID_bool;
696+
}
697+
698+
//arithmetic relations
699+
if(e.id() == ID_equal || e.id() == ID_notequal)
700+
return true;
701+
if(e.id() == ID_ieee_float_equal || e.id() == ID_ieee_float_notequal)
702+
return true;
703+
if(e.id() == ID_ge || e.id() == ID_gt)
704+
return true;
705+
if(e.id() == ID_le || e.id() == ID_lt)
706+
return true;
707+
708+
//propositional operators
709+
if(
710+
e.id() == ID_not || e.id() == ID_and || e.id() == ID_or ||
711+
e.id() == ID_implies)
712+
return true;
713+
if(e.id() == ID_exists || e.id() == ID_forall)
714+
return true;
715+
716+
//weird
717+
if(
718+
e.id() == ID_isfinite || e.id() == ID_isnormal || e.id() == ID_isinf ||
719+
e.id() == ID_isnan)
720+
return true;
721+
722+
return false;
723+
};
724+
725+
switch(type)
726+
{
727+
case ASSIGN:
728+
DATA_CHECK(
729+
code.get_statement() == ID_assign,
730+
"assign instruction should contain an assign statement");
731+
DATA_CHECK(targets.empty(), "assign instruction should not have a target");
732+
break;
733+
case ASSUME:
734+
DATA_CHECK_WITH_DIAGNOSTICS(
735+
targets.empty(),
736+
"assume instruction should not have a target",
737+
source_location);
738+
DATA_CHECK_WITH_DIAGNOSTICS(
739+
evaluates_to_boolean(guard),
740+
"assuming non-boolean condition\n" + guard.pretty(),
741+
source_location);
742+
case ASSERT:
743+
DATA_CHECK_WITH_DIAGNOSTICS(
744+
targets.empty(),
745+
"assert instruction should not have a target",
746+
source_location);
747+
DATA_CHECK_WITH_DIAGNOSTICS(
748+
evaluates_to_boolean(guard),
749+
"asserting non-boolean condition\n" + guard.pretty(),
750+
source_location);
751+
default:
752+
break;
753+
}
754+
}
755+
671756
bool goto_programt::equals(const goto_programt &other) const
672757
{
673758
if(instructions.size() != other.instructions.size())

src/goto-programs/goto_program.h

Lines changed: 1 addition & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -404,24 +404,7 @@ class goto_programt
404404
///
405405
/// The validation mode indicates whether well-formedness check failures are
406406
/// reported via DATA_INVARIANT violations or exceptions.
407-
void validate(const namespacet &ns, const validation_modet vm) const
408-
{
409-
validate_code_full_pick(code, ns, vm);
410-
validate_expr_full_pick(guard, ns, vm);
411-
412-
switch(type)
413-
{
414-
case ASSIGN:
415-
DATA_CHECK(
416-
code.get_statement() == ID_assign,
417-
"assign instruction should contain an assign statement");
418-
DATA_CHECK(
419-
targets.empty(), "assign instruction should not have a target");
420-
break;
421-
default:
422-
break;
423-
}
424-
}
407+
void validate(const namespacet &ns, const validation_modet vm) const;
425408
};
426409

427410
// Never try to change this to vector-we mutate the list while iterating

0 commit comments

Comments
 (0)