Skip to content
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

Heapster Widening and Implication Prover Improvements #1796

Merged
merged 6 commits into from
Jan 5, 2023

Conversation

eddywestbrook
Copy link
Contributor

This PR includes 3 relatively small changes to Heapster to help in verifying some (somewhat) "real world" C code:

  • Enhanced widening so that memblock permissions with eqsh shapes can be widening by substituting in shape of the equal block for the eqsh shape;
  • Updated widening so it unfolds conjunctive permissions when widening atomic permissions; and
  • Updated recombinePerm to handle more cases with named permissions.

Copy link
Contributor

@RyanGlScott RyanGlScott left a comment

Choose a reason for hiding this comment

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

I don't have much insight into how this code works, but here are two things that I noticed after a quick look.

Comment on lines +4782 to +4787
splitLLVMBlockPerm blsubst off bp@(llvmBlockShape ->
PExpr_EqShape _len (PExpr_Var b))
-- FIXME: make sure the returned shape fits into len bytes!
| Just sh <- blsubst b
= splitLLVMBlockPerm blsubst off (bp { llvmBlockShape = sh })
splitLLVMBlockPerm _ _ (llvmBlockShape -> PExpr_EqShape _ _) = Nothing
Copy link
Contributor

Choose a reason for hiding this comment

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

Nit pick: combine the two llvmBlockShape -> PExpr_EqShape ... cases:

Suggested change
splitLLVMBlockPerm blsubst off bp@(llvmBlockShape ->
PExpr_EqShape _len (PExpr_Var b))
-- FIXME: make sure the returned shape fits into len bytes!
| Just sh <- blsubst b
= splitLLVMBlockPerm blsubst off (bp { llvmBlockShape = sh })
splitLLVMBlockPerm _ _ (llvmBlockShape -> PExpr_EqShape _ _) = Nothing
splitLLVMBlockPerm blsubst off bp@(llvmBlockShape ->
PExpr_EqShape _len (PExpr_Var b))
-- FIXME: make sure the returned shape fits into len bytes!
| Just sh <- blsubst b
= splitLLVMBlockPerm blsubst off (bp { llvmBlockShape = sh })
| otherwise
= Nothing

Aside from making this slightly more readable, this should be a little easier for GHC's pattern-match coverage checker to handle.

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 see what you mean, that it's weird to use a view pattern with a record accessor. I'll fix that.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Wait, except I guess that's not what you were suggesting. I guess you were suggesting I use an otherwise branch of the pattern-match. That's not actually quite correct, because that would only match when the second argument to PExpr_EqShape is of the form PExpr_Var b, whereas the current version doesn't match on that argument at all in this case. TBF, PExpr_Var b is the only PermExpr expression that can match at that particular type.

Maybe this is all bikeshedding, because there already is a catch-all case at the end of the function?

Copy link
Contributor

Choose a reason for hiding this comment

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

Ah, quite right. Indeed, you would need to move the match on PExpr_Var into a pattern guard to preserve the existing semantics of this function:

Suggested change
splitLLVMBlockPerm blsubst off bp@(llvmBlockShape ->
PExpr_EqShape _len (PExpr_Var b))
-- FIXME: make sure the returned shape fits into len bytes!
| Just sh <- blsubst b
= splitLLVMBlockPerm blsubst off (bp { llvmBlockShape = sh })
splitLLVMBlockPerm _ _ (llvmBlockShape -> PExpr_EqShape _ _) = Nothing
splitLLVMBlockPerm blsubst off bp@(llvmBlockShape ->
PExpr_EqShape _len blk)
-- FIXME: make sure the returned shape fits into len bytes!
| PExpr_Var b <- blk
, Just sh <- blsubst b
= splitLLVMBlockPerm blsubst off (bp { llvmBlockShape = sh })
| otherwise
= Nothing

I'll let you make the call on whether the old or new code is more readable.

Comment on lines 4848 to 4853
do (bp_l,bp') <- splitLLVMBlockPerm (const Nothing) (bvRangeOffset rng) bp
return ([bp_l],bp')
else return ([],bp)
bp_r <-
if bvInRange (bvRangeEnd rng) (llvmBlockRange bp) then
snd <$> splitLLVMBlockPerm (bvRangeEnd rng) bp
snd <$> splitLLVMBlockPerm (const Nothing) (bvRangeEnd rng) bp
Copy link
Contributor

Choose a reason for hiding this comment

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

Is it worth commenting why these two calls to splitLLVMBlockPerm have empty substitutions?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Fair enough, I can do that

@eddywestbrook eddywestbrook added PR: ready to merge Magic flag for pull requests to ask Mergify to merge given an approval and a successful CI run subsystem: heapster Issues specifically related to memory verification using Heapster labels Jan 5, 2023
@mergify mergify bot merged commit a63a2f4 into master Jan 5, 2023
@mergify mergify bot deleted the heapster/widening-eqsh branch January 5, 2023 21:25
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
PR: ready to merge Magic flag for pull requests to ask Mergify to merge given an approval and a successful CI run subsystem: heapster Issues specifically related to memory verification using Heapster
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants