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

Avoid base invariant fallback not understood message on reflexive pointer literal equality #1396

Merged
merged 4 commits into from
Apr 4, 2024

Conversation

sim642
Copy link
Member

@sim642 sim642 commented Mar 21, 2024

Closes #1374.

The fix is uglier than I imagined it to be because address set refinement happens in invariant_fallback, not in the general inv_exp, so it doesn't simply fall into the existing

| Const _ , _ -> st (* nothing to do *)

A less ugly fix would be to make inv_exp also do addresses with HC4-revise, but that requires carefully porting all the ancient fallback logic with countless edge cases.

@sim642 sim642 added this to the v2.4.0 milestone Mar 21, 2024
@michael-schwarz michael-schwarz self-requested a review March 21, 2024 16:00
@michael-schwarz
Copy link
Member

michael-schwarz commented Mar 21, 2024

Maybe the fix should also attempt to forgo emitting these: Tasking the event system with what we know to be a fool's errand, might have a performance impact. While it will most likely be very small, it's probably still worth doing as it'll be very little extra work to add this check.

Also, I am not entirely convinced by the usage of polymorphic variants here yet. I guess the only difference to normal variants here is that NothingToRefine cannot be emitted by helper. Is this really an important invariant that we want to enforce (and are worth paying the penalty for less efficient code for it, provided this is still the case after flambda)?

@sim642
Copy link
Member Author

sim642 commented Mar 21, 2024

Also, I am not entirely convinced by the usage of polymorphic variants here yet. I guess the only difference to normal variants here is that NothingToRefine cannot be emitted by helper. Is this really an important invariant that we want to enforce (and are worth paying the penalty for less efficient code for it, provided this is still the case after flambda)?

The use of polymorphic variants doesn't actually change the memory representations here: argument-less polymorphic variants are unboxed integers like normal variants and a polymorphic variant with two arguments is really a block with a reference to a pair block, but that was also the case before with a pair option.

@michael-schwarz
Copy link
Member

Besides the point but still interesting:

The use of polymorphic variants doesn't actually change the memory representations here: [...] a polymorphic variant with two arguments is really a block with a reference to a pair block, but that was also the case before with a pair option.

Interesting, do you have a reference for this? RealWorldOCaml seems to disagree:

Polymorphic variants use more memory space than normal variants when parameters are included in the data type constructors. Normal variants use the tag byte to encode the variant value and save the fields for the contents, but this single byte is insufficient to encode the hashed value for polymorphic variants. They must allocate a new block (with tag 0) and store the value in there instead. Polymorphic variants with constructors thus use one word of memory more than normal variant constructors.

https://dev.realworldocaml.org/runtime-memory-layout.html

I would read this as:

  • (x * y ) option
    - 1 block for the pointer to the tuple, and Some vs None expressed in the tag
    - 1 block for the tuple itself
    - + memory for x and y

@sim642
Copy link
Member Author

sim642 commented Mar 21, 2024

Polymorphic variants with constructors thus use one word of memory more than normal variant constructors.

Normal variants flatten their arguments instead of storing a tuple, so what this is saying is that `Refine of lval * value uses one block more than Refine of lval * value would. But also Refine of (lval * value) would use one block more for the pair which it explicitly contains. And that by abstraction is the same as (lval * value) option.

Copy link
Member

@michael-schwarz michael-schwarz left a comment

Choose a reason for hiding this comment

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

I added the code that prevents emitting refines of form &a==&a in the first place and tested it by checking that the error messages disappear on master (which doesn't have the rest of this PR) with this change.

@michael-schwarz
Copy link
Member

The atomic privatizations added in the course of #1216 seem to depend on the refine event being emitted for &a == &a. That seems very strange.

@sim642
Copy link
Member Author

sim642 commented Mar 28, 2024

The atomic privatizations added in the course of #1216 seem to depend on the refine event being emitted for &a == &a. That seems very strange.

That's odd indeed. Maybe it has something to do with the special atomic lock somehow.

@sim642
Copy link
Member Author

sim642 commented Apr 4, 2024

I extracted the optimization to #1407 to get approved thing merged.

@sim642 sim642 merged commit 2cbdc03 into master Apr 4, 2024
38 checks passed
@sim642 sim642 deleted the issue-1374-2 branch April 4, 2024 13:22
sim642 added a commit that referenced this pull request Apr 4, 2024
sim642 added a commit to sim642/opam-repository that referenced this pull request Aug 2, 2024
CHANGES:

* Remove unmaintained analyses: spec, file (goblint/analyzer#1281).
* Add linear two-variable equalities analysis (goblint/analyzer#1297, goblint/analyzer#1412, goblint/analyzer#1466).
* Add callstring, loopfree callstring and context gas analyses (goblint/analyzer#1038, goblint/analyzer#1340, goblint/analyzer#1379, goblint/analyzer#1427, goblint/analyzer#1439).
* Add non-relational thread-modular value analyses with thread IDs (goblint/analyzer#1366, goblint/analyzer#1398, goblint/analyzer#1399).
* Add NULL byte array domain (goblint/analyzer#1076).
* Fix spurious overflow warnings from internal evaluations (goblint/analyzer#1406, goblint/analyzer#1411, goblint/analyzer#1511).
* Refactor non-definite mutex handling to fix unsoundness (goblint/analyzer#1430, goblint/analyzer#1500, goblint/analyzer#1503, goblint/analyzer#1409).
* Fix non-relational thread-modular value analysis unsoundness with ambiguous points-to sets (goblint/analyzer#1457, goblint/analyzer#1458).
* Fix mutex type analysis unsoundness and enable it by default (goblint/analyzer#1414, goblint/analyzer#1416, goblint/analyzer#1510).
* Add points-to set refinement on mutex path splitting (goblint/analyzer#1287, goblint/analyzer#1343, goblint/analyzer#1374, goblint/analyzer#1396, goblint/analyzer#1407).
* Improve narrowing operators (goblint/analyzer#1502, goblint/analyzer#1540, goblint/analyzer#1543).
* Extract automatic configuration tuning for soundness (goblint/analyzer#1369).
* Fix many locations in witnesses (goblint/analyzer#1355, goblint/analyzer#1372, goblint/analyzer#1400, goblint/analyzer#1403).
* Improve output readability (goblint/analyzer#1294, goblint/analyzer#1312, goblint/analyzer#1405, goblint/analyzer#1497).
* Refactor logging (goblint/analyzer#1117).
* Modernize all library function specifications (goblint/analyzer#1029, goblint/analyzer#688, goblint/analyzer#1174, goblint/analyzer#1289, goblint/analyzer#1447, goblint/analyzer#1487).
* Remove OCaml 4.10, 4.11, 4.12 and 4.13 support (goblint/analyzer#1448).
avsm pushed a commit to avsm/opam-repository that referenced this pull request Sep 5, 2024
CHANGES:

* Remove unmaintained analyses: spec, file (goblint/analyzer#1281).
* Add linear two-variable equalities analysis (goblint/analyzer#1297, goblint/analyzer#1412, goblint/analyzer#1466).
* Add callstring, loopfree callstring and context gas analyses (goblint/analyzer#1038, goblint/analyzer#1340, goblint/analyzer#1379, goblint/analyzer#1427, goblint/analyzer#1439).
* Add non-relational thread-modular value analyses with thread IDs (goblint/analyzer#1366, goblint/analyzer#1398, goblint/analyzer#1399).
* Add NULL byte array domain (goblint/analyzer#1076).
* Fix spurious overflow warnings from internal evaluations (goblint/analyzer#1406, goblint/analyzer#1411, goblint/analyzer#1511).
* Refactor non-definite mutex handling to fix unsoundness (goblint/analyzer#1430, goblint/analyzer#1500, goblint/analyzer#1503, goblint/analyzer#1409).
* Fix non-relational thread-modular value analysis unsoundness with ambiguous points-to sets (goblint/analyzer#1457, goblint/analyzer#1458).
* Fix mutex type analysis unsoundness and enable it by default (goblint/analyzer#1414, goblint/analyzer#1416, goblint/analyzer#1510).
* Add points-to set refinement on mutex path splitting (goblint/analyzer#1287, goblint/analyzer#1343, goblint/analyzer#1374, goblint/analyzer#1396, goblint/analyzer#1407).
* Improve narrowing operators (goblint/analyzer#1502, goblint/analyzer#1540, goblint/analyzer#1543).
* Extract automatic configuration tuning for soundness (goblint/analyzer#1369).
* Fix many locations in witnesses (goblint/analyzer#1355, goblint/analyzer#1372, goblint/analyzer#1400, goblint/analyzer#1403).
* Improve output readability (goblint/analyzer#1294, goblint/analyzer#1312, goblint/analyzer#1405, goblint/analyzer#1497).
* Refactor logging (goblint/analyzer#1117).
* Modernize all library function specifications (goblint/analyzer#1029, goblint/analyzer#688, goblint/analyzer#1174, goblint/analyzer#1289, goblint/analyzer#1447, goblint/analyzer#1487).
* Remove OCaml 4.10, 4.11, 4.12 and 4.13 support (goblint/analyzer#1448).
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Reflexive pointer literal equality not understood
2 participants