Skip to content

Invariant cleanup in goto programs i* #2952

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

hannes-steffenhagen-diffblue
Copy link
Contributor

@hannes-steffenhagen-diffblue hannes-steffenhagen-diffblue commented Sep 14, 2018

This PR is part of the invariant cleanup work, for the files in goto-programs starting with i.

This entails replacing asserts with cprover style invariants, using structured exception types and using to_XXX_expr style conversions instead of 'structure' asserts for expressions.

Copy link
Contributor

@allredj allredj left a 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: 6ff3096).
Build URL: https://travis-ci.com/diffblue/test-gen/builds/84818543

if(v.size()!=1)
throw "invalid boolean value";
throw interpreter_errort("invalid boolean value");
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I wonder if this shouldn't be an invariant. The input expr is always the path condition of the interpreted program and I don't think the user is directly responsible for what the interpreter chooses to be a path condition.

@hannes-steffenhagen-diffblue hannes-steffenhagen-diffblue force-pushed the invariant_cleanup-goto-programs-i_r branch 2 times, most recently from 129444d to cd0bd66 Compare September 21, 2018 11:17
@hannes-steffenhagen-diffblue hannes-steffenhagen-diffblue force-pushed the invariant_cleanup-goto-programs-i_r branch from cd0bd66 to dec77b7 Compare October 3, 2018 13:50
@hannes-steffenhagen-diffblue hannes-steffenhagen-diffblue force-pushed the invariant_cleanup-goto-programs-i_r branch from dec77b7 to 79efa6d Compare October 11, 2018 09:40
@hannes-steffenhagen-diffblue hannes-steffenhagen-diffblue force-pushed the invariant_cleanup-goto-programs-i_r branch from 79efa6d to 11af196 Compare October 11, 2018 11:07
msg.error() << "failed to figure out type of file" << messaget::eom;
throw 0;
throw invalid_source_file_exceptiont(
"Failed to figure out type of file `" + filename + '\'');
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This should arguably happen before the check whether the file can be opened, but that's a minor point and not really within the spirit of this PR

Copy link
Contributor

@allredj allredj left a 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: 79efa6d).
Build URL: https://travis-ci.com/diffblue/test-gen/builds/87615645
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).

The incompatibility may have been introduced by an earlier PR. In that case merging this
PR should be avoided unless it fixes the current incompatibility.

Copy link
Contributor

@xbauch xbauch left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It might be a little bit more readable if the variable renaming was in a separate commit. But other than that, it looks good to me.

Copy link
Collaborator

@martin-cs martin-cs left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for the clean-up. Comments are mostly opinions on what kind of error conditions these are.

@@ -69,12 +69,12 @@ void interpretert::initialize(bool init)
main_it=goto_functions.function_map.find(goto_functionst::entry_point());

if(main_it==goto_functions.function_map.end())
throw "main not found";
throw analysis_exceptiont("main not found");
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is this actually a structural invariant on goto-programs?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I wasn't sure about this one, because you might have goto programs without an entry point (libraries mostly). I suppose it could be a precondition if we assume that a caller should've checked for an entry point before calling this.

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It is getting in to the heart of why we need to check that goto-programs are well formed and to clarify what "normal forms" exist for them. If it has been linked and is a complete goto program then it should have an entry point which is a function in the map. If it is only partially built (goto-cc -c for example) then it may not do. It is not immediately clear to me whose fault it would be to try to interpret a n "object file" rather than an "executable".


const goto_functionst::goto_functiont &goto_function=main_it->second;

if(!goto_function.body_available())
throw "main has no body";
throw analysis_exceptiont("main has no body");
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

As above.

throw "RETURN without call"; // NOLINT(readability/throw)
{
throw analysis_exceptiont(
"RETURN without call"); // NOLINT(readability/throw)
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think this is an INVARIANT as if the interpreter is working as it should, then this should never happen.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I was thinking this could happen in a nonsensical goto program that has returns in unexpected places, such as __CPROVER_initialize. Is that wrong?

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If I understand the code correctly (and it is possible I don't) then the INVARIANT is that the number of RETURNS executed should never exceed the number of functions started. So this should always hold.

@@ -317,19 +320,23 @@ void interpretert::step()

case START_THREAD:
trace_step.type=goto_trace_stept::typet::SPAWN;
throw "START_THREAD not yet implemented"; // NOLINT(readability/throw)
throw analysis_exceptiont(
"START_THREAD not yet implemented"); // NOLINT(readability/throw)
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

UNIMPLEMENTED ? Also below.

@@ -359,7 +366,7 @@ void interpretert::step()
case CATCH:
break;
default:
throw "encountered instruction with undefined instruction type";
UNREACHABLE; // I'm assuming we'd catch such a thing before this point
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sounds like you're saying it is a consequence of the goto program being well-formed ;-)

@@ -724,15 +730,15 @@ void interpretert::assign(
void interpretert::execute_assume()
{
if(!evaluate_boolean(pc->guard))
throw "assumption failed";
throw analysis_exceptiont("assumption failed");
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Unrelated to this; I'm not sure this is the right way of handling this case. I think it should just terminate correctly.

This mostly entails using to_XXX_expr in place of using ad hoc asserts.
At the same time, some minor cleanup work is done to improve the
readability of the affected code
@hannes-steffenhagen-diffblue hannes-steffenhagen-diffblue force-pushed the invariant_cleanup-goto-programs-i_r branch from 11af196 to ce7f792 Compare October 11, 2018 13:32
@hannes-steffenhagen-diffblue
Copy link
Contributor Author

@martin-cs Yes, since I'm not super familiar with this code myself I was a bit unclear in many cases about whether INVARIANT or exception is the better 'mechanism' to use. I'll have another look over the cases you pointed out.

@martin-cs
Copy link
Collaborator

@hannes-steffenhagen-diffblue : The test I tend to you is : if there are a set of user controllable flags and a non-corrupted / incorrect program that can cause it to happen, it is a potential user error and should be an exception. If the only way it can happen is if there are one or more bugs in CPROVER, then it should be an invariant of some kind.

@hannes-steffenhagen-diffblue
Copy link
Contributor Author

@martin-cs I completely agree with that, it's just difficult to judge on a case by case basis sometimes.

Copy link
Contributor

@allredj allredj left a 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: 11af196).
Build URL: https://travis-ci.com/diffblue/test-gen/builds/87644100
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).

The incompatibility may have been introduced by an earlier PR. In that case merging this
PR should be avoided unless it fixes the current incompatibility.

@hannes-steffenhagen-diffblue
Copy link
Contributor Author

hannes-steffenhagen-diffblue commented Oct 11, 2018

Heads up, I'm a bit uncomfortable with putting these changes in as the interpreter seems to be broken and untested atm.

See #3146

I'll extract the initialize_goto_model stuff as that seems to be unrelated

Copy link
Contributor

@allredj allredj left a 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: ce7f792).
Build URL: https://travis-ci.com/diffblue/test-gen/builds/87649507

@martin-cs
Copy link
Collaborator

@hannes-steffenhagen-diffblue : It is difficult to judge; this is why I try to phrase my comments on these as "IMHO it should be".

As regards the interpreter; it didn't use to be in a great state but I thought someone at Diffblue had taken over it's care and feeding. I have a vague feeling that @dcattaruzza was asking about it at one point...

Copy link
Collaborator

@tautschnig tautschnig left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks ok to me (with one comment below); but really this should be checked against TG, where I believe some interpreter tests exist.

if(v.size()!=1)
throw "invalid boolean value";
throw analysis_exceptiont("invalid boolean value");
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I would drop the FIXME and turn this into an INVARIANT. People will start complaining if it's not actually an invariant... :-)

@hannes-steffenhagen-diffblue
Copy link
Contributor Author

I extracted the initialize_goto_model bit because that is tested, short, and fairly trivial (no changing of conditions, just different exception types) #3190

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

5 participants