-
Notifications
You must be signed in to change notification settings - Fork 273
Skeleton for well-formedness checking of goto models [blocks: #3118, #3147, #3188, #3191, #3187, #3193] #3123
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
Skeleton for well-formedness checking of goto models [blocks: #3118, #3147, #3188, #3191, #3187, #3193] #3123
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.
This PR failed Diffblue compatibility checks (cbmc commit: bcca1a6).
Build URL: https://travis-ci.com/diffblue/test-gen/builds/87221686
Status will be re-evaluated on next push.
Please contact @peterschrammel, @thk123, or @allredj for support.
Common spurious failures:
- the cbmc commit has disappeared in the mean time (e.g. in a force-push)
- the author is not in the list of contributors (e.g. first-time contributors).
a293f3e
to
37a4de4
Compare
C<expr_type>()(expr, std::forward<Args>(args)...) | ||
|
||
template <template <typename> class C, typename... Args> | ||
void call_on_expr(const exprt &expr, Args &&... args) |
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 function simulates virtual call resolution on exprt
via a case distinction on id()
. The structs call_checkt
, call_validatet
, and call_validate_fullt
in validate.h
specify the method to be called (check()
, validate()
, and validate_full()
resp.) and take as a template parameter the expression type to cast to.
else | ||
{ | ||
CALL_ON_EXPR(exprt); | ||
} |
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.
Cases for more expressions will be added here in the future.
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.
In the end the last case should fail an invariant in order to actually detect when something is missing. For now it would be good if it could output a warning or so.
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've added a macro REPORT_UNIMPLEMENTED_EXPRESSION_CHECKS
that can be set when compiling. If enabled the ids for currently unimplemented expression checks are reported to stderr
.
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 PR failed Diffblue compatibility checks (cbmc commit: 37a4de4).
Build URL: https://travis-ci.com/diffblue/test-gen/builds/87236032
Status will be re-evaluated on next push.
Please contact @peterschrammel, @thk123, or @allredj for support.
Common spurious failures:
- the cbmc commit has disappeared in the mean time (e.g. in a force-push)
- the author is not in the list of contributors (e.g. first-time contributors).
/// reported via DATA_INVARIANT violations or exceptions. | ||
void validate(const namespacet &ns, const validation_modet vm) const | ||
{ | ||
for(const auto &entry : function_map) |
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 have this loop on the goto_model
level: one less file to modify. But this works just as good.
…e#3123 The condition to be checked is the same. Interface function name was changed to follow the above PR. Also the check is now optional via command line.
42bf8fe
to
41cb816
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.
This PR failed Diffblue compatibility checks (cbmc commit: 42bf8fe).
Build URL: https://travis-ci.com/diffblue/test-gen/builds/87472451
Status will be re-evaluated on next push.
Please contact @peterschrammel, @thk123, or @allredj for support.
Common spurious failures:
- the cbmc commit has disappeared in the mean time (e.g. in a force-push)
- the author is not in the list of contributors (e.g. first-time contributors).
src/util/validate.h
Outdated
template <typename T> | ||
struct call_checkt | ||
{ | ||
static_assert(std::is_base_of<irept, T>::value, ""); |
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.
missing message (several occurrences)
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.
Hm, the message wouldn't really add anything here. With C++17 the message will become optional then we could remove it.
else | ||
{ | ||
CALL_ON_EXPR(exprt); | ||
} |
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.
In the end the last case should fail an invariant in order to actually detect when something is missing. For now it would be good if it could output a warning or so.
} | ||
else | ||
{ | ||
CALL_ON_TYPE(typet); |
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.
see comment for exprt
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.
Added a macro REPORT_UNIMPLEMENTED_TYPE_CHECKS
} | ||
else | ||
{ | ||
CALL_ON_CODE(codet); |
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.
see comment for exprt
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.
added a macro REPORT_UNIMPLEMENTED_CODE_CHECKS
src/util/validate_code.cpp
Outdated
} | ||
|
||
/// Check that the given code statement is well-formed, assuming that all its | ||
/// enclosed statements, subexpressions, etc. have all ready been checked for |
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.
already?
src/util/std_code.h
Outdated
/// | ||
/// The validation mode indicates whether well-formedness check failures are | ||
/// reported via DATA_INVARIANT violations or exceptions. | ||
void check(const validation_modet vm = validation_modet::INVARIANT) const |
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.
see comment for exprt
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.
see reply for exprt :)
src/cbmc/cbmc_parse_options.cpp
Outdated
@@ -972,6 +978,7 @@ void cbmc_parse_optionst::help() | |||
" --xml-ui use XML-formatted output\n" | |||
" --xml-interface bi-directional XML interface\n" | |||
" --json-ui use JSON-formatted output\n" | |||
" --validate-goto-model enables additional well-formedness checks on the goto program\n" // NOLINT(*) |
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.
break long help text and align below enables
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.
You mean so the output of --help
will be at most 80 characters wide, or that the code should be at most 80 characters wide, or both?
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.
cbmc/src/goto-instrument/reachability_slicer.h
Lines 44 to 47 in 7905492
" --fp-reachability-slice f remove instructions that cannot appear on a trace\n" \ | |
" that visits all given functions. The list of\n" \ | |
" functions has to be given as a comma separated\n" \ | |
" list f.\n" \ |
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.
Thanks @xbauch. So that seems to suggest 80 characters in the output but not necessarily in the code. I'm gonna change it to that.
@@ -526,6 +526,12 @@ int cbmc_parse_optionst::doit() | |||
if(set_properties()) | |||
return CPROVER_EXIT_SET_PROPERTIES_FAILED; | |||
|
|||
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.
Would we like to have this in the other driver programs too?
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 would have thought goto-instrument was the place for it.
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.
Yes, I think we should have the option in all of the tools to validate the goto model.
@martin-cs I think also in e.g. cbmc
it would make sense to validate the goto program as a safety net sort of thing. Once right after goto_convert
and perhaps once more before goto_symex
to check that all the transformation passes like remove_function_pointers
, etc. did not produce an ill-formed 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.
@danpoe : I'm very much in favour of validating the program between all transformation passes; that sounds great. To the point I might suggest making that the last step of each transformation. I think this will need to be able to check for various "normal forms" as well, i.e. returns and function pointers removed, etc. ( @tautschnig may have opinions on this subject ). As I first envisaged this, that should be enough to prove that all of the DATA_INVARIANTs hold.
i also like the "with exceptions when we load it and with invariants after" approach. My only question is about the specific, user accessible command-line flag to just check the validity of the goto-program and nothing else. That seems like something we definitely want but that it should probably be in goto-instrument as a "checking and modifying the goto-program" bit of functionality, rather than in every tool.
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.
Ah yes, that makes sense. @sonodtt is currently working on some additional checks of the goto program that will allow to pass flags that indicate whether function pointers and returns are expected to have been removed.
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.
Cool.
@sonodtt : having looked at this in the past ( #751 is the first bit I have written down ), may I suggest that you make the flags independent for each feature. For example, one of the last few differences between the static_analyst
and ait
frameworks is that the later requires the abscence of function pointers (naturally or removed) and return removal. function pointer removal is an (at the moment undocumented) precondition of return removal and so on. It would be amazing if we could actually map out and enforce these requirements on "normal forms".
41cb816
to
0316f5f
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.
This seems like a useful and a worthwhile thing to do. I'm not sure I quite 'get' the architecture of this but I think I could be persuaded. I slightly worry that this might lead to duplication of checks but that is better than not having any at all!
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 PR failed Diffblue compatibility checks (cbmc commit: 41cb816).
Build URL: https://travis-ci.com/diffblue/test-gen/builds/87476584
Status will be re-evaluated on next push.
Please contact @peterschrammel, @thk123, or @allredj for support.
Common spurious failures:
- the cbmc commit has disappeared in the mean time (e.g. in a force-push)
- the author is not in the list of contributors (e.g. first-time contributors).
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: 0316f5f).
Build URL: https://travis-ci.com/diffblue/test-gen/builds/87480682
Using DATA_CHECK instead of calling error handling directly.
src/util/validate.h
Outdated
|
||
/// This macro takes a condition which denotes a well-formedness criterion on | ||
/// goto programs, expressions, instructions, etc. Based on the value of the | ||
/// variable vm (the validation mode), it either uses DATA_INVARIANT() to check |
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 may have missed a global declaration of vm
somewhere, but from what I've seen it looks like vm
is just 'whatever variable of that name is in scope at the moment?` - Could you either make that explicit in the docs and/or actually add a global declaration for it somewhere? I'm otherwise wondering what the compile error messages might look like if someone tries to use these macros outside of a validate() function, or if the try to declare a variable of a different type but the same name... :-)
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.
Ok, I've added some doc and added a static assertion to check that vm
has the expected type.
0316f5f
to
69c46d5
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: 69c46d5).
Build URL: https://travis-ci.com/diffblue/test-gen/builds/87519725
69c46d5
to
5befa49
Compare
…flags) There are two flags: --validate-goto-binary reads in a goto binary and checks that it is well formed and then exits; --validate-goto-model enables additional well-formedness checks at various points during the execution of goto-instrument in addition to the normal analyses that it runs.
af3aa4f
to
d638ea7
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: d638ea7).
Build URL: https://travis-ci.com/diffblue/test-gen/builds/90857933
DATA_CHECK( | ||
base_type_eq(code.op0().type(), code.op1().type(), ns), | ||
"lhs and rhs of assignment must have same type"); | ||
} |
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.
It is no longer necessary to use base_type_eq to compare types -- you can simply use == !
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.
That's not quite the case just yet, is it? Otherwise we should have a major campaign removing all cases of base_type_eq
.
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.
Yes, we should have that campaign, together with getting rid of most instances of ns.follow().
DATA_CHECK( | ||
base_type_eq(expr.op0().type(), expr.op1().type(), ns), | ||
"lhs and rhs of binary relation expression should have same type"); | ||
} |
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.
Same here
If you use == instead of base_type_eq, then the namespace that gets passed around becomes unused. If that bugs you, you could use it to check whether the tag types are in the symbol table, and whether symbol_exprt identifiers are in the symbol table. |
Ok, if that is meant to remain separate, then you could get rid of the namespacet parameters. |
Follows the diffblue#3123 skeleton with additional checks in SSA_stept.
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.
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.
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.
This PR introduces a framework for well-formedness checking of goto models. It also introduces two new macros
DATA_CHECK()
andDATA_CHECK_WITH_DIAGNOSTICS()
for use in the various validation methods (likevalidate()
,validate_full()
on expressions). Based on the value of a variablevm
(the validation mode, which is an enum with valuesINVARIANT
orEXCEPTION
), when a well-formedness check fails either aDATA_INVARIANT()
fails or anincorrect_goto_program_exceptiont
is thrown.