crucible-0.7: test/absint/Max.hs
-- | A domain for tracking the maximum value a register can take
--
-- This is intentionally a very tall domain so that widening is
-- required.
{-# LANGUAGE DataKinds #-}
{-# LANGUAGE GADTs #-}
{-# LANGUAGE KindSignatures #-}
{-# LANGUAGE RankNTypes #-}
{-# LANGUAGE StandaloneDeriving #-}
module Max (
Max(..), SyntaxExt,
maxDom,
maxInterp
) where
import qualified Data.Parameterized.Context as PU
import qualified Lang.Crucible.CFG.Core as C
import qualified Lang.Crucible.CFG.Expr as C
import Lang.Crucible.Analysis.Fixpoint
data Max (tp :: C.CrucibleType) where
Max :: Int -> Max tp
deriving instance Eq (Max tp)
deriving instance Show (Max tp)
instance C.ShowF Max
type Max' = Pointed Max
maxDom :: Domain Max'
maxDom = d
where
d = pointed j (==) (WTOWidening (>10) w)
j (Max i1) (Max i2) = Pointed (Max (max i1 i2))
w _ _ = Top
type SyntaxExt = ()
maxInterp :: Interpretation SyntaxExt Max'
maxInterp = Interpretation { interpExpr = mExpr
, interpExt = undefined
, interpCall = mCall
, interpReadGlobal = mRdGlobal
, interpWriteGlobal = mWrGlobal
, interpBr = mBr
, interpMaybe = mMaybe
}
mExpr :: ScopedReg
-> C.TypeRepr tp
-> C.Expr ext ctx tp
-> PointAbstraction blocks Max' ctx
-> (Maybe (PointAbstraction blocks Max' ctx), Max' tp)
mExpr _sr _tr (C.App e) abstr =
case e of
C.IntLit i -> (Nothing, Pointed (Max (fromIntegral i)))
C.IntAdd r1 r2 ->
let a1 = lookupAbstractRegValue abstr r1
a2 = lookupAbstractRegValue abstr r2
in case (a1, a2) of
(Pointed (Max m1), Pointed (Max m2)) -> (Nothing, Pointed (Max (m1 + m2)))
_ -> (Nothing, Top)
_ -> (Nothing, Top)
mCall :: C.CtxRepr args
-> C.TypeRepr ret
-> C.Reg ctx (C.FunctionHandleType args ret)
-> Max' (C.FunctionHandleType args ret)
-> PU.Assignment Max' args
-> PointAbstraction blocks dom ctx
-> (Maybe (PointAbstraction blocks Max' ctx), Max' ret)
mCall _ _ _ _ _ _ = (Nothing, Top)
mBr :: C.Reg ctx C.BoolType
-> Max' C.BoolType
-> C.JumpTarget blocks ctx
-> C.JumpTarget blocks ctx
-> PointAbstraction blocks Max' ctx
-> (Maybe (PointAbstraction blocks Max' ctx), Maybe (PointAbstraction blocks Max' ctx))
mBr _ _ _ _ _ = (Nothing, Nothing)
mMaybe :: C.TypeRepr tp
-> C.Reg ctx (C.MaybeType tp)
-> Max' (C.MaybeType tp)
-> PointAbstraction blocks Max' ctx
-> (Maybe (PointAbstraction blocks Max' ctx), Max' tp, Maybe (PointAbstraction blocks Max' ctx))
mMaybe _ _ _ _ = (Nothing, Top, Nothing)
mWrGlobal :: C.GlobalVar tp -> C.Reg ctx tp -> PointAbstraction blocks Max' ctx -> Maybe (PointAbstraction blocks Max' ctx)
mWrGlobal _ _ _ = Nothing
mRdGlobal :: C.GlobalVar tp -> PointAbstraction blocks Max' ctx -> (Maybe (PointAbstraction blocks Max' ctx), Max' tp)
mRdGlobal _ _ = (Nothing, Top)