-
Notifications
You must be signed in to change notification settings - Fork 273
Well-formedness checking of SSA equation [depends on #3480] #3287
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Looks good so far, a few minor comments
src/cbmc/cbmc_parse_options.cpp
Outdated
if(cmdline.isset("validate-ssa-equation")) | ||
{ | ||
options.set_option("validate-ssa-equation", true); | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This should best be put in cbmc_parse_optionst::get_command_line_options()
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done.
DATA_CHECK(!has_operands(), "SSA expression do not have operands"); | ||
DATA_CHECK(id() == ID_symbol, "SSA expression symbols are symbols"); | ||
DATA_CHECK(get_bool(ID_C_SSA_symbol), "wrong SSA expression ID"); | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Btw, these methods have now become static methods that take the parent type in the recent changes to PR #3123. So that would then become static void check(const exprt &expr, const validation_modet vm)
.
We should also add a case for SSA_exprt
to call_on_expr()
in validate_expressions.cpp
.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done.
src/util/ssa_expr.h
Outdated
|
||
void check(const validation_modet vm = validation_modet::INVARIANT) const | ||
{ | ||
DATA_CHECK(!has_operands(), "SSA expression do not have operands"); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Nit: According to the coding standard (cbmc/CODING_STANDARD.md
), if possible the messages in invariants should be "should" statements that describe what should hold, e.g. "SSA expression should have operands".
@@ -125,8 +125,29 @@ int goto_instrument_parse_optionst::doit() | |||
|
|||
get_goto_program(); | |||
|
|||
{ | |||
const bool b = cmdline.isset("validate-goto-binary"); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
What does b
stand for?
@@ -1572,6 +1593,12 @@ void goto_instrument_parse_optionst::help() | |||
" --show-local-safe-pointers show pointer expressions that are trivially dominated by a not-null check\n" // NOLINT(*) | |||
" --show-safe-dereferences show pointer expressions that are trivially dominated by a not-null check\n" // NOLINT(*) | |||
" *and* used as a dereference operand\n" // NOLINT(*) | |||
// NOLINTNEXTLINE(whitespace/line_length) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I suggest to provide HELP_VALIDATION
and OPT_VALIDATION
to avoid code duplication.
src/util/validate.h
Outdated
} | ||
}; | ||
|
||
#endif /* CPROVER_UTIL_VALIDATE_H */ |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
// preferred
src/util/validate_code.h
Outdated
const namespacet &ns, | ||
const validation_modet vm); | ||
|
||
#endif /* CPROVER_UTIL_VALIDATE_CODE_H */ |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
// preferred
src/util/validate_expressions.h
Outdated
const namespacet &ns, | ||
const validation_modet vm); | ||
|
||
#endif /* CPROVER_UTIL_VALIDATE_EXPRESSIONS_H */ |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
// preferred
src/util/validate_types.h
Outdated
const namespacet &ns, | ||
const validation_modet vm); | ||
|
||
#endif /* CPROVER_UTIL_VALIDATE_TYPES_H */ |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
// preferred
src/util/validate_types.h
Outdated
class namespacet; | ||
enum class validation_modet; | ||
|
||
void check_type_pick(const typet &type, const validation_modet vm); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Parameter names could be omitted in the declarations. It's obvious what they are.
src/cbmc/cbmc_parse_options.cpp
Outdated
{ | ||
const namespacet ns(goto_model.symbol_table); | ||
goto_model.validate(ns, validation_modet::INVARIANT); | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is this from a previous PR as it doesn't match the description of the PR?
@@ -406,6 +406,12 @@ int goto_analyzer_parse_optionst::doit() | |||
if(process_goto_program(options)) | |||
return CPROVER_EXIT_INTERNAL_ERROR; | |||
|
|||
if(cmdline.isset("validate-goto-model")) | |||
{ |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
So, I'm opinionated but ... why add this option to every program? Why not just add it to goto-instrument? If it's the same check (and eventually everyone will do it on program load) why do we need the extra option everywhere?
4c66ee5
to
e5349cc
Compare
e5349cc
to
971df90
Compare
971df90
to
ea8c694
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Some comments below, but the biggest item that I'd like to see added/changed is the current check_renaming
of goto_symex_state.cpp to be moved into the validation framework and thus only done when validation is enabled.
validate_full_expr(ssa_full_lhs, ns, vm); | ||
validate_full_expr(original_full_lhs, ns, vm); | ||
validate_full_expr(ssa_rhs, ns, vm); | ||
base_type_eq(ssa_lhs.get_original_expr(), ssa_rhs, ns); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This has no effect?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Oh, my bad: this was intended to check that lhs
and rhs
have the same type. Should be fixed now.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
✔️
Passed Diffblue compatibility checks (cbmc commit: ea8c694).
Build URL: https://travis-ci.com/diffblue/test-gen/builds/91355754
@tautschnig regarding the |
src/goto-symex/goto_symex.h
Outdated
@@ -76,7 +76,8 @@ class goto_symext | |||
path_storage(path_storage), | |||
path_segment_vccs(0), | |||
_total_vccs(std::numeric_limits<unsigned>::max()), | |||
_remaining_vccs(std::numeric_limits<unsigned>::max()) | |||
_remaining_vccs(std::numeric_limits<unsigned>::max()), | |||
global_validation_mode(validation_modet::IGNORE) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Wouldn't it be possible to look at options
instead and store that in a Boolean, as is done for several other entries in options
above?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Well I can use options
in goto_symext
but not in statet
(unless I pass it there somehow).
src/goto-symex/goto_symex_state.cpp
Outdated
@@ -241,9 +217,10 @@ void goto_symex_statet::assignment( | |||
// the type might need renaming | |||
rename(lhs.type(), l1_identifier, ns); | |||
lhs.update_type(); | |||
assert_l1_renaming(lhs); | |||
const validation_modet vm = global_validation_mode; | |||
DATA_CHECK(!check_renaming_l1(lhs), "lhs renaming failed on l1"); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
What I'd do here is something along the lines of !validation_enabled || !check_renaming_l1(lhs)
to avoid changing the validation_modet
enum.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I reverted the new validation mode. I'm not sure if you're suggesting not to use DATA_CHECK
at all and just call the regular invariants, or not. Have a look at the new version.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Many thanks for the update!
src/goto-symex/goto_symex.h
Outdated
@@ -524,7 +524,7 @@ class goto_symext | |||
{ | |||
target.validate(ns, vm); | |||
} | |||
validation_modet global_validation_mode; | |||
bool run_validation_checks; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
With the exception that I'd place this textually next to the other Boolean variables that store options, yes, this is how I thought it could be done.
src/goto-symex/goto_symex_state.cpp
Outdated
if(run_validation_checks) | ||
{ | ||
const validation_modet vm = local_validation_mode; | ||
DATA_CHECK(!check_renaming_l1(lhs), "lhs renaming failed on l1"); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Hopefully that pain will go away soon when DATA_CHECK
takes three arguments...
src/goto-symex/symex_main.cpp
Outdated
@@ -301,7 +301,7 @@ void goto_symext::symex_from_entry_point_of( | |||
|
|||
statet state; | |||
|
|||
state.global_validation_mode = global_validation_mode; | |||
state.run_validation_checks = run_validation_checks; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
One future day we will actually have a proper constructor I suppose...
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
✔️
Passed Diffblue compatibility checks (cbmc commit: 77868dc).
Build URL: https://travis-ci.com/diffblue/test-gen/builds/91655999
77868dc
to
6bc7648
Compare
@tautschnig I've moved the Boolean flag to the previous ones and squashed the commits. |
6bc7648
to
242655b
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
✔️
Passed Diffblue compatibility checks (cbmc commit: 242655b).
Build URL: https://travis-ci.com/diffblue/test-gen/builds/91697460
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM, but would be good to rebase on top of #3480 and make the implicit parameter to DATA_CHECK be explicit.
src/goto-symex/goto_symex_state.cpp
Outdated
assert_l1_renaming(lhs); | ||
|
||
#if 0 | ||
const validation_modet local_validation_mode = validation_modet::INVARIANT; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
If the validation mode is hardcoded to validation_modet::INVARIANT
we could also use DATA_INVARIANT()
directly instead. I think when using DATA_CHECK()
the mode should be truly configurable.
unit/goto-symex/ssa_equation.cpp
Outdated
{ | ||
caught = true; | ||
} | ||
REQUIRE(caught); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think catch supports REQUIRE_THROWS_*
macros to check that a particular exception is thrown.
Follows the diffblue#3123 skeleton with additional checks in SSA_stept. Adds a condition such that renaming checks are only run with the validate option.
242655b
to
eb0b86b
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
✔️
Passed Diffblue compatibility checks (cbmc commit: eb0b86b).
Build URL: https://travis-ci.com/diffblue/test-gen/builds/93144445
…plicit-argument Make validation mode parameter explicit in DATA_CHECK macros [blocks #3287]
This is an attempt at introducing well-formedness checking into SSA equation. It follows the process of #3123 by implementing the
validate
method inSSA_stept
and extendingssa_exprt
withcheck/validate
functionality. Unit tests will be included if the attempt is deemed worthy of pursuing.