Skip to content

Adds the notion of a local write set to contracts #6331

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

Merged
merged 7 commits into from
Sep 14, 2021

Conversation

feliperodri
Copy link
Collaborator

@feliperodri feliperodri commented Sep 3, 2021

Signed-off-by: Felipe R. Monteiro felisous@amazon.com

  • Each commit message has a non-empty body, explaining why the change was made.
  • Methods or procedures I have added are documented, following the guidelines provided in CODING_STANDARD.md.
  • The feature or user visible behaviour I have added or modified has been documented in the User Guide in doc/cprover-manual/
  • Regression or unit tests are included, or existing tests cover the modified code (in this case I have detailed which ones those are in the commit message).
  • My commit message includes data points confirming performance improvements (if claimed).
  • My PR is restricted to a single feature or bugfix.
  • White-space or formatting changes outside the feature-related changed lines are in commits of their own.

@feliperodri feliperodri added aws Bugs or features of importance to AWS CBMC users Code Contracts Function and loop contracts labels Sep 3, 2021
@feliperodri feliperodri self-assigned this Sep 3, 2021
@codecov
Copy link

codecov bot commented Sep 3, 2021

Codecov Report

Merging #6331 (ea82b03) into develop (aeba3f0) will increase coverage by 0.00%.
The diff coverage is 96.94%.

❗ Current head ea82b03 differs from pull request most recent head 39c62dd. Consider uploading reports for the commit 39c62dd to get more accurate results
Impacted file tree graph

@@           Coverage Diff            @@
##           develop    #6331   +/-   ##
========================================
  Coverage    75.89%   75.90%           
========================================
  Files         1515     1515           
  Lines       163972   163990   +18     
========================================
+ Hits        124444   124473   +29     
+ Misses       39528    39517   -11     
Impacted Files Coverage Δ
src/goto-instrument/contracts/contracts.h 100.00% <ø> (ø)
src/goto-instrument/contracts/assigns.cpp 94.44% <94.59%> (-3.34%) ⬇️
src/goto-instrument/contracts/assigns.h 100.00% <100.00%> (ø)
src/goto-instrument/contracts/contracts.cpp 94.93% <100.00%> (+2.59%) ⬆️
src/util/simplify_expr.cpp 84.71% <100.00%> (ø)
src/goto-programs/goto_program.h 89.30% <0.00%> (-0.20%) ⬇️
src/goto-checker/report_util.cpp 62.31% <0.00%> (+0.28%) ⬆️

Continue to review full report at Codecov.

Legend - Click here to learn more
Δ = absolute <relative> (impact), ø = not affected, ? = missing data
Powered by Codecov. Last update 14d35cc...39c62dd. Read the comment docs.

Copy link
Contributor

@TGWDB TGWDB left a comment

Choose a reason for hiding this comment

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

Good to have a regression test (and the test looks good), please put the information from the test description comment close to where it would be found/used by a developer (to explain why the code works the way it does).

@feliperodri feliperodri changed the title Adds regression test for contract enforcement Removes deallocated objects from write set Sep 13, 2021
@feliperodri
Copy link
Collaborator Author

@SaswatPadhi could you take another look at it?

@SaswatPadhi SaswatPadhi added bugfix and removed Tests labels Sep 13, 2021
Copy link
Contributor

@SaswatPadhi SaswatPadhi left a comment

Choose a reason for hiding this comment

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

I am leaving some initial comments below, but I think we should discuss these two sets that are being maintained within assigns clause now. I think an assigns clause should just refer to the assigns clause on a function / loop -- it shouldn't be modified with other stuff.

We could create a separate class, may be called assignable_set, which would represent a union of the assigns clause + freely assignable local symbols. Let's discuss more offline.

^SIGNAL=0$
^VERIFICATION SUCCESSFUL$
^\[foo.\d+\] line \d+ Check that z is assignable: FAILURE$
^.* 1 of \d+ failed \(\d+ iteration.*\)$
Copy link
Contributor

Choose a reason for hiding this comment

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

Same comment. Why are we checking 1 out of "anything"?

Copy link
Contributor

Choose a reason for hiding this comment

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

Thanks for explaining offline. Resolving this.

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

For this case, it's OK to track 1 of "anything". Pointer primitive check can generate many properties to check and I want to make sure that there is only 1 failure: Check that z is assignable.

Copy link
Contributor

Choose a reason for hiding this comment

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

I am a little confused as to why only 1 assertion fails here though.

The assigns clause for foo doesn't have z, nor does it have *z. So shouldn't we fail 2 assertions:

  1. the containment check @ assignment z = malloc...
  2. the subset check @ call baz() in the next line (which has *z in the assign clause for baz but not foo)?

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

We discussed this offline. Two important points:

  1. There is no containment check here, malloc is not treated as a normal function call.
  2. There is a bug in checking the subset relation which is not stressed by this test case. We will address it on a separate PR.

Copy link
Contributor

Choose a reason for hiding this comment

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

There is no containment check here, malloc is not treated as a normal function call.

Hmm, but malloc just returns a fresh allocation, the left-hand side of the assignment in z = malloc..., i.e. the variable z, must be checked for containment in the assigns clause.

There is a bug in checking the subset relation which is not stressed by this test case. We will address it on a separate PR.

On digging a little bit deeper, I realized that the we don't actually need to separately check the assigns clause during replacement. We can go ahead and havoc directly, and those havocs would fail if something is not assignable in the calling context.

Anything that is local, including local allocations
are now tracked by our freely assignable set.

Signed-off-by: Felipe R. Monteiro <felisous@amazon.com>
Signed-off-by: Felipe R. Monteiro <felisous@amazon.com>
Copy link
Contributor

@SaswatPadhi SaswatPadhi left a comment

Choose a reason for hiding this comment

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

Some more comments.

Signed-off-by: Felipe R. Monteiro <felisous@amazon.com>
Signed-off-by: Felipe R. Monteiro <felisous@amazon.com>
…bles

Signed-off-by: Felipe R. Monteiro <felisous@amazon.com>
@feliperodri feliperodri changed the title Removes deallocated objects from write set Adds the notion of a local write set to contracts Sep 13, 2021
Copy link
Contributor

@SaswatPadhi SaswatPadhi left a comment

Choose a reason for hiding this comment

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

Thanks! :) A few last comments

{
b = 1;
c = 2;
*points_to_b = 1;
Copy link
Contributor

Choose a reason for hiding this comment

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

Nice test case! We are now correctly looking at assignable (and freely assignable) "addresses" instead of symbols :)

Signed-off-by: Felipe R. Monteiro <felisous@amazon.com>
Copy link
Contributor

@SaswatPadhi SaswatPadhi left a comment

Choose a reason for hiding this comment

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

Awesome 🎉

2 comments on the regression tests, but otherwise LGTM.

^SIGNAL=0$
^VERIFICATION SUCCESSFUL$
^\[foo.\d+\] line \d+ Check that z is assignable: FAILURE$
^.* 1 of \d+ failed \(\d+ iteration.*\)$
Copy link
Contributor

Choose a reason for hiding this comment

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

I am a little confused as to why only 1 assertion fails here though.

The assigns clause for foo doesn't have z, nor does it have *z. So shouldn't we fail 2 assertions:

  1. the containment check @ assignment z = malloc...
  2. the subset check @ call baz() in the next line (which has *z in the assign clause for baz but not foo)?

Signed-off-by: Felipe R. Monteiro <felisous@amazon.com>
@feliperodri feliperodri merged commit 7435884 into diffblue:develop Sep 14, 2021
@feliperodri feliperodri deleted the handle-free branch September 14, 2021 19:15
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
aws Bugs or features of importance to AWS CBMC users bugfix Code Contracts Function and loop contracts
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants