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

When is the Position of an AST node mandatory? #732

Closed
fpoli opened this issue Jun 22, 2023 · 6 comments
Closed

When is the Position of an AST node mandatory? #732

fpoli opened this issue Jun 22, 2023 · 6 comments
Labels
question Further information is requested

Comments

@fpoli
Copy link
Member

fpoli commented Jun 22, 2023

In Prusti, we only generate Position instances (with a unique line, column and ID) for the AST nodes that we know might be the offending node of a verification error. Sometimes, we also generate positions for the AST nodes that we know might be the reason of a verification error. For any other AST node we generate a dummy position where the line and column are zero.

This worked well so far when using Silicon configured to report one verification error per method. However, when we configure Silicon to report multiple verification errors we still only receive one verification error per method. Aurel found that by removing .distinctBy(failureFilterAndGroupingCriterion) we actually get all the errors that we expect, but I then wonder why the deduplication is there in the first place.

I have a few questions about this:

  • What are the AST nodes from which Silicon takes the position used to deduplicate verification errors?
  • In general, what is the minimum set of AST nodes for which a frontend should generate unique positions?
  • Why is there a deduplication of verification errors in Silicon? Is it perhaps no longer needed?
@fpoli fpoli added the question Further information is requested label Jun 22, 2023
@marcoeilers
Copy link
Contributor

  • Why is there a deduplication of verification errors in Silicon? Is it perhaps no longer needed?

My guess would be that deduplication is used because you're likely to get the exact same error on multiple paths (because you reach e.g. the same assert statement that fails on different paths).

  • What are the AST nodes from which Silicon takes the position used to deduplicate verification errors?

It seems to be the position that would be reported for the error, which as far as I can see is always the position of the offendingNode. What AST node is used for that will depend on the type of error, so that question doesn't have a short answer.

  • In general, what is the minimum set of AST nodes for which a frontend should generate unique positions?

I don't think that question has an answer. Silicon works (as in, doesn't crash or do anything unsound) without unique positions, as you see, it just filters out all errors that would have the same exact error message.
Obviously we could add a switch to disable error deduplication (that seems to make a lot of sense in general) or somehow make error deduplication more configurable.

What I don't understand is this:
If your errors are filtered out, then that must mean that they have the same position, so the offendingNodes must have the same position, which suggests that actually they don't have unique positions (or at least the string version of the positions is not unique).

@fpoli
Copy link
Member Author

fpoli commented Jun 26, 2023

If your errors are filtered out, then that must mean that they have the same position, so the offendingNodes must have the same position, which suggests that actually they don't have unique positions (or at least the string version of the positions is not unique).

Yes, which means that we are generating dummy positions for AST nodes for which we should instead generate unique positions. Knowing that those are the offendingNodes helps, thanks!

Last question, then we can close:

@marcoeilers
Copy link
Contributor

My impression was that the important thing is that position.toString() is unique. So if the string representation contains line, column, and ID, then making any of those unique would suffice. But I guess the ID is something Prusti-specific? I think that's not a part of a standard Viper position. So I don't know what the implementation of toString for your Position class does.

@fpoli
Copy link
Member Author

fpoli commented Jun 26, 2023

Are you sure that it's the toString of a position that is used to deduplicate the errors? I thought that failureFilterAndGroupingCriterion, by calling readableMessage(withId = true, withPosition = true), always uses the implementation at AbstractVerificationError::readableMessage, which should always take into account the ID.

All positions constructed by Prusti are instances of Silver's IdentifierPosition; by ID I always mean that identifier. I now notice that IdentifierPosition does not override the toString defined in HasLineColumn, so the resulting string does not depend on the ID stored in IdentifierPosition. However, I think that this does not affect the deduplication.

@marcoeilers
Copy link
Contributor

I assumed withId referred to the ID of the type of error, e.g., assert.failed:insufficient.permission. Since positions in general don't have an ID.

@fpoli
Copy link
Member Author

fpoli commented Jun 26, 2023

Oooh, you mean that withId in readableMessage(withId = true, withPosition = true) refers to the "assert.failed:insufficient.permission" ID and not to the ID of IdentifierPosition instances. That explains a lot of weird things!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
question Further information is requested
Projects
None yet
Development

No branches or pull requests

2 participants