tcExpr( bb, stmt, d->guard, gWordTy );
if (typeOfIRExpr(tyenv, d->guard) != Ity_I1)
sanityCheckFail(bb,stmt,"IRStmt.Dirty.guard not :: Ity_I1");
- /* A dirty helper that is executed conditionally (or not at all)
- AND returns a value is not handled properly. */
- if (d->tmp != IRTemp_INVALID &&
- (d->guard->tag != Iex_Const || d->guard->Iex.Const.con->Ico.U1 == 0))
+ /* A dirty helper that is executed conditionally (or not at
+ all) may not return a value. Hence if .tmp is not
+ IRTemp_INVALID, .guard must be manifestly True at JIT
+ time. */
+ if (d->tmp != IRTemp_INVALID
+ && (d->guard->tag != Iex_Const
+ || d->guard->Iex.Const.con->Ico.U1 == 0))
sanityCheckFail(bb,stmt,"IRStmt.Dirty with a return value"
" is executed under a condition");
/* check types, minimally */
typedef
struct _IRDirty {
- /* What to call, and details of args/results */
+ /* What to call, and details of args/results. .guard must be
+ non-NULL. If .tmp is not IRTemp_INVALID (that is, the call
+ returns a result) then .guard must be demonstrably (at
+ JIT-time) always true, that is, the call must be
+ unconditional. Conditional calls that assign .tmp are not
+ allowed. */
IRCallee* cee; /* where to call */
IRExpr* guard; /* :: Ity_Bit. Controls whether call happens */
IRExpr** args; /* arg list, ends in NULL */