Invariant cleanup goto programs sz#2968
Conversation
allredj
left a comment
There was a problem hiding this comment.
Passed Diffblue compatibility checks (cbmc commit: c91d2f7).
Build URL: https://travis-ci.com/diffblue/test-gen/builds/85020510
src/goto-programs/set_properties.cpp
Outdated
| throw "property "+id2string(*property_set.begin())+" not found"; | ||
| INVARIANT_WITH_DIAGNOSTICS( | ||
| property_set.empty(), | ||
| "Property ", |
There was a problem hiding this comment.
start with lower case (several occurrences)
There was a problem hiding this comment.
This one is a message that is aimed at the user; it is NOT checking an invariant!
| error().source_location=target->source_location; | ||
| error() << "sprintf expected to have two or more arguments" << eom; | ||
| throw 0; | ||
| UNREACHABLE; |
There was a problem hiding this comment.
The check as a whole should be an invariant (several occurrences).
There was a problem hiding this comment.
This is not an invariant either; it is an input condition check. An invariant is something that the program maintains internally, and not something it expects the environment to provide.
There was a problem hiding this comment.
I would expect this to be ensured by the C frontend (which it actually does). After that we should be able to assume it invariant.
kroening
left a comment
There was a problem hiding this comment.
There is a fundamental confusion here between invariants and input checks.
|
I've tried distinguishing between user input error and invariants. Unknown user input is handled by a new exception class and invalid input by the |
| if(!goto_functions.function_map.count(entry_point)) | ||
| throw "entry point not found"; | ||
| INVARIANT( | ||
| goto_functions.function_map.count(entry_point), "entry point not found"); |
There was a problem hiding this comment.
Do all current invocations of this function make sure this invariant truly holds?
There was a problem hiding this comment.
Well it's not guaranteed by the invocation; I guess it's more like a property of a well-formed goto-program. Maybe a DATA_INVARIANT would be more appropriate.
There was a problem hiding this comment.
I'd say the fix is to make sure it is guaranteed by all current invocations. The INVARIANT then makes this future-proof as additional invocation points added later on may fail to do the same check.
There was a problem hiding this comment.
I dag a bit deeper and the input goto_model is (so far always) a product of read_goto_binary. I've added a post-condition to the read_bin_goto_object_v4 function, so that only models with entry points are presently produced.
There was a problem hiding this comment.
This is really not guaranteed, and it's not desired to be guaranteed.
This is really a 'user input error'.
There was a problem hiding this comment.
Ok. I think we use invalid_user_input exceptions for invalid command line options. On one hand the error originates from the source code but on the other hand the well-formedness of a goto-programs requires an entry point. For now the code throws incorrect_goto_program exception, but I can re-write it, if incorrect_source_program would be more accurate.
|
|
||
| throw invalid_user_input_exceptiont( | ||
| "sprintf expected to have two or more arguments", | ||
| "sprintf(char *str, const char *format, ...);"); |
There was a problem hiding this comment.
Is the error() output above now redundant? It certainly seems to be a bad idea to duplicate text?
src/goto-programs/vcd_goto_trace.cpp
Outdated
| else if(expr.id()==ID_union) | ||
| { | ||
| assert(expr.operands().size()==1); | ||
| INVARIANT(expr.operands().size() == 1, "union only takes 1 operand"); |
There was a problem hiding this comment.
I'd suggest to use union_exprt/to_union_expr. Let's not duplicate invariant checks.
|
Another problem is that throwing an exception is very terminal -- we may wish to record the fact that there is an error, and continue processing, possibly to generate further error messages. |
Yes, but whether this can or cannot be done is very context dependent, and I'm not sure this specifically applies to any of the changes in this PR? |
allredj
left a comment
There was a problem hiding this comment.
Passed Diffblue compatibility checks (cbmc commit: f1de4e8).
Build URL: https://travis-ci.com/diffblue/test-gen/builds/85161891
|
|
||
| functions.compute_location_numbers(); | ||
|
|
||
| POSTCONDITION(functions.function_map.count(goto_functionst::entry_point())); |
There was a problem hiding this comment.
Nit pick: Visual Studio warns about this conversion from an integer to a Boolean. So either add != 0 or use functions.function_map.find(...) != functions.function_map.end().
There was a problem hiding this comment.
Added comparison with 0.
| if(ptr==nullptr) | ||
| throw "symbol "+id2string(symbol.name)+" has unknown mode"; | ||
| INVARIANT_WITH_DIAGNOSTICS( | ||
| ptr != nullptr, "symbol ", id2string(symbol.name), " has unknown mode"); |
src/goto-programs/vcd_goto_trace.cpp
Outdated
| #include <cassert> | ||
| #include <ctime> | ||
|
|
||
| #include <util/invariant.h> |
There was a problem hiding this comment.
Removed as now redundant, invariant check is inside to_union_expr.
allredj
left a comment
There was a problem hiding this comment.
Passed Diffblue compatibility checks (cbmc commit: 0f2549d).
Build URL: https://travis-ci.com/diffblue/test-gen/builds/85326549
0f2549d to
a094ff7
Compare
|
Squashed the commits, rebased, re-worked to use the |
allredj
left a comment
There was a problem hiding this comment.
Passed Diffblue compatibility checks (cbmc commit: a094ff7).
Build URL: https://travis-ci.com/diffblue/test-gen/builds/85404599
| POSTCONDITION( | ||
| goto_model.goto_functions.function_map.count( | ||
| goto_functionst::entry_point()) != 0); | ||
| } |
There was a problem hiding this comment.
This is certainly not guaranteed to hold -- we may wish to instrument goto binaries before linking is completed.
| throw invalid_user_input_exceptiont( | ||
| "property " + id2string(*property_set.begin()) + " unknown", | ||
| "--property id"); | ||
| } |
There was a problem hiding this comment.
That new exception isn't caught!
There was a problem hiding this comment.
Added catch blocks to all call sites.
| if(!goto_functions.function_map.count(entry_point)) | ||
| throw "entry point not found"; | ||
| INVARIANT( | ||
| goto_functions.function_map.count(entry_point), "entry point not found"); |
There was a problem hiding this comment.
This is really not guaranteed, and it's not desired to be guaranteed.
This is really a 'user input error'.
| assert(f_it!=goto_functions.function_map.end()); | ||
| INVARIANT( | ||
| f_it != goto_functions.function_map.end(), "initialize function not found"); | ||
|
|
There was a problem hiding this comment.
This isn't an internal invariant, but a well-formed-ness condition on the goto binary.
There was a problem hiding this comment.
Changed to incorrect goto exception.
| throw incorrect_goto_program_exceptiont( | ||
| "sprintf expected to have two or more arguments", | ||
| target->source_location); | ||
| } |
There was a problem hiding this comment.
This isn't really a property of the goto-program, but one of the original source code.
There was a problem hiding this comment.
Introduced new exception for source code errors (used a few times in this file).
| throw incorrect_goto_program_exceptiont( | ||
| "snprintf expected to have three or more arguments", | ||
| target->source_location); | ||
| } |
| assert(expr.operands().size()==1); | ||
| return as_vcd_binary(expr.op0(), ns); | ||
| return as_vcd_binary(to_union_expr(expr).op0(), ns); | ||
| } |
| throw invalid_user_input_exceptiont( | ||
| "version no longer supported", | ||
| "supported version = " + std::to_string(current_goto_version)); | ||
| else if(version > current_goto_version) |
There was a problem hiding this comment.
If you print the current version, also print the version of the goto binary.
650d39b to
dbad224
Compare
allredj
left a comment
There was a problem hiding this comment.
Passed Diffblue compatibility checks (cbmc commit: dbad224).
Build URL: https://travis-ci.com/diffblue/test-gen/builds/85715156
src/cbmc/cbmc_parse_options.cpp
Outdated
| ::set_properties(goto_model, cmdline.get_values("property")); | ||
| } | ||
|
|
||
| catch(const incorrect_goto_program_exceptiont &e) |
There was a problem hiding this comment.
I don't like these try-catch blocks that do not perform any recovery action. In my opinion, all the try-catch blocks in cbmc_parse_options can be removed because the only action that is taken is to exit. The same can be achieved in a much cleaner way by catching those exceptions at top-level (parse_optionst) only.
There was a problem hiding this comment.
Yes, it's much neater catching them all in parse_option_baset.
50719d5 to
d556b4f
Compare
allredj
left a comment
There was a problem hiding this comment.
Passed Diffblue compatibility checks (cbmc commit: d556b4f).
Build URL: https://travis-ci.com/diffblue/test-gen/builds/85754711
src/util/parse_options.cpp
Outdated
| std::cerr << e.what() << "\n"; | ||
| return CPROVER_EXIT_USAGE_ERROR; | ||
| } | ||
| catch(const incorrect_goto_program_exceptiont &e) |
There was a problem hiding this comment.
Isn't that subsumed by the case below?
There was a problem hiding this comment.
Yes, I guess the intention is to distinguish individual exception classes, maybe different error message or return code. There is not dedicated error code for incorrect goto programs, only for PARSE_ERROR.
There was a problem hiding this comment.
parse_options_baset is mean to be very broadly applicable -- including in programs that do not know anything about goto_programs. I would go for a broader superclass here.
There was a problem hiding this comment.
Ok, catching incorrect_goto_program is omitted, and cprover_exception_baset is caught directly.
allredj
left a comment
There was a problem hiding this comment.
Passed Diffblue compatibility checks (cbmc commit: 7075395).
Build URL: https://travis-ci.com/diffblue/test-gen/builds/85851896
| throw "entry point not found"; | ||
| if(goto_functions.function_map.count(entry_point) == 0) | ||
| throw incorrect_goto_program_exceptiont("entry point not found"); | ||
|
|
There was a problem hiding this comment.
I'd say it's misleading to throw this exception. A goto program without entry point is in no way malformed or incorrect.
There was a problem hiding this comment.
Ok, I think that invalid_user_input would be misleading as well, so I've added user_input_error exception (locally in slice_global_inits until use elsewhere is required).
allredj
left a comment
There was a problem hiding this comment.
Passed Diffblue compatibility checks (cbmc commit: cceeb4e).
Build URL: https://travis-ci.com/diffblue/test-gen/builds/85970940
|
@kroening - Could you re-review this PR when you have a moment or two? we think this is now just blocked on your input. |
| } | ||
|
|
||
| std::string what() const | ||
| { |
| { | ||
| } | ||
| std::string what() const | ||
| { |
059e0a1 to
3aee09c
Compare
3aee09c to
cb844be
Compare
allredj
left a comment
There was a problem hiding this comment.
Passed Diffblue compatibility checks (cbmc commit: cb844be).
Build URL: https://travis-ci.com/diffblue/test-gen/builds/86887302
No description provided.