-
Notifications
You must be signed in to change notification settings - Fork 277
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
Conversation
4f29797
to
1db3e27
Compare
Codecov Report
@@ Coverage Diff @@
## develop #6331 +/- ##
========================================
Coverage 75.89% 75.90%
========================================
Files 1515 1515
Lines 163972 163990 +18
========================================
+ Hits 124444 124473 +29
+ Misses 39528 39517 -11
Continue to review full report at Codecov.
|
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.
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).
1db3e27
to
90b82d1
Compare
@SaswatPadhi could you take another look at it? |
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 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.*\)$ |
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 comment. Why are we checking 1
out of "anything"?
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.
Thanks for explaining offline. Resolving this.
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.
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
.
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 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:
- the containment check @ assignment
z = malloc...
- the subset check @ call
baz()
in the next line (which has*z
in the assign clause forbaz
but notfoo
)?
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 discussed this offline. Two important points:
- There is no containment check here,
malloc
is not treated as a normal function call. - 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.
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 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>
90b82d1
to
c06ccf1
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.
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>
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.
Thanks! :) A few last comments
{ | ||
b = 1; | ||
c = 2; | ||
*points_to_b = 1; |
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.
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>
37bed13
to
6d86395
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.
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.*\)$ |
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 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:
- the containment check @ assignment
z = malloc...
- the subset check @ call
baz()
in the next line (which has*z
in the assign clause forbaz
but notfoo
)?
Signed-off-by: Felipe R. Monteiro <felisous@amazon.com>
ea82b03
to
39c62dd
Compare
Signed-off-by: Felipe R. Monteiro felisous@amazon.com