-
Notifications
You must be signed in to change notification settings - Fork 277
Invariant cleanup goto programs sz #2968
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.
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.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
start with lower case (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.
This one is a message that is aimed at the user; it is NOT checking an invariant!
@@ -281,7 +282,7 @@ void string_instrumentationt::do_sprintf( | |||
{ | |||
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.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The check as a whole should be an invariant (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.
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.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
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.
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.
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.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Do all current invocations of this function make sure this invariant truly holds?
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 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.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
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.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
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.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
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.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
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.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
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
@@ -55,7 +55,7 @@ std::string as_vcd_binary( | |||
} | |||
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.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
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? |
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: f1de4e8).
Build URL: https://travis-ci.com/diffblue/test-gen/builds/85161891
@@ -158,6 +158,8 @@ static bool read_bin_goto_object_v4( | |||
|
|||
functions.compute_location_numbers(); | |||
|
|||
POSTCONDITION(functions.function_map.count(goto_functionst::entry_point())); |
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 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.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
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"); |
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.
There is #2984, which will do away with all this code...
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.
Rolled back all changes in this file, hopefully #2984 will clean it adequately.
src/goto-programs/vcd_goto_trace.cpp
Outdated
#include <ctime> | ||
|
||
#include <util/invariant.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.
No invariant added?
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.
Removed as now redundant, invariant check is inside to_union_expr
.
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: 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 |
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: 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.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is certainly not guaranteed to hold -- we may wish to instrument goto binaries before linking is completed.
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, removed.
throw "property "+id2string(*property_set.begin())+" not found"; | ||
throw invalid_user_input_exceptiont( | ||
"property " + id2string(*property_set.begin()) + " unknown", | ||
"--property 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.
That new exception isn't 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.
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.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is really not guaranteed, and it's not desired to be guaranteed.
This is really a 'user input error'.
@@ -73,7 +75,8 @@ void slice_global_inits(goto_modelt &goto_model) | |||
|
|||
goto_functionst::function_mapt::iterator f_it; | |||
f_it=goto_functions.function_map.find(INITIALIZE_FUNCTION); | |||
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.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This isn't an internal invariant, but a well-formed-ness condition on the 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.
Changed to incorrect goto exception.
throw 0; | ||
throw incorrect_goto_program_exceptiont( | ||
"sprintf expected to have two or more arguments", | ||
target->source_location); | ||
} |
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 isn't really a property of the goto-program, but one of the original source code.
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.
Introduced new exception for source code errors (used a few times in this file).
throw 0; | ||
throw incorrect_goto_program_exceptiont( | ||
"snprintf expected to have three or more arguments", | ||
target->source_location); | ||
} |
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.
@@ -55,8 +54,7 @@ std::string as_vcd_binary( | |||
} | |||
else if(expr.id()==ID_union) | |||
{ | |||
assert(expr.operands().size()==1); | |||
return as_vcd_binary(expr.op0(), ns); | |||
return as_vcd_binary(to_union_expr(expr).op0(), 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.
I'd write .op() 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.
Ok.
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.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
If you print the current version, also print the version of the 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.
Done.
650d39b
to
dbad224
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: dbad224).
Build URL: https://travis-ci.com/diffblue/test-gen/builds/85715156
src/cbmc/cbmc_parse_options.cpp
Outdated
@@ -541,6 +542,12 @@ bool cbmc_parse_optionst::set_properties() | |||
::set_properties(goto_model, cmdline.get_values("property")); | |||
} | |||
|
|||
catch(const incorrect_goto_program_exceptiont &e) |
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 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.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes, it's much neater catching them all in parse_option_baset
.
50719d5
to
d556b4f
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: d556b4f).
Build URL: https://travis-ci.com/diffblue/test-gen/builds/85754711
src/util/parse_options.cpp
Outdated
@@ -76,6 +76,11 @@ int parse_options_baset::main() | |||
std::cerr << e.what() << "\n"; | |||
return CPROVER_EXIT_USAGE_ERROR; | |||
} | |||
catch(const incorrect_goto_program_exceptiont &e) |
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.
Isn't that subsumed by the case below?
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 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.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
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.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ok, catching incorrect_goto_program
is omitted, and cprover_exception_baset
is caught directly.
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: 7075395).
Build URL: https://travis-ci.com/diffblue/test-gen/builds/85851896
if(!goto_functions.function_map.count(entry_point)) | ||
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.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
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.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
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).
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: 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 | ||
{ |
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.
Add 'override'
{ | ||
} | ||
std::string what() 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.
override
059e0a1
to
3aee09c
Compare
3aee09c
to
cb844be
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: cb844be).
Build URL: https://travis-ci.com/diffblue/test-gen/builds/86887302
No description provided.