Attaching an instance of UndefinedBehavior leads to much more comprehensive error messages down the line, e.g. the message will cite a part of the C standard.
It makes the error programatically inspectable. This capability is used extensively in uc-crux-llvm.
One issue I see in Translation.Instruction in particular is that the main way to attach instances of UndefinedBehavior is via side-conditions, whereas in some cases functions like caseptr have been used to the point where the behavior is always undefined in the given branch (the reportError example linked above is an instance of this). In this case, there's no sensible value to return.
There are two approaches I can see to address this:
Manufacture arbitrary values, and attach an always-false side condition to them. This is a bit inelegant since the value doesn't matter.
Refactor the code in question to not branch with functions like caseptr so that a meaningful predicate/value pair can be constructed. This seems like a lot of work, and like it could lead to less readable code.
Create a new constructor for LLVM expressions that expresses the notion that the value is always undefined.
In addition to reportError, assertExpr is used a lot (indirectly through pointerAsBitvectorExpr) where it would be nice to have a side condition instead.
There are a few spots in LLVM module translation where functions like
reportError
are used:https://github.com/GaloisInc/crucible/blob/a42ef5b65faea52d3530d53ed7ac800a3a14f1e3/crucible-llvm/src/Lang/Crucible/LLVM/Translation/Instruction.hs#L1210-L1215
where it may be better to use something that attaches an
UndefinedBehavior
, likepoisonSideCondition
:https://github.com/GaloisInc/crucible/blob/a42ef5b65faea52d3530d53ed7ac800a3a14f1e3/crucible-llvm/src/Lang/Crucible/LLVM/Translation/Instruction.hs#L118-L127
This would be good for two reasons:
UndefinedBehavior
leads to much more comprehensive error messages down the line, e.g. the message will cite a part of the C standard.uc-crux-llvm
.One issue I see in
Translation.Instruction
in particular is that the main way to attach instances ofUndefinedBehavior
is via side-conditions, whereas in some cases functions likecaseptr
have been used to the point where the behavior is always undefined in the given branch (thereportError
example linked above is an instance of this). In this case, there's no sensible value to return.There are two approaches I can see to address this:
caseptr
so that a meaningful predicate/value pair can be constructed. This seems like a lot of work, and like it could lead to less readable code.