Skip to content

Adds --expand-pointer-predicates to goto-instrument [depends-on: #3769, blocks #2706] #2644

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

Closed
wants to merge 3 commits into from

Conversation

qaphla
Copy link

@qaphla qaphla commented Jul 31, 2018

This builds on #2635.
The only new commit since then is 9be31ff.

This adds a new built-in predicate, __CPROVER_points_to_valid_memory, and provides the --expand-pointer-predicates pass to goto-instrument to handle the side effects that it has in assumptions. More detail can be found in the commit message.

This differs from #2602 in that unlike __CPROVER_r_ok and __CPROVER_w_ok, __CPROVER_points_to_valid_memory(ptr, size) will, when used in an assumption, ensure that there is a suitable memory object at ptr by creating one if necessary. It is, however, likely that __CPROVER_points_to_valid_memory can be made to take advantage of __CPROVER_r/w_ok in its implementation once those make it into develop.

klaas added 2 commits July 30, 2018 14:54
This change exposes is_lvalue for use outside of
goto-programs/builtin_functions.cpp.
The --expand-pointer-predicates pass resolves pointer predicates
(util/pointer_predicates.{cpp, h}) which have side effects and
so require expanding into multiple instructions.
Currently, the only such predicate that needs to be expanded is
__CPROVER_points_to_valid_memory (name subject to change).

The __CPROVER_points_to_valid_memory predicates takes two parameters,
a pointer and a size. Semantically,
__CPROVER_points_to_valid_memory(p, size) should be true if and only
if p points to a memory object which is valid to read/write for at
least size bytes past p. When used in assertions, this will be checked
in a similar manner to how --pointer-check checks validity of a
dereference. When used in assumptions, this predicate creates (if none
exists already) an object for p to refer to, using
local_bitvector_analysis to make that determination, and then makes
assumptions (again corresponding to the assertions made by
--pointer-check) about that object.
@qaphla qaphla force-pushed the expand_pointer_predicates branch from 5f9ce75 to dd6c63c Compare July 31, 2018 18:40
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: dd6c63c).
Build URL: https://travis-ci.com/diffblue/test-gen/builds/80542769
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).

Copy link
Contributor

@smowton smowton left a comment

Choose a reason for hiding this comment

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

Made a few inline comments on the new commit. Broader points:

(1) what relation if any does this have to the existing memory validity checks introduced by goto_check? Should this be using parts of goto-check instead of implementing a new way of introducing checks?

(2) It seems odd that the meaning of the predicate is remarkably different in assume context from assert context (and not implemented at all in expression or GOTO-guard context). Should these be different operations?

@qaphla
Copy link
Author

qaphla commented Aug 1, 2018

(1) As used in assertions, __CPROVER_points_to_valid_memory(ptr, size) corresponds exactly to the validity checks introduced by goto_check given an access to the 0th byte and the size - 1th byte of ptr. I think it is still useful to have a syntax for generating these checks more concisely than writing down those two dereferences and letting --pointer-check generate them. That said, the assertion portion of this could easily be put into goto-check (as it should be, when cleaned up, identical to #2602, which is built inside goto-check).

The assumption portion is the main feature that prompted me to develop this, and probably could be put into goto_check if desired, but that seems a bit strange to me, as goto_check seems to deal entirely (almost entirely? I'm not sure what enable_assert_to_assume is doing) with assertions and inserting checks for properties.

(2) I am admittedly biased, but it doesn't seem strange at all to me that the implementation of the predicate is different in assume and assert contexts. The expression resulting from expanding the predicate is the same in both cases, and the only difference is that in assume context, we add an additional set of instructions to create a new memory object for ptr to refer to if none exists. It appears that if no sch object exists, then assumptions about POINTER_OBJECT(ptr) or POINTER_OFFSET(ptr) do not accomplish anything, and so to get anything useful out of the assumptions, we need to ensure than such an object exists. In most cases, I agree, #2602's method is sufficient. This feature arose from work on contracts and the desire to analyze pieces of code in isolation, where it is useful to be able to make such assumptions and not have to worry about setting up a harness that creates objects for each pointer. This use case also provides the reason that I would like to have a single predicate that works like this in both assume and assert contexts, as I would like to be able to write down one contract which can be either assumed or asserted in the correct locations (e.g. a precondition should be asserted before the function call, and assumed at the beginning of the code that checks the function), which having two separate predicates would prevent. This is also why I have only addressed assume and assert contexts, though thinking further about it, it seems that the only real distinction that needs to be made is between assume contexts and everything else. This is an easy enough change to make, but should probably wait until it's clearer whether this belongs in goto_check or not. (I think it likely that it does, but need to figure out how to handle adding assumptions in goto_check).

@smowton
Copy link
Contributor

smowton commented Aug 1, 2018

Hmm. My instinct is the harness should do the right thing (e.g. when verifying Java we should usually offer a nondet choice between NULL and a fresh object), and the meaning of the predicate should be the same in all contexts, but more senior people (@peterschrammel @tautschnig @kroening) may differ.

@martin-cs
Copy link
Collaborator

I see and agree with @smowton 's concerns about the asymmetry of the semantics of this. I also, very much, see your use case and wanting to be able to generate sane harnesses with a minimal amount of hassle. However I'm not sure this is the right way of going about things. Assuming that something points to a valid location is not the same as assuming that there is a new, unique location that it points to. I think this approach may run into a lot of complexity around aliasing.

To my mind the right way of approaching this problem is to have a dual to generate-function-bodies that generates a calling harness (either 1 shot or dynamically builds one up using verification failures) for an arbitrary piece of code. Assumptions about writeability could be used in that to build a sensible context.

@tautschnig tautschnig self-assigned this Nov 10, 2018
@tautschnig tautschnig changed the title Adds --expand-pointer-predicates to goto-instrument Adds --expand-pointer-predicates to goto-instrument [blocks #2706] Nov 10, 2018
@tautschnig tautschnig changed the title Adds --expand-pointer-predicates to goto-instrument [blocks #2706] Adds --expand-pointer-predicates to goto-instrument [depends-on: #3769, blocks #2706] Feb 25, 2019
@TGWDB
Copy link
Contributor

TGWDB commented May 3, 2023

Closing due to age (no further comment on PR content), please reopen with rebase on develop if you intent to continue this work.

@TGWDB TGWDB closed this May 3, 2023
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.

6 participants