-
Notifications
You must be signed in to change notification settings - Fork 274
Invariant cleanup goto programs jr #2967
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
Invariant cleanup goto programs jr #2967
Conversation
4d8920e
to
4f9e5c8
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: 4f9e5c8).
Build URL: https://travis-ci.com/diffblue/test-gen/builds/85033090
throw 0; | ||
throw deserialization_exceptiont( | ||
"failed to figure out type of file" | ||
"\nsource 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.
A structured variant would be good to enable proper JSON/XML output of the 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.
Actually, it seems like the source location here is only used to communicate the filename. I'll reword the error message.
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 this case the source location is actually just used to communicate the file name, so I think I'll just reword the message
@@ -94,8 +95,7 @@ void lazy_goto_modelt::initialize(const cmdlinet &cmdline) | |||
const std::vector<std::string> &files=cmdline.args; | |||
if(files.empty()) | |||
{ | |||
msg.error() << "Please provide a program" << messaget::eom; | |||
throw 0; | |||
throw invalid_user_input_exceptiont("No program provided", "", ""); |
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.
Provide a proper constructor for such a case
|
||
{ | ||
// TODO more helpful error message | ||
throw deserialization_exceptiont("Typechecking main failed"); |
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)
src/goto-programs/remove_vector.cpp
Outdated
@@ -114,13 +115,14 @@ static void remove_vector(exprt &expr) | |||
} | |||
else if(expr.id()==ID_unary_minus || expr.id()==ID_bitnot) | |||
{ | |||
DATA_INVARIANT( | |||
expr.operands().size() == 1, "unary operators have one 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.
operand
src/goto-programs/replace_calls.cpp
Outdated
throw "Returns must not be removed before replacing calls"; | ||
INVARIANT( | ||
!has_suffix(id2string(se.get_identifier()), RETURN_VALUE_SUFFIX), | ||
"this happens before returns are 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.
The original message was somehow better.
@@ -158,8 +159,8 @@ void lazy_goto_modelt::initialize(const cmdlinet &cmdline) | |||
|
|||
if(language_files.typecheck(symbol_table)) | |||
{ | |||
msg.error() << "CONVERSION ERROR" << messaget::eom; | |||
throw 0; | |||
// TODO more helpful error message |
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'm not sure this is a TODO (and neither in the parser case): those "more helpful error messages" are provided already, during parsing/type checking.
src/goto-programs/remove_complex.cpp
Outdated
@@ -32,10 +32,10 @@ static exprt complex_member(const exprt &expr, irep_idt id) | |||
} | |||
else | |||
{ | |||
assert(expr.type().id()==ID_struct); | |||
PRECONDITION(expr.type().id() == ID_struct); |
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 actually checked by the subsequent to_struct_type
src/goto-programs/remove_complex.cpp
Outdated
@@ -222,12 +229,12 @@ static void remove_complex(exprt &expr) | |||
|
|||
if(expr.id()==ID_complex_real) | |||
{ | |||
assert(expr.operands().size()==1); | |||
static_cast<void>(to_complex_real_expr(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.
Better use this in the subsequent statement: expr = complex_member(to_complex_real_expr(expr).op(), ID_real)
INVARIANT( | ||
call.function().id() == ID_symbol, | ||
"by this point, all kinds of function calls should have been " | ||
"converted to simple function calls"); |
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.
Maybe add the error message as a comment in here, but really to_symbol_expr
below actually takes care of this.
ca29d81
to
5ec6f92
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: 5ec6f92).
Build URL: https://travis-ci.com/diffblue/test-gen/builds/86723412
@peterschrammel @tautschnig I believe I've addressed your comments on here now, could you please re-review? |
@@ -17,6 +17,7 @@ | |||
#include <langapi/language.h> | |||
|
|||
#include <fstream> | |||
#include <util/exception_utils.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.
Nit pick: please move this a few lines up, with the other util
includes.
<< '\'' << messaget::eom; | ||
throw 0; | ||
throw system_exceptiont( | ||
"failed to open input file `" + filename + '\''); |
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 this (most likely) also an invalid_user_input_exceptiont
. It's of course possible that your file system is somehow hosed, but in almost all cases the user will be the one who got it wrong.
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's quite possible that the root cause is because the user passed in the wrong filename. Or it could fail for other reasons. The only thing we know at this point is that we can't open the file, so we report that as such here.
@@ -147,8 +147,7 @@ void lazy_goto_modelt::initialize(const cmdlinet &cmdline) | |||
|
|||
if(language.parse(infile, filename)) | |||
{ | |||
msg.error() << "PARSING ERROR" << messaget::eom; | |||
throw 0; | |||
throw deserialization_exceptiont("PARSING 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.
Isn't this invalid input? (I.e., another case of a user 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.
deserialization_exceptiont
is for "invalid inputs", but of another kind. If you look at invalid_user_input_exceptiont
it's actually just indicating malformed arguments (IMHO it should be renamed to something like bad_argument_exceptiont
), whereas deserialization_exceptiont
means we got some input but it wasn't in the format that we expected.
@@ -158,8 +157,7 @@ void lazy_goto_modelt::initialize(const cmdlinet &cmdline) | |||
|
|||
if(language_files.typecheck(symbol_table)) | |||
{ | |||
msg.error() << "CONVERSION ERROR" << messaget::eom; | |||
throw 0; | |||
throw deserialization_exceptiont("CONVERSION 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.
As above: I don't think deserialization_exceptiont
is the right choice.
linking.object_type_updates)) | ||
throw 0; | ||
{ | ||
throw deserialization_exceptiont("typechecking main failed"); |
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.
As above: this is the result of invalid user input.
src/goto-programs/remove_complex.cpp
Outdated
ID_complex_real, expr.op0(), expr.op0().type().subtype()); | ||
ID_complex_real, | ||
typecast_expr.op(), | ||
typecast_expr.op().type().subtype()); |
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.
We now have a complex_real_exprt
, please use this one in here while changing those lines.
src/goto-programs/remove_complex.cpp
Outdated
|
||
expr=struct_expr; | ||
} | ||
else if(expr.id()==ID_complex) | ||
{ | ||
assert(expr.operands().size()==2); | ||
static_cast<void>(to_complex_expr(expr)); | ||
expr.id(ID_struct); |
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.
Maybe we should just make this code a bit more explicit:
struct_exprt s(expr.type());
s.add_source_location() = expr.source_location();
s.copy_to_operands(to_complex_expr(expr).real(), to_complex_expr(expr).imag());
expr.swap(s);
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 been meaning to ask, why do we prefer swap over assignment in these cases?
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.
Swapping two irept
is literally just swapping two pointers, doing operator=
involves a sequence of reference-count updates -- unless rvalue references can be used, at which point it's just a swap again. But then the mentioned reference-count updates may happen either way if one of the swapped irept
s goes out of scope. So it's probably an unmeasurable difference.
src/goto-programs/remove_vector.cpp
Outdated
@@ -108,13 +109,14 @@ static void remove_vector(exprt &expr) | |||
} | |||
else if(expr.id()==ID_unary_minus || expr.id()==ID_bitnot) | |||
{ | |||
DATA_INVARIANT( | |||
expr.operands().size() == 1, "unary operators have one 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.
Could still use to_unary_expr
instead
src/goto-programs/remove_vector.cpp
Outdated
@@ -82,13 +82,14 @@ static void remove_vector(exprt &expr) | |||
expr.id()==ID_mod || expr.id()==ID_bitxor || | |||
expr.id()==ID_bitand || expr.id()==ID_bitor) | |||
{ | |||
DATA_INVARIANT( | |||
expr.operands().size() == 2, "binary operators have 2 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.
How about to_binary_expr
?
5ec6f92
to
a7c8bab
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: a7c8bab).
Build URL: https://travis-ci.com/diffblue/test-gen/builds/86762862
I'll use the |
Should be unblocked by now (#3099 has been merged). |
3fa5d57
to
e9067f4
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: 3fa5d57).
Build URL: https://travis-ci.com/diffblue/test-gen/builds/87482764
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: e9067f4).
Build URL: https://travis-ci.com/diffblue/test-gen/builds/87486188
@tautschnig I've changed the exception types (except for one system_exceptiont where I still think it's the right one to use, even though I see the argument). Would you mind taking another look? |
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 older code is confused about which are binary and which are n-ary operations. This is not uncommon as I remember submitting the patch that started clarifying this. My guess is that there aren't tests for this. Fixing it may be beyond the scope of this PR but we should at least have the checks and invariants correctly annotated.
e9067f4
to
4a46e09
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: 4a46e09).
Build URL: https://travis-ci.com/diffblue/test-gen/builds/87670052
4a46e09
to
75414ce
Compare
@martin-cs I changed the DATA_INVARIANT to precondition, added a precondition in the other case where it just used to_binary_expr without a check before, and reworded the fixme comment to make it more clear that the operations are n-ary operations specifically rather than just "not binary". |
@hannes-steffenhagen-diffblue : Thank you. |
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.
All issues I raised have been handled appropriately.
throw 0; | ||
{ | ||
source_locationt source_location; | ||
source_location.set_file(irep_idt(file)); |
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 am surprised you actually need the irep_idt
in there?
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.
We don't. Not sure why that's in here, I'll remove it.
src/goto-programs/remove_complex.cpp
Outdated
assert(expr.operands().size()==2); | ||
expr.id(ID_struct); | ||
auto const &complex_expr = to_complex_expr(expr); | ||
struct_exprt struct_expr{complex_expr.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.
Nit pick: use round parentheses
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: 75414ce).
Build URL: https://travis-ci.com/diffblue/test-gen/builds/88091760
75414ce
to
365bb72
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: 365bb72).
Build URL: https://travis-ci.com/diffblue/test-gen/builds/88137222
Only 793fe3b and later are new (will require rebase later, this is just up for review now).