All the definitions of `greaterThan` were `!lowerThanOrEqual`, and all
the uses were implicitly assuming this semantic.
However, this was confusing because in a Lattice the ordering is not
total, hence `!lowerThanOrEqual` is not equivalent to `greaterThan`.
This commit drops the `greaterThan` method altogether to avoid
confusion.
This commit introduces the helper templated struct InterruptCreator,
that is used to provide defaults for the methods
MonotoneFramework::createSummaryInterrupt() and
MonotoneFramework::createNoReturnInterrupt() whenever the Interrupt
template parameter for Monotoneframework is of type
DefaultInterrupt<LatticeElement>.
This frees the implementor of a new MonotoneFramework from the need
to implement those methods in the most common cases.
Whenever Interrupt is DefaultInterrupt<LatticeElement>,
MonotoneFramework::createSummaryInterrupt() aborts, since a summary
should never be generated for those kind of analyses.
Instead, MonotoneFramework::createNoReturnInterrupt() generates a
default Interrupt, since it will never be used.
In most cases, a user of MonotoneFramework does not need a
interprocedural analysis, nor an analysis whose results on
terminal labels have to be aggregated in a FinalResults.
DefaultInterrupt<LatticeElement> is designed exactly for those
cases, and is hence used as default template parameter for
MonotoneFramework.
This class provides the simplest possible implementation for an Interrupt
for a Monotone Framework.
In particular this interrupt is suitable for MonotoneFrameworks that are NOT
interprocedural, and that DO NOT need to combine all the results on the
terminal labels at the end of the analysis in a single FinalResult.
With these assumption, the resulting Interrupt is pretty simple and it just
forwards the results of the transfer function.
The MonotoneFrameworkSet class had two sets of methods, one for handling
set operations on it, the other handling lattice ordering.
It also silently assumed that the lattice combine operation was the set
union, which is not true in general.
This commit decouples the set operations from the lattice operations.
This allows to provide two separate implementations of
IntersectionMonotoneSet (for which the compbine operation is the set
intersection) and UnionMonotoneSet (for which the combine operation is
the set union).
Before this change, `EnforceCFGCombingPass` was occasionally failing on
`verifyModule` if called from Caliban, with mismatches in the
`llvm.dbg.cu` debug metadata.
This metadata is a list of `DICompileUnit`, and `verifyModule` was
failing inside `verifyCompileUnits` because some of the visited compile
unit during the verify were not listed in `llvm.dbg.cu`.
One of the reasons of this problem might be that during
the enforcing we clone many things in the enforced function, and this
may cause the cloned stuff not to update the metadata accordingly.
I couldn't track down if this was caused by my misuse of LLVM's API for
cloning, of to some actual bug in LLVM.
In the end I couldn't find out the exact cause and fix it, so this
commit is a workaround. It adds a dependency on `RemoveDbgMetadata`, so
that the debug metadata causing `verifyModule` to fail are removed
before the enforcing, hence preventing things going astray during the
enforcing, and fixing the failure.
This workaround should be fine, because this is one of the last steps
before generating C code, and debug info are note serialized to C
anyway.
Added a pass that removes the `bad_return_pc` check, which is useful
only when we want to preserve semantics, but it is useless and harmful
for decompilation.