-
Notifications
You must be signed in to change notification settings - Fork 26
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
Fix empty PVL enums causing verification failure #1248
Conversation
This is a decent hotfix. The only thing I'm wondering about is whether it should actually be stronger, i.e. if you have an instance of EmptyEnum you should be able to prove false:
I'm not sure how to encode that without viper/z3 picking up this fact without even mentioning |
Actually, you can also assign
Would you mind trying this change out? It's especially important that it doesn't make (false) asserts in unrelated methods suddenly pass, but with the null check in place that should be fine. |
Thanks for taking a look! It looks like the fact that enums can be null is encoded as an Indeed it would be nice if VerCors could prove no instances of With the suggested change, a number of tests break (both Java and PVL). If I try to verify the program from above, the axiom becomes:
I get:
I can find |
You can still refer to another type (i.e. That warning comes from the decreases clauses on these functions. Recently those were changed to no longer count as preconditions for this check but we haven't changed to that viper version yet but it's fine to ignore those warnings for now. |
I think this requires a little bit more design work. Initially I intended for the COL enum type to be more of a mathematical enum type, meaning you can have an empty enum, and having an instance of that would allow you to prove false. Obviously I never got that far :) In addition, the implementation encodes enums as a domain, and (correct me if I'm wrong) in silicon/z3 domains are assumed to be inhabited. So that makes it a bit difficult to get the behaviour we want with a small fix. Or at least, in terms of design, it's not really clear to me what needs to change. In addition, Java allows empty enums, so that's actually a shortcoming of the frontend. Writing the enum axioms over the type @wandernauta If you have time to redesign the enum implementation more thoroughly you are welcome to do so. It would be nice to have an internal enum type that is a bit more well founded. But otherwise, if we just want VerCors to behave sane without too much effort, I think it may be best do just disallow empty enums in PVL for now, like we do in the Java frontend. AFIAK I don't think anyone really depends on it. If you could change your PR to reflect that that'd be nice. In addition, we should probably fix the SatCheck pass/default constructor generation code to generate a sane error message when a false axiom is added. (#1255) |
This sounds good to me, especially since it doesn't hinder making Would it be sufficient to do this at the grammar level (so an empty enum would error
Will do! |
Probably the best place to do this is in PVLToCol.scala. You can find examples that use the |
An enum that does not define any enumeration constants is now a parse error.
38389e7
to
d2c1d40
Compare
Looks finished. Please confirm, then I'll merge it. |
Yep! I think this should do it. Thanks for your help! |
The PVL grammar (but not other front-ends) allows writing enumerations with no constants:
However, the
toIntRange
axiom that theEnumToDomain
pass encodes for such an enum doesn't obviously hold, which causes verification of any program with such an enum to fail, for instance:This change makes it so that this specific axiom is omitted for empty enums.
Also adds a test that a snippet like the above should verify.
Front-ends are unchanged; for example, the Java frontend still rejects empty enums.
Pre-fix crash log for reference