-
Notifications
You must be signed in to change notification settings - Fork 88
Description
@stilscher and I discovered the following problem: Superstable contains too many things which causes spurious warnings to remain after an incremental run in cases where code is no longer reachable after the patch.
The fundamental issue is that we do not destabilize (and don't want to) into function calls (of unchanged functions) that no longer happen (or do at least no longer happen in a given context). Hence the unknowns corresponding to such code remain superstable and the warnings are re-used.
I added an example to this branch where a call to a function is removed so an entire function becomes uncalled: https://github.com/goblint/analyzer/tree/interactive_postsolver_pruning
It behaves as expected when one disables the incremental post-solver.
The same issue happens also when only certain calling contexts go away.
Short of a full reachability or horrible hacks where one destabilizes every unknown that is no longer queried at calls, it does not seem obvious how to fix this.
One way that I am currently investigating (suggested by Helmut) is doing a lightweight full reachability where we record for each unknown the set of unknowns its last evaluation depended on. This way, one does not have to execute all the right-hand sides for reachability. For those things that are reachable & superstable, I can reuse the old warnings and accesses, for those things that are reachable and not superstable, I then need to execute the right-hand sides as I currently do.
This is reasonable if most time in the post-solver is spent executing right-hand sides instead of doing reachability.