{-# LANGUAGE PartialTypeSignatures, MultiParamTypeClasses, DeriveGeneric, DefaultSignatures, FlexibleContexts, Strict #-}
module Data.Pointers (
FContext (..),
mk_fcontext,
get_pointer_domain,
expr_highly_likely_pointer,
expr_is_global_pointer,
expr_is_highly_likely_local_pointer,
expr_is_global_immediate,
srcs_of_expr,
srcs_of_exprs,
is_known_source,
join_exprs,
join_single,
separate_pointer_domains,
pointer_bases_separate_necessarily,
pointer_bases_separate_possibly,
sources_separate_necessarily,
sources_separate_possibly,
necessarily_equal,
necessarily_equal_stateparts,
necessarily_separate,
necessarily_separate_stateparts,
necessarily_enclosed,
unfold_non_determinism,
trim_expr
)
where
import Analysis.Context
import Data.Binary
import Base
import Config
import Data.ControlFlow
import Data.SimplePred
import qualified Data.Map as M
import qualified Data.Set as S
import qualified Data.IntMap as IM
import qualified Data.IntSet as IS
import Data.List
import Data.Word
import Data.Maybe
import Debug.Trace
data FContext = FContext {
FContext -> Context
f_ctxt :: Context,
FContext -> Int
f_entry :: Int,
FContext -> String
f_name :: String,
FContext -> FInit
f_init :: FInit
}
mk_fcontext :: Context -> Int -> FContext
mk_fcontext :: Context -> Int -> FContext
mk_fcontext Context
ctxt Int
entry =
let f :: String
f = Context -> Int -> String
function_name_of_entry Context
ctxt Int
entry
finit :: Maybe FInit
finit = Int -> IntMap FInit -> Maybe FInit
forall a. Int -> IntMap a -> Maybe a
IM.lookup Int
entry (IntMap FInit -> Maybe FInit) -> IntMap FInit -> Maybe FInit
forall a b. (a -> b) -> a -> b
$ Context -> IntMap FInit
ctxt_finits Context
ctxt
fctxt :: FContext
fctxt = Context -> Int -> String -> FInit -> FContext
FContext Context
ctxt Int
entry String
f (Maybe FInit
finit Maybe FInit -> FInit -> FInit
forall p. Maybe p -> p -> p
`orElse` FInit
forall k a. Map k a
M.empty) in
FContext
fctxt
statepart_to_finit_expr :: FContext -> StatePart -> Maybe SimpleExpr
statepart_to_finit_expr :: FContext -> StatePart -> Maybe SimpleExpr
statepart_to_finit_expr FContext
ctxt StatePart
sp = StatePart -> FInit -> Maybe SimpleExpr
forall k a. Ord k => k -> Map k a -> Maybe a
M.lookup StatePart
sp (FInit -> Maybe SimpleExpr) -> FInit -> Maybe SimpleExpr
forall a b. (a -> b) -> a -> b
$ FContext -> FInit
f_init FContext
ctxt
get_pointer_domain ::
FContext
-> SimpleExpr
-> PointerDomain
get_pointer_domain :: FContext -> SimpleExpr -> PointerDomain
get_pointer_domain FContext
ctxt SimpleExpr
e =
let bs :: Set PointerBase
bs = Bool -> SimpleExpr -> Set PointerBase
get_pointer_bases' Bool
True (SimpleExpr -> Set PointerBase) -> SimpleExpr -> Set PointerBase
forall a b. (a -> b) -> a -> b
$ SimpleExpr -> SimpleExpr
simp SimpleExpr
e in
if Bool -> Bool
not (Set PointerBase -> Bool
forall a. Set a -> Bool
S.null Set PointerBase
bs) Bool -> Bool -> Bool
&& Set PointerBase -> Int
forall a. Set a -> Int
S.size Set PointerBase
bs Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
<= Int
get_max_num_of_bases then
Set PointerBase -> PointerDomain
Domain_Bases Set PointerBase
bs
else let srcs :: Set BotSrc
srcs = FContext -> SimpleExpr -> Set BotSrc
srcs_of_expr FContext
ctxt SimpleExpr
e in
if Bool -> Bool
not (Set BotSrc -> Bool
forall a. Set a -> Bool
S.null Set BotSrc
srcs) Bool -> Bool -> Bool
&& Set BotSrc -> Int
forall a. Set a -> Int
S.size Set BotSrc
srcs Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
<= Int
get_max_num_of_sources then
Set BotSrc -> PointerDomain
Domain_Sources Set BotSrc
srcs
else
Set BotSrc -> PointerDomain
Domain_Sources (Set BotSrc -> PointerDomain) -> Set BotSrc -> PointerDomain
forall a b. (a -> b) -> a -> b
$ Set BotSrc
forall a. Set a
S.empty
where
get_max_num_of_bases :: Int
get_max_num_of_bases = Context -> Int
ctxt_max_num_of_bases (Context -> Int) -> Context -> Int
forall a b. (a -> b) -> a -> b
$ FContext -> Context
f_ctxt FContext
ctxt
get_max_num_of_sources :: Int
get_max_num_of_sources = Context -> Int
ctxt_max_num_of_sources (Context -> Int) -> Context -> Int
forall a b. (a -> b) -> a -> b
$ FContext -> Context
f_ctxt FContext
ctxt
get_pointer_bases' :: Bool -> SimpleExpr -> S.Set PointerBase
get_pointer_bases' :: Bool -> SimpleExpr -> Set PointerBase
get_pointer_bases' Bool
use_finit (Bottom (FromNonDeterminism Set SimpleExpr
es)) = Set (Set PointerBase) -> Set PointerBase
forall (f :: * -> *) a. (Foldable f, Ord a) => f (Set a) -> Set a
S.unions (Set (Set PointerBase) -> Set PointerBase)
-> Set (Set PointerBase) -> Set PointerBase
forall a b. (a -> b) -> a -> b
$ (SimpleExpr -> Set PointerBase)
-> Set SimpleExpr -> Set (Set PointerBase)
forall b a. Ord b => (a -> b) -> Set a -> Set b
S.map (Bool -> SimpleExpr -> Set PointerBase
get_pointer_bases' Bool
use_finit) Set SimpleExpr
es
get_pointer_bases' Bool
use_finit (SE_Op (Plus Int
_) [SimpleExpr]
es) = Set (Set PointerBase) -> Set PointerBase
forall (f :: * -> *) a. (Foldable f, Ord a) => f (Set a) -> Set a
S.unions (Set (Set PointerBase) -> Set PointerBase)
-> Set (Set PointerBase) -> Set PointerBase
forall a b. (a -> b) -> a -> b
$ (SimpleExpr -> Set PointerBase)
-> Set SimpleExpr -> Set (Set PointerBase)
forall b a. Ord b => (a -> b) -> Set a -> Set b
S.map (Bool -> SimpleExpr -> Set PointerBase
get_pointer_bases' Bool
use_finit) (Set SimpleExpr -> Set (Set PointerBase))
-> Set SimpleExpr -> Set (Set PointerBase)
forall a b. (a -> b) -> a -> b
$ [SimpleExpr] -> Set SimpleExpr
forall a. Ord a => [a] -> Set a
S.fromList [SimpleExpr]
es
get_pointer_bases' Bool
use_finit (SE_Op (Minus Int
_) (SimpleExpr
e:[SimpleExpr]
es)) = Bool -> SimpleExpr -> Set PointerBase
get_pointer_bases' Bool
use_finit SimpleExpr
e
get_pointer_bases' Bool
use_finit SimpleExpr
e = Bool -> SimpleExpr -> Set PointerBase
get_pointer_base Bool
use_finit SimpleExpr
e
get_pointer_base :: Bool -> SimpleExpr -> S.Set PointerBase
get_pointer_base :: Bool -> SimpleExpr -> Set PointerBase
get_pointer_base Bool
use_finit (SE_Immediate Word64
a) = if Context -> SimpleExpr -> Bool
expr_is_global_immediate (FContext -> Context
f_ctxt FContext
ctxt) SimpleExpr
e then PointerBase -> Set PointerBase
forall a. a -> Set a
S.singleton (PointerBase -> Set PointerBase) -> PointerBase -> Set PointerBase
forall a b. (a -> b) -> a -> b
$ Word64 -> PointerBase
GlobalAddress Word64
a else Set PointerBase
forall a. Set a
S.empty
get_pointer_base Bool
use_finit (SE_Var (SP_StackPointer String
f)) = PointerBase -> Set PointerBase
forall a. a -> Set a
S.singleton (PointerBase -> Set PointerBase) -> PointerBase -> Set PointerBase
forall a b. (a -> b) -> a -> b
$ String -> PointerBase
StackPointer String
f
get_pointer_base Bool
True (SE_Var StatePart
sp) = (Bool -> SimpleExpr -> Set PointerBase
get_pointer_bases' Bool
False (SimpleExpr -> Set PointerBase)
-> Maybe SimpleExpr -> Maybe (Set PointerBase)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> FContext -> StatePart -> Maybe SimpleExpr
statepart_to_finit_expr FContext
ctxt StatePart
sp) Maybe (Set PointerBase) -> Set PointerBase -> Set PointerBase
forall p. Maybe p -> p -> p
`orElse` (StatePart -> Set PointerBase
statepart_to_pointerbase StatePart
sp)
get_pointer_base Bool
False (SE_Var StatePart
sp) = (StatePart -> Set PointerBase
statepart_to_pointerbase StatePart
sp)
get_pointer_base Bool
use_finit (SE_Malloc Maybe Word64
id Maybe String
hash) = PointerBase -> Set PointerBase
forall a. a -> Set a
S.singleton (PointerBase -> Set PointerBase) -> PointerBase -> Set PointerBase
forall a b. (a -> b) -> a -> b
$ Maybe Word64 -> Maybe String -> PointerBase
Malloc Maybe Word64
id Maybe String
hash
get_pointer_base Bool
use_finit (Bottom (FromPointerBases Set PointerBase
bs)) = if Set PointerBase -> Bool
forall a. Set a -> Bool
S.null Set PointerBase
bs then Set PointerBase
forall a. Set a
S.empty else Set PointerBase
bs
get_pointer_base Bool
use_finit SimpleExpr
e = Set PointerBase
forall a. Set a
S.empty
statepart_to_pointerbase :: StatePart -> S.Set PointerBase
statepart_to_pointerbase :: StatePart -> Set PointerBase
statepart_to_pointerbase (SP_Mem (SE_Immediate Word64
a) Int
8) = case Int -> IntMap String -> Maybe String
forall a. Int -> IntMap a -> Maybe a
IM.lookup (Word64 -> Int
forall a b. (Integral a, Num b) => a -> b
fromIntegral Word64
a) (Context -> IntMap String
ctxt_syms (Context -> IntMap String) -> Context -> IntMap String
forall a b. (a -> b) -> a -> b
$ FContext -> Context
f_ctxt FContext
ctxt) of
Maybe String
Nothing -> Set PointerBase
forall a. Set a
S.empty
Just String
sym -> PointerBase -> Set PointerBase
forall a. a -> Set a
S.singleton (PointerBase -> Set PointerBase) -> PointerBase -> Set PointerBase
forall a b. (a -> b) -> a -> b
$ Word64 -> String -> PointerBase
PointerToSymbol Word64
a String
sym
statepart_to_pointerbase StatePart
_ = Set PointerBase
forall a. Set a
S.empty
bases_of_domain :: PointerDomain -> Maybe (S.Set PointerBase)
bases_of_domain :: PointerDomain -> Maybe (Set PointerBase)
bases_of_domain (Domain_Bases Set PointerBase
bs) = if Bool -> Bool
not (Bool -> Bool) -> Bool -> Bool
forall a b. (a -> b) -> a -> b
$ Set PointerBase -> Bool
forall a. Set a -> Bool
S.null Set PointerBase
bs then Set PointerBase -> Maybe (Set PointerBase)
forall a. a -> Maybe a
Just Set PointerBase
bs else Maybe (Set PointerBase)
forall a. Maybe a
Nothing
bases_of_domain PointerDomain
_ = Maybe (Set PointerBase)
forall a. Maybe a
Nothing
get_pointer_bases :: FContext -> SimpleExpr -> Maybe (Set PointerBase)
get_pointer_bases FContext
ctxt SimpleExpr
e = PointerDomain -> Maybe (Set PointerBase)
bases_of_domain (PointerDomain -> Maybe (Set PointerBase))
-> PointerDomain -> Maybe (Set PointerBase)
forall a b. (a -> b) -> a -> b
$ FContext -> SimpleExpr -> PointerDomain
get_pointer_domain FContext
ctxt SimpleExpr
e
expr_highly_likely_pointer :: FContext -> SimpleExpr -> Bool
expr_highly_likely_pointer FContext
ctxt SimpleExpr
e = FContext -> SimpleExpr -> Maybe (Set PointerBase)
get_pointer_bases FContext
ctxt SimpleExpr
e Maybe (Set PointerBase) -> Maybe (Set PointerBase) -> Bool
forall a. Eq a => a -> a -> Bool
/= Maybe (Set PointerBase)
forall a. Maybe a
Nothing
get_global_pointer_bases :: FContext -> SimpleExpr -> Set PointerBase
get_global_pointer_bases FContext
ctxt SimpleExpr
e = ((PointerBase -> Bool) -> Set PointerBase -> Set PointerBase
forall a. (a -> Bool) -> Set a -> Set a
S.filter PointerBase -> Bool
is_global_ptr_base (Set PointerBase -> Set PointerBase)
-> Maybe (Set PointerBase) -> Maybe (Set PointerBase)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> FContext -> SimpleExpr -> Maybe (Set PointerBase)
get_pointer_bases FContext
ctxt SimpleExpr
e) Maybe (Set PointerBase) -> Set PointerBase -> Set PointerBase
forall p. Maybe p -> p -> p
`orElse` Set PointerBase
forall a. Set a
S.empty
expr_is_global_pointer :: FContext -> SimpleExpr -> Bool
expr_is_global_pointer FContext
ctxt SimpleExpr
e = Bool -> Bool
not (Bool -> Bool) -> Bool -> Bool
forall a b. (a -> b) -> a -> b
$ Set PointerBase -> Bool
forall a. Set a -> Bool
S.null (Set PointerBase -> Bool) -> Set PointerBase -> Bool
forall a b. (a -> b) -> a -> b
$ FContext -> SimpleExpr -> Set PointerBase
get_global_pointer_bases FContext
ctxt SimpleExpr
e
expr_is_global_immediate :: Context -> SimpleExpr -> Bool
expr_is_global_immediate Context
ctxt (SE_Immediate Word64
a) = if Context -> Word64 -> Bool
is_roughly_an_address Context
ctxt (Word64 -> Word64
forall a b. (Integral a, Num b) => a -> b
fromIntegral Word64
a) then Context -> Word64 -> Bool
forall a. Integral a => Context -> a -> Bool
address_has_symbol Context
ctxt Word64
a Bool -> Bool -> Bool
|| Context -> Word64 -> Maybe (String, String, Word64, Word64)
find_section_for_address Context
ctxt (Word64 -> Word64
forall a b. (Integral a, Num b) => a -> b
fromIntegral Word64
a) Maybe (String, String, Word64, Word64)
-> Maybe (String, String, Word64, Word64) -> Bool
forall a. Eq a => a -> a -> Bool
/= Maybe (String, String, Word64, Word64)
forall a. Maybe a
Nothing else Bool
False
expr_is_global_immediate Context
ctxt SimpleExpr
_ = Bool
False
expr_is_highly_likely_local_pointer :: FContext -> SimpleExpr -> Bool
expr_is_highly_likely_local_pointer FContext
ctxt SimpleExpr
e = FContext -> PointerDomain -> Bool
is_highly_likely_local_pointer_domain FContext
ctxt (PointerDomain -> Bool) -> PointerDomain -> Bool
forall a b. (a -> b) -> a -> b
$ FContext -> SimpleExpr -> PointerDomain
get_pointer_domain FContext
ctxt SimpleExpr
e
is_highly_likely_local_pointer_domain :: FContext -> PointerDomain -> Bool
is_highly_likely_local_pointer_domain FContext
ctxt (Domain_Bases Set PointerBase
bs) = Bool -> Bool
not (Set PointerBase -> Bool
forall a. Set a -> Bool
S.null Set PointerBase
bs) Bool -> Bool -> Bool
&& (PointerBase -> Bool) -> Set PointerBase -> Bool
forall (t :: * -> *) a. Foldable t => (a -> Bool) -> t a -> Bool
all PointerBase -> Bool
is_local_base Set PointerBase
bs
where
is_local_base :: PointerBase -> Bool
is_local_base (StackPointer String
f) = String
f String -> String -> Bool
forall a. Eq a => a -> a -> Bool
== FContext -> String
f_name FContext
ctxt
is_local_base PointerBase
_ = Bool
False
is_highly_likely_local_pointer_domain FContext
ctxt (Domain_Sources Set BotSrc
srcs) = Bool -> Bool
not (Set BotSrc -> Bool
forall a. Set a -> Bool
S.null Set BotSrc
srcs) Bool -> Bool -> Bool
&& (BotSrc -> Bool) -> Set BotSrc -> Bool
forall (t :: * -> *) a. Foldable t => (a -> Bool) -> t a -> Bool
all BotSrc -> Bool
is_local_src Set BotSrc
srcs
where
is_local_src :: BotSrc -> Bool
is_local_src (Src_StackPointer String
f) = String
f String -> String -> Bool
forall a. Eq a => a -> a -> Bool
== FContext -> String
f_name FContext
ctxt
is_local_src BotSrc
_ = Bool
False
is_global_ptr_base :: PointerBase -> Bool
is_global_ptr_base (GlobalAddress Word64
_) = Bool
True
is_global_ptr_base PointerBase
_ = Bool
False
is_malloc :: PointerBase -> Bool
is_malloc (Malloc Maybe Word64
_ Maybe String
_) = Bool
True
is_malloc PointerBase
_ = Bool
False
srcs_of_expr :: FContext -> SimpleExpr -> Set BotSrc
srcs_of_expr FContext
ctxt SimpleExpr
e = FContext -> Bool -> SimpleExpr -> Set BotSrc
srcs_of_expr' FContext
ctxt Bool
True SimpleExpr
e
is_known_source :: BotSrc -> Bool
is_known_source (Src_StackPointer String
_) = Bool
True
is_known_source (Src_Malloc Maybe Word64
_ Maybe String
_) = Bool
True
is_known_source (Src_ImmediateAddress Word64
_) = Bool
True
is_known_source BotSrc
_ = Bool
False
srcs_of_exprs :: FContext -> [SimpleExpr] -> Set BotSrc
srcs_of_exprs FContext
ctxt [SimpleExpr]
es = [Set BotSrc] -> Set BotSrc
forall (f :: * -> *) a. (Foldable f, Ord a) => f (Set a) -> Set a
S.unions ([Set BotSrc] -> Set BotSrc) -> [Set BotSrc] -> Set BotSrc
forall a b. (a -> b) -> a -> b
$ (SimpleExpr -> Set BotSrc) -> [SimpleExpr] -> [Set BotSrc]
forall a b. (a -> b) -> [a] -> [b]
map (FContext -> Bool -> SimpleExpr -> Set BotSrc
srcs_of_expr' FContext
ctxt Bool
True) [SimpleExpr]
es
sources_of_domain :: FContext -> PointerDomain -> S.Set BotSrc
sources_of_domain :: FContext -> PointerDomain -> Set BotSrc
sources_of_domain FContext
ctxt (Domain_Bases Set PointerBase
bs) = Set (Set BotSrc) -> Set BotSrc
forall (f :: * -> *) a. (Foldable f, Ord a) => f (Set a) -> Set a
S.unions (Set (Set BotSrc) -> Set BotSrc) -> Set (Set BotSrc) -> Set BotSrc
forall a b. (a -> b) -> a -> b
$ (PointerBase -> Set BotSrc) -> Set PointerBase -> Set (Set BotSrc)
forall b a. Ord b => (a -> b) -> Set a -> Set b
S.map (FContext -> Bool -> PointerBase -> Set BotSrc
forall p p. p -> p -> PointerBase -> Set BotSrc
srcs_of_base FContext
ctxt Bool
True) Set PointerBase
bs
sources_of_domain FContext
ctxt (Domain_Sources Set BotSrc
srcs) = Set BotSrc
srcs
srcs_of_expr' :: FContext -> Bool -> SimpleExpr -> Set BotSrc
srcs_of_expr' FContext
ctxt Bool
use_finit (Bottom BotTyp
typ) = FContext -> Bool -> BotTyp -> Set BotSrc
srcs_of_bottyp FContext
ctxt Bool
use_finit BotTyp
typ
srcs_of_expr' FContext
ctxt Bool
use_finit (SE_Malloc Maybe Word64
id Maybe String
h) = BotSrc -> Set BotSrc
forall a. a -> Set a
S.singleton (BotSrc -> Set BotSrc) -> BotSrc -> Set BotSrc
forall a b. (a -> b) -> a -> b
$ Maybe Word64 -> Maybe String -> BotSrc
Src_Malloc Maybe Word64
id Maybe String
h
srcs_of_expr' FContext
ctxt Bool
use_finit (SE_Var (SP_StackPointer String
f)) = BotSrc -> Set BotSrc
forall a. a -> Set a
S.singleton (BotSrc -> Set BotSrc) -> BotSrc -> Set BotSrc
forall a b. (a -> b) -> a -> b
$ String -> BotSrc
Src_StackPointer String
f
srcs_of_expr' FContext
ctxt Bool
True (SE_Var StatePart
sp) = (FContext -> Bool -> SimpleExpr -> Set BotSrc
srcs_of_expr' FContext
ctxt Bool
False (SimpleExpr -> Set BotSrc)
-> Maybe SimpleExpr -> Maybe (Set BotSrc)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> FContext -> StatePart -> Maybe SimpleExpr
statepart_to_finit_expr FContext
ctxt StatePart
sp) Maybe (Set BotSrc) -> Set BotSrc -> Set BotSrc
forall p. Maybe p -> p -> p
`orElse` (BotSrc -> Set BotSrc
forall a. a -> Set a
S.singleton (BotSrc -> Set BotSrc) -> BotSrc -> Set BotSrc
forall a b. (a -> b) -> a -> b
$ StatePart -> BotSrc
Src_Var StatePart
sp)
srcs_of_expr' FContext
ctxt Bool
False (SE_Var StatePart
sp) = BotSrc -> Set BotSrc
forall a. a -> Set a
S.singleton (BotSrc -> Set BotSrc) -> BotSrc -> Set BotSrc
forall a b. (a -> b) -> a -> b
$ StatePart -> BotSrc
Src_Var StatePart
sp
srcs_of_expr' FContext
ctxt Bool
use_finit e :: SimpleExpr
e@(SE_Immediate Word64
i) = if Context -> SimpleExpr -> Bool
expr_is_global_immediate (FContext -> Context
f_ctxt FContext
ctxt) SimpleExpr
e then BotSrc -> Set BotSrc
forall a. a -> Set a
S.singleton (BotSrc -> Set BotSrc) -> BotSrc -> Set BotSrc
forall a b. (a -> b) -> a -> b
$ Word64 -> BotSrc
Src_ImmediateAddress Word64
i else Set BotSrc
forall a. Set a
S.empty
srcs_of_expr' FContext
ctxt Bool
use_finit (SE_StatePart StatePart
sp) = Set BotSrc
forall a. Set a
S.empty
srcs_of_expr' FContext
ctxt Bool
use_finit (SE_Op Operator
_ [SimpleExpr]
es) = [Set BotSrc] -> Set BotSrc
forall (f :: * -> *) a. (Foldable f, Ord a) => f (Set a) -> Set a
S.unions ([Set BotSrc] -> Set BotSrc) -> [Set BotSrc] -> Set BotSrc
forall a b. (a -> b) -> a -> b
$ (SimpleExpr -> Set BotSrc) -> [SimpleExpr] -> [Set BotSrc]
forall a b. (a -> b) -> [a] -> [b]
map (FContext -> Bool -> SimpleExpr -> Set BotSrc
srcs_of_expr' FContext
ctxt Bool
use_finit) [SimpleExpr]
es
srcs_of_expr' FContext
ctxt Bool
use_finit (SE_Bit Int
i SimpleExpr
e) = FContext -> Bool -> SimpleExpr -> Set BotSrc
srcs_of_expr' FContext
ctxt Bool
use_finit SimpleExpr
e
srcs_of_expr' FContext
ctxt Bool
use_finit (SE_SExtend Int
_ Int
_ SimpleExpr
e) = FContext -> Bool -> SimpleExpr -> Set BotSrc
srcs_of_expr' FContext
ctxt Bool
use_finit SimpleExpr
e
srcs_of_expr' FContext
ctxt Bool
use_finit (SE_Overwrite Int
_ SimpleExpr
a SimpleExpr
b) = [Set BotSrc] -> Set BotSrc
forall (f :: * -> *) a. (Foldable f, Ord a) => f (Set a) -> Set a
S.unions ([Set BotSrc] -> Set BotSrc) -> [Set BotSrc] -> Set BotSrc
forall a b. (a -> b) -> a -> b
$ (SimpleExpr -> Set BotSrc) -> [SimpleExpr] -> [Set BotSrc]
forall a b. (a -> b) -> [a] -> [b]
map (FContext -> Bool -> SimpleExpr -> Set BotSrc
srcs_of_expr' FContext
ctxt Bool
use_finit) [SimpleExpr
a,SimpleExpr
b]
srcs_of_bottyp :: FContext -> Bool -> BotTyp -> Set BotSrc
srcs_of_bottyp FContext
ctxt Bool
use_finit (FromNonDeterminism Set SimpleExpr
es) = Set (Set BotSrc) -> Set BotSrc
forall (f :: * -> *) a. (Foldable f, Ord a) => f (Set a) -> Set a
S.unions (Set (Set BotSrc) -> Set BotSrc) -> Set (Set BotSrc) -> Set BotSrc
forall a b. (a -> b) -> a -> b
$ (SimpleExpr -> Set BotSrc) -> Set SimpleExpr -> Set (Set BotSrc)
forall b a. Ord b => (a -> b) -> Set a -> Set b
S.map (FContext -> Bool -> SimpleExpr -> Set BotSrc
srcs_of_expr' FContext
ctxt Bool
use_finit) Set SimpleExpr
es
srcs_of_bottyp FContext
ctxt Bool
use_finit (FromPointerBases Set PointerBase
bs) = Set (Set BotSrc) -> Set BotSrc
forall (f :: * -> *) a. (Foldable f, Ord a) => f (Set a) -> Set a
S.unions (Set (Set BotSrc) -> Set BotSrc) -> Set (Set BotSrc) -> Set BotSrc
forall a b. (a -> b) -> a -> b
$ (PointerBase -> Set BotSrc) -> Set PointerBase -> Set (Set BotSrc)
forall b a. Ord b => (a -> b) -> Set a -> Set b
S.map (FContext -> Bool -> PointerBase -> Set BotSrc
forall p p. p -> p -> PointerBase -> Set BotSrc
srcs_of_base FContext
ctxt Bool
use_finit) Set PointerBase
bs
srcs_of_bottyp FContext
ctxt Bool
use_finit (FromSources Set BotSrc
srcs) = Set BotSrc
srcs
srcs_of_bottyp FContext
ctxt Bool
use_finit (FromBitMode Set BotSrc
srcs) = Set BotSrc
srcs
srcs_of_bottyp FContext
ctxt Bool
use_finit (FromOverlap Set BotSrc
srcs) = Set BotSrc
srcs
srcs_of_bottyp FContext
ctxt Bool
use_finit (FromSemantics Set BotSrc
srcs) = Set BotSrc
srcs
srcs_of_bottyp FContext
ctxt Bool
use_finit (FromMemWrite Set BotSrc
srcs) = Set BotSrc
srcs
srcs_of_bottyp FContext
ctxt Bool
use_finit (FromUninitializedMemory Set BotSrc
srcs) = Set BotSrc
srcs
srcs_of_bottyp FContext
ctxt Bool
use_finit (FromCall String
f) = BotSrc -> Set BotSrc
forall a. a -> Set a
S.singleton (BotSrc -> Set BotSrc) -> BotSrc -> Set BotSrc
forall a b. (a -> b) -> a -> b
$ String -> BotSrc
Src_Function String
f
srcs_of_base :: p -> p -> PointerBase -> Set BotSrc
srcs_of_base p
ctxt p
use_finit (StackPointer String
f) = BotSrc -> Set BotSrc
forall a. a -> Set a
S.singleton (BotSrc -> Set BotSrc) -> BotSrc -> Set BotSrc
forall a b. (a -> b) -> a -> b
$ String -> BotSrc
Src_StackPointer String
f
srcs_of_base p
ctxt p
use_finit (Malloc Maybe Word64
id Maybe String
h) = BotSrc -> Set BotSrc
forall a. a -> Set a
S.singleton (BotSrc -> Set BotSrc) -> BotSrc -> Set BotSrc
forall a b. (a -> b) -> a -> b
$ Maybe Word64 -> Maybe String -> BotSrc
Src_Malloc Maybe Word64
id Maybe String
h
srcs_of_base p
ctxt p
use_finit (GlobalAddress Word64
a) = BotSrc -> Set BotSrc
forall a. a -> Set a
S.singleton (BotSrc -> Set BotSrc) -> BotSrc -> Set BotSrc
forall a b. (a -> b) -> a -> b
$ Word64 -> BotSrc
Src_ImmediateAddress Word64
a
srcs_of_base p
ctxt p
use_finit (PointerToSymbol Word64
a String
sym) = BotSrc -> Set BotSrc
forall a. a -> Set a
S.singleton (BotSrc -> Set BotSrc) -> BotSrc -> Set BotSrc
forall a b. (a -> b) -> a -> b
$ StatePart -> BotSrc
Src_Var (StatePart -> BotSrc) -> StatePart -> BotSrc
forall a b. (a -> b) -> a -> b
$ SimpleExpr -> Int -> StatePart
SP_Mem (Word64 -> SimpleExpr
SE_Immediate Word64
a) Int
8
join_exprs' :: String -> FContext -> [SimpleExpr] -> SimpleExpr
join_exprs' :: String -> FContext -> [SimpleExpr] -> SimpleExpr
join_exprs' String
msg FContext
ctxt [SimpleExpr]
es =
let es' :: Set SimpleExpr
es' = (SimpleExpr -> SimpleExpr) -> Set SimpleExpr -> Set SimpleExpr
forall b a. Ord b => (a -> b) -> Set a -> Set b
S.map SimpleExpr -> SimpleExpr
simp (Set SimpleExpr -> Set SimpleExpr)
-> Set SimpleExpr -> Set SimpleExpr
forall a b. (a -> b) -> a -> b
$ [Set SimpleExpr] -> Set SimpleExpr
forall (f :: * -> *) a. (Foldable f, Ord a) => f (Set a) -> Set a
S.unions ([Set SimpleExpr] -> Set SimpleExpr)
-> [Set SimpleExpr] -> Set SimpleExpr
forall a b. (a -> b) -> a -> b
$ (SimpleExpr -> Set SimpleExpr) -> [SimpleExpr] -> [Set SimpleExpr]
forall a b. (a -> b) -> [a] -> [b]
map ([SimpleExpr] -> Set SimpleExpr
forall a. Ord a => [a] -> Set a
S.fromList ([SimpleExpr] -> Set SimpleExpr)
-> (SimpleExpr -> [SimpleExpr]) -> SimpleExpr -> Set SimpleExpr
forall b c a. (b -> c) -> (a -> b) -> a -> c
. FContext -> SimpleExpr -> [SimpleExpr]
unfold_non_determinism FContext
ctxt) [SimpleExpr]
es in
if Set SimpleExpr -> Int
forall a. Set a -> Int
S.size Set SimpleExpr
es' Int -> Int -> Bool
forall a. Eq a => a -> a -> Bool
== Int
0 then
SimpleExpr
rock_bottom
else if Set SimpleExpr -> Int
forall a. Set a -> Int
S.size Set SimpleExpr
es' Int -> Int -> Bool
forall a. Eq a => a -> a -> Bool
== Int
1 then
[SimpleExpr] -> SimpleExpr
forall a. [a] -> a
head ([SimpleExpr] -> SimpleExpr) -> [SimpleExpr] -> SimpleExpr
forall a b. (a -> b) -> a -> b
$ Set SimpleExpr -> [SimpleExpr]
forall a. Set a -> [a]
S.toList Set SimpleExpr
es'
else if Set SimpleExpr -> Int
forall a. Set a -> Int
S.size Set SimpleExpr
es' Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
<= Int
get_max_num_of_cases Bool -> Bool -> Bool
&& (SimpleExpr -> Bool) -> Set SimpleExpr -> Bool
forall (t :: * -> *) a. Foldable t => (a -> Bool) -> t a -> Bool
all (Bool -> Bool
not (Bool -> Bool) -> (SimpleExpr -> Bool) -> SimpleExpr -> Bool
forall b c a. (b -> c) -> (a -> b) -> a -> c
. SimpleExpr -> Bool
contains_bot) Set SimpleExpr
es' then
BotTyp -> SimpleExpr
Bottom (Set SimpleExpr -> BotTyp
FromNonDeterminism Set SimpleExpr
es')
else if SimpleExpr
rock_bottom SimpleExpr -> Set SimpleExpr -> Bool
forall a. Ord a => a -> Set a -> Bool
`S.member` Set SimpleExpr
es' then
SimpleExpr
rock_bottom
else let bss :: Set (Set PointerBase)
bss = (SimpleExpr -> Set PointerBase)
-> Set SimpleExpr -> Set (Set PointerBase)
forall b a. Ord b => (a -> b) -> Set a -> Set b
S.map (Maybe (Set PointerBase) -> Set PointerBase
forall a. Maybe (Set a) -> Set a
nothing_to_empty (Maybe (Set PointerBase) -> Set PointerBase)
-> (SimpleExpr -> Maybe (Set PointerBase))
-> SimpleExpr
-> Set PointerBase
forall b c a. (b -> c) -> (a -> b) -> a -> c
. FContext -> SimpleExpr -> Maybe (Set PointerBase)
get_pointer_bases FContext
ctxt) Set SimpleExpr
es'
bs :: Set PointerBase
bs = Set (Set PointerBase) -> Set PointerBase
forall (f :: * -> *) a. (Foldable f, Ord a) => f (Set a) -> Set a
S.unions Set (Set PointerBase)
bss in
if Set PointerBase -> Int
forall a. Set a -> Int
S.size Set PointerBase
bs Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
<= Int
get_max_num_of_bases Bool -> Bool -> Bool
&& (Set PointerBase -> Bool) -> Set (Set PointerBase) -> Bool
forall (t :: * -> *) a. Foldable t => (a -> Bool) -> t a -> Bool
all (Bool -> Bool
not (Bool -> Bool)
-> (Set PointerBase -> Bool) -> Set PointerBase -> Bool
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Set PointerBase -> Bool
forall a. Set a -> Bool
S.null) Set (Set PointerBase)
bss then
BotTyp -> SimpleExpr
Bottom (Set PointerBase -> BotTyp
FromPointerBases Set PointerBase
bs)
else
let srcs :: Set BotSrc
srcs = Set (Set BotSrc) -> Set BotSrc
forall (f :: * -> *) a. (Foldable f, Ord a) => f (Set a) -> Set a
S.unions (Set (Set BotSrc) -> Set BotSrc) -> Set (Set BotSrc) -> Set BotSrc
forall a b. (a -> b) -> a -> b
$ (SimpleExpr -> Set BotSrc) -> Set SimpleExpr -> Set (Set BotSrc)
forall b a. Ord b => (a -> b) -> Set a -> Set b
S.map (FContext -> SimpleExpr -> Set BotSrc
srcs_of_expr FContext
ctxt) Set SimpleExpr
es' in
if Set BotSrc -> Int
forall a. Set a -> Int
S.size Set BotSrc
srcs Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
<= Int
get_max_num_of_sources then
BotTyp -> SimpleExpr
Bottom (Set BotSrc -> BotTyp
FromSources Set BotSrc
srcs)
else
SimpleExpr
rock_bottom
where
get_max_num_of_cases :: Int
get_max_num_of_cases = Context -> Int
ctxt_max_num_of_cases (Context -> Int) -> Context -> Int
forall a b. (a -> b) -> a -> b
$ FContext -> Context
f_ctxt FContext
ctxt
get_max_num_of_bases :: Int
get_max_num_of_bases = Context -> Int
ctxt_max_num_of_bases (Context -> Int) -> Context -> Int
forall a b. (a -> b) -> a -> b
$ FContext -> Context
f_ctxt FContext
ctxt
get_max_num_of_sources :: Int
get_max_num_of_sources = Context -> Int
ctxt_max_num_of_sources (Context -> Int) -> Context -> Int
forall a b. (a -> b) -> a -> b
$ FContext -> Context
f_ctxt FContext
ctxt
nothing_to_empty :: Maybe (Set a) -> Set a
nothing_to_empty Maybe (Set a)
Nothing = Set a
forall a. Set a
S.empty
nothing_to_empty (Just Set a
bs) = Set a
bs
join_exprs :: String -> FContext -> [SimpleExpr] -> SimpleExpr
join_exprs String
msg FContext
ctxt [SimpleExpr]
es =
let e :: SimpleExpr
e = String -> FContext -> [SimpleExpr] -> SimpleExpr
join_exprs' String
msg FContext
ctxt [SimpleExpr]
es in
SimpleExpr
e
join_single :: FContext -> SimpleExpr -> SimpleExpr
join_single :: FContext -> SimpleExpr -> SimpleExpr
join_single FContext
ctxt SimpleExpr
e =
case FContext -> SimpleExpr -> Maybe (Set PointerBase)
get_pointer_bases FContext
ctxt SimpleExpr
e of
Maybe (Set PointerBase)
Nothing -> SimpleExpr
join_sources
Just Set PointerBase
bs -> if Bool -> Bool
not (Set PointerBase -> Bool
forall a. Set a -> Bool
S.null Set PointerBase
bs) Bool -> Bool -> Bool
&& Set PointerBase -> Int
forall a. Set a -> Int
S.size Set PointerBase
bs Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
<= Int
get_max_num_of_bases then BotTyp -> SimpleExpr
Bottom (Set PointerBase -> BotTyp
FromPointerBases Set PointerBase
bs) else SimpleExpr
join_sources
where
get_max_num_of_bases :: Int
get_max_num_of_bases = Context -> Int
ctxt_max_num_of_bases (Context -> Int) -> Context -> Int
forall a b. (a -> b) -> a -> b
$ FContext -> Context
f_ctxt FContext
ctxt
get_max_num_of_sources :: Int
get_max_num_of_sources = Context -> Int
ctxt_max_num_of_sources (Context -> Int) -> Context -> Int
forall a b. (a -> b) -> a -> b
$ FContext -> Context
f_ctxt FContext
ctxt
join_sources :: SimpleExpr
join_sources =
let srcs :: Set BotSrc
srcs = FContext -> SimpleExpr -> Set BotSrc
srcs_of_expr FContext
ctxt SimpleExpr
e in
if Set BotSrc -> Int
forall a. Set a -> Int
S.size Set BotSrc
srcs Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
<= Int
get_max_num_of_sources then
BotTyp -> SimpleExpr
Bottom (Set BotSrc -> BotTyp
FromSources Set BotSrc
srcs)
else
SimpleExpr
rock_bottom
pointers_from_different_global_section :: Context -> a -> a -> Bool
pointers_from_different_global_section Context
ctxt a
a0 a
a1 = Context -> Word64 -> Maybe (String, String, Word64, Word64)
find_section_for_address Context
ctxt (a -> Word64
forall a b. (Integral a, Num b) => a -> b
fromIntegral a
a0) Maybe (String, String, Word64, Word64)
-> Maybe (String, String, Word64, Word64) -> Bool
forall a. Eq a => a -> a -> Bool
/= Context -> Word64 -> Maybe (String, String, Word64, Word64)
find_section_for_address Context
ctxt (a -> Word64
forall a b. (Integral a, Num b) => a -> b
fromIntegral a
a1)
domains_separate :: FContext -> Bool -> PointerDomain -> PointerDomain -> Bool
domains_separate FContext
ctxt Bool
necc (Domain_Bases Set PointerBase
bs0) (Domain_Bases Set PointerBase
bs1) =
if Bool
necc then
((PointerBase, PointerBase) -> Bool)
-> [(PointerBase, PointerBase)] -> Bool
forall (t :: * -> *) a. Foldable t => (a -> Bool) -> t a -> Bool
all ((PointerBase -> PointerBase -> Bool)
-> (PointerBase, PointerBase) -> Bool
forall a b c. (a -> b -> c) -> (a, b) -> c
uncurry ((PointerBase -> PointerBase -> Bool)
-> (PointerBase, PointerBase) -> Bool)
-> (PointerBase -> PointerBase -> Bool)
-> (PointerBase, PointerBase)
-> Bool
forall a b. (a -> b) -> a -> b
$ FContext -> Bool -> PointerBase -> PointerBase -> Bool
pointer_bases_separate FContext
ctxt Bool
necc) [(PointerBase
b0,PointerBase
b1) | PointerBase
b0 <- Set PointerBase -> [PointerBase]
forall a. Set a -> [a]
S.toList Set PointerBase
bs0, PointerBase
b1 <- Set PointerBase -> [PointerBase]
forall a. Set a -> [a]
S.toList Set PointerBase
bs1]
else
Set PointerBase -> Set PointerBase -> Bool
forall a. Ord a => Set a -> Set a -> Bool
S.disjoint Set PointerBase
bs0 Set PointerBase
bs1 Bool -> Bool -> Bool
&& ((PointerBase, PointerBase) -> Bool)
-> [(PointerBase, PointerBase)] -> Bool
forall (t :: * -> *) a. Foldable t => (a -> Bool) -> t a -> Bool
any ((PointerBase -> PointerBase -> Bool)
-> (PointerBase, PointerBase) -> Bool
forall a b c. (a -> b -> c) -> (a, b) -> c
uncurry ((PointerBase -> PointerBase -> Bool)
-> (PointerBase, PointerBase) -> Bool)
-> (PointerBase -> PointerBase -> Bool)
-> (PointerBase, PointerBase)
-> Bool
forall a b. (a -> b) -> a -> b
$ FContext -> Bool -> PointerBase -> PointerBase -> Bool
pointer_bases_separate FContext
ctxt Bool
necc) [(PointerBase
b0,PointerBase
b1) | PointerBase
b0 <- Set PointerBase -> [PointerBase]
forall a. Set a -> [a]
S.toList Set PointerBase
bs0, PointerBase
b1 <- Set PointerBase -> [PointerBase]
forall a. Set a -> [a]
S.toList Set PointerBase
bs1]
domains_separate FContext
ctxt Bool
necc PointerDomain
dom0 PointerDomain
dom1 =
let srcs0 :: Set BotSrc
srcs0 = FContext -> PointerDomain -> Set BotSrc
sources_of_domain FContext
ctxt PointerDomain
dom0
srcs1 :: Set BotSrc
srcs1 = FContext -> PointerDomain -> Set BotSrc
sources_of_domain FContext
ctxt PointerDomain
dom1 in
if Set BotSrc -> Bool
forall a. Set a -> Bool
S.null Set BotSrc
srcs0 Bool -> Bool -> Bool
|| Set BotSrc -> Bool
forall a. Set a -> Bool
S.null Set BotSrc
srcs1 then
Bool
False
else if Bool
necc then
((BotSrc, BotSrc) -> Bool) -> [(BotSrc, BotSrc)] -> Bool
forall (t :: * -> *) a. Foldable t => (a -> Bool) -> t a -> Bool
all ((BotSrc -> BotSrc -> Bool) -> (BotSrc, BotSrc) -> Bool
forall a b c. (a -> b -> c) -> (a, b) -> c
uncurry ((BotSrc -> BotSrc -> Bool) -> (BotSrc, BotSrc) -> Bool)
-> (BotSrc -> BotSrc -> Bool) -> (BotSrc, BotSrc) -> Bool
forall a b. (a -> b) -> a -> b
$ FContext -> Bool -> BotSrc -> BotSrc -> Bool
sources_separate FContext
ctxt Bool
necc) [(BotSrc
src0,BotSrc
src1) | BotSrc
src0 <- Set BotSrc -> [BotSrc]
forall a. Set a -> [a]
S.toList Set BotSrc
srcs0, BotSrc
src1 <- Set BotSrc -> [BotSrc]
forall a. Set a -> [a]
S.toList Set BotSrc
srcs1]
else
Set BotSrc -> Set BotSrc -> Bool
forall a. Ord a => Set a -> Set a -> Bool
S.disjoint Set BotSrc
srcs0 Set BotSrc
srcs1 Bool -> Bool -> Bool
&& ((BotSrc, BotSrc) -> Bool) -> [(BotSrc, BotSrc)] -> Bool
forall (t :: * -> *) a. Foldable t => (a -> Bool) -> t a -> Bool
any ((BotSrc -> BotSrc -> Bool) -> (BotSrc, BotSrc) -> Bool
forall a b c. (a -> b -> c) -> (a, b) -> c
uncurry ((BotSrc -> BotSrc -> Bool) -> (BotSrc, BotSrc) -> Bool)
-> (BotSrc -> BotSrc -> Bool) -> (BotSrc, BotSrc) -> Bool
forall a b. (a -> b) -> a -> b
$ FContext -> Bool -> BotSrc -> BotSrc -> Bool
sources_separate FContext
ctxt Bool
necc) [(BotSrc
src0,BotSrc
src1) | BotSrc
src0 <- Set BotSrc -> [BotSrc]
forall a. Set a -> [a]
S.toList Set BotSrc
srcs0, BotSrc
src1 <- Set BotSrc -> [BotSrc]
forall a. Set a -> [a]
S.toList Set BotSrc
srcs1]
pointer_bases_separate :: FContext -> Bool -> PointerBase -> PointerBase -> Bool
pointer_bases_separate FContext
ctxt Bool
necc (StackPointer String
f) (StackPointer String
f') = if Bool
necc then Bool
False else String
f String -> String -> Bool
forall a. Eq a => a -> a -> Bool
/= String
f'
pointer_bases_separate FContext
ctxt Bool
necc (StackPointer String
f) (GlobalAddress Word64
_) = Bool
True
pointer_bases_separate FContext
ctxt Bool
necc (StackPointer String
f) (PointerToSymbol Word64
_ String
_) = Bool
True
pointer_bases_separate FContext
ctxt Bool
necc (StackPointer String
f) (Malloc Maybe Word64
_ Maybe String
_) = Bool
True
pointer_bases_separate FContext
ctxt Bool
necc (GlobalAddress Word64
_) (StackPointer String
f) = Bool
True
pointer_bases_separate FContext
ctxt Bool
necc (GlobalAddress Word64
_) (PointerToSymbol Word64
_ String
_) = Bool
True
pointer_bases_separate FContext
ctxt Bool
necc (GlobalAddress Word64
a0) (GlobalAddress Word64
a1) = if Bool
necc then Bool
False else Context -> Word64 -> Word64 -> Bool
forall a a. (Integral a, Integral a) => Context -> a -> a -> Bool
pointers_from_different_global_section (FContext -> Context
f_ctxt FContext
ctxt) Word64
a0 Word64
a1
pointer_bases_separate FContext
ctxt Bool
necc (GlobalAddress Word64
_) (Malloc Maybe Word64
_ Maybe String
_) = Bool
True
pointer_bases_separate FContext
ctxt Bool
necc (PointerToSymbol Word64
_ String
_) (StackPointer String
f) = Bool
True
pointer_bases_separate FContext
ctxt Bool
necc (PointerToSymbol Word64
_ String
_) (GlobalAddress Word64
_) = Bool
True
pointer_bases_separate FContext
ctxt Bool
necc (PointerToSymbol Word64
_ String
sym0) (PointerToSymbol Word64
_ String
sym1) = String
sym0 String -> String -> Bool
forall a. Eq a => a -> a -> Bool
/= String
sym1
pointer_bases_separate FContext
ctxt Bool
necc (PointerToSymbol Word64
_ String
sym0) (Malloc Maybe Word64
_ Maybe String
_) = Bool
True
pointer_bases_separate FContext
ctxt Bool
necc (Malloc Maybe Word64
id0 Maybe String
hash0) (Malloc Maybe Word64
id1 Maybe String
hash1) = Maybe Word64
forall a. Maybe a
Nothing Maybe Word64 -> [Maybe Word64] -> Bool
forall (t :: * -> *) a. (Foldable t, Eq a) => a -> t a -> Bool
`notElem` [Maybe Word64
id0,Maybe Word64
id1] Bool -> Bool -> Bool
&& Maybe String
forall a. Maybe a
Nothing Maybe String -> [Maybe String] -> Bool
forall (t :: * -> *) a. (Foldable t, Eq a) => a -> t a -> Bool
`notElem` [Maybe String
hash0,Maybe String
hash1] Bool -> Bool -> Bool
&& (Maybe Word64
id0,Maybe String
hash0) (Maybe Word64, Maybe String)
-> (Maybe Word64, Maybe String) -> Bool
forall a. Eq a => a -> a -> Bool
/= (Maybe Word64
id1,Maybe String
hash1)
pointer_bases_separate FContext
ctxt Bool
necc (Malloc Maybe Word64
_ Maybe String
_) PointerBase
_ = Bool
True
pointer_bases_separate_necessarily :: FContext -> PointerBase -> PointerBase -> Bool
pointer_bases_separate_necessarily FContext
ctxt = FContext -> Bool -> PointerBase -> PointerBase -> Bool
pointer_bases_separate FContext
ctxt Bool
True
pointer_bases_separate_possibly :: FContext -> PointerBase -> PointerBase -> Bool
pointer_bases_separate_possibly FContext
ctxt = FContext -> Bool -> PointerBase -> PointerBase -> Bool
pointer_bases_separate FContext
ctxt Bool
False
sources_separate :: FContext -> Bool -> BotSrc -> BotSrc -> Bool
sources_separate :: FContext -> Bool -> BotSrc -> BotSrc -> Bool
sources_separate FContext
ctxt Bool
necc BotSrc
src0 BotSrc
src1 =
case (BotSrc -> Maybe PointerBase
src_to_base BotSrc
src0, BotSrc -> Maybe PointerBase
src_to_base BotSrc
src1) of
(Just PointerBase
b0,Just PointerBase
b1) -> FContext -> Bool -> PointerBase -> PointerBase -> Bool
pointer_bases_separate FContext
ctxt Bool
necc PointerBase
b0 PointerBase
b1
(Just (StackPointer String
_), Maybe PointerBase
_) -> Bool -> Bool
not Bool
necc
(Maybe PointerBase
_, Just (StackPointer String
_)) -> Bool -> Bool
not Bool
necc
(Just (Malloc Maybe Word64
_ Maybe String
_), Maybe PointerBase
_) -> Bool
True
(Maybe PointerBase
_, Just (Malloc Maybe Word64
_ Maybe String
_)) -> Bool
True
(Maybe PointerBase, Maybe PointerBase)
_ -> Bool
False
where
src_to_base :: BotSrc -> Maybe PointerBase
src_to_base (Src_StackPointer String
f) = PointerBase -> Maybe PointerBase
forall a. a -> Maybe a
Just (PointerBase -> Maybe PointerBase)
-> PointerBase -> Maybe PointerBase
forall a b. (a -> b) -> a -> b
$ String -> PointerBase
StackPointer String
f
src_to_base (Src_Malloc Maybe Word64
i Maybe String
h) = PointerBase -> Maybe PointerBase
forall a. a -> Maybe a
Just (PointerBase -> Maybe PointerBase)
-> PointerBase -> Maybe PointerBase
forall a b. (a -> b) -> a -> b
$ Maybe Word64 -> Maybe String -> PointerBase
Malloc Maybe Word64
i Maybe String
h
src_to_base (Src_ImmediateAddress Word64
a) = PointerBase -> Maybe PointerBase
forall a. a -> Maybe a
Just (PointerBase -> Maybe PointerBase)
-> PointerBase -> Maybe PointerBase
forall a b. (a -> b) -> a -> b
$ Word64 -> PointerBase
GlobalAddress Word64
a
src_to_base BotSrc
_ = Maybe PointerBase
forall a. Maybe a
Nothing
sources_separate_necessarily :: FContext -> BotSrc -> BotSrc -> Bool
sources_separate_necessarily FContext
ctxt = FContext -> Bool -> BotSrc -> BotSrc -> Bool
sources_separate FContext
ctxt Bool
True
sources_separate_possibly :: FContext -> BotSrc -> BotSrc -> Bool
sources_separate_possibly FContext
ctxt = FContext -> Bool -> BotSrc -> BotSrc -> Bool
sources_separate FContext
ctxt Bool
False
separate_pointer_domains :: FContext -> Bool -> SimpleExpr -> a -> SimpleExpr -> a -> Bool
separate_pointer_domains FContext
ctxt Bool
necc SimpleExpr
a0 a
si0 SimpleExpr
a1 a
si1 =
if Bool -> Bool
not Bool
necc Bool -> Bool -> Bool
&& Bool
possibly_separate_globals then
Bool
True
else
let dom0 :: PointerDomain
dom0 = FContext -> SimpleExpr -> PointerDomain
get_pointer_domain FContext
ctxt SimpleExpr
a0
dom1 :: PointerDomain
dom1 = FContext -> SimpleExpr -> PointerDomain
get_pointer_domain FContext
ctxt SimpleExpr
a1 in
[Bool] -> Bool
forall (t :: * -> *). Foldable t => t Bool -> Bool
or [
FContext -> Bool -> PointerDomain -> PointerDomain -> Bool
domains_separate FContext
ctxt Bool
necc PointerDomain
dom0 PointerDomain
dom1,
SimpleExpr -> Bool
is_immediate SimpleExpr
a0 Bool -> Bool -> Bool
&& FContext -> SimpleExpr -> Bool
expr_is_highly_likely_local_pointer FContext
ctxt SimpleExpr
a1,
SimpleExpr -> Bool
is_immediate SimpleExpr
a1 Bool -> Bool -> Bool
&& FContext -> SimpleExpr -> Bool
expr_is_highly_likely_local_pointer FContext
ctxt SimpleExpr
a0
]
where
possibly_separate_globals :: Bool
possibly_separate_globals =
case (SimpleExpr
a0,SimpleExpr
a1) of
(SE_Immediate Word64
imm0,SimpleExpr
_) -> if Context -> SimpleExpr -> Bool
expr_is_global_immediate (FContext -> Context
f_ctxt FContext
ctxt) SimpleExpr
a0 then Word64 -> a -> Set BotSrc -> Bool
forall a. Integral a => Word64 -> a -> Set BotSrc -> Bool
below Word64
imm0 a
si0 ((BotSrc -> Bool) -> Set BotSrc -> Set BotSrc
forall a. (a -> Bool) -> Set a -> Set a
S.filter BotSrc -> Bool
is_global_src (Set BotSrc -> Set BotSrc) -> Set BotSrc -> Set BotSrc
forall a b. (a -> b) -> a -> b
$ FContext -> SimpleExpr -> Set BotSrc
srcs_of_expr FContext
ctxt SimpleExpr
a1) else Bool
False
(SimpleExpr
_,SE_Immediate Word64
imm1) -> if Context -> SimpleExpr -> Bool
expr_is_global_immediate (FContext -> Context
f_ctxt FContext
ctxt) SimpleExpr
a1 then Word64 -> a -> Set BotSrc -> Bool
forall a. Integral a => Word64 -> a -> Set BotSrc -> Bool
below Word64
imm1 a
si1 ((BotSrc -> Bool) -> Set BotSrc -> Set BotSrc
forall a. (a -> Bool) -> Set a -> Set a
S.filter BotSrc -> Bool
is_global_src (Set BotSrc -> Set BotSrc) -> Set BotSrc -> Set BotSrc
forall a b. (a -> b) -> a -> b
$ FContext -> SimpleExpr -> Set BotSrc
srcs_of_expr FContext
ctxt SimpleExpr
a0) else Bool
False
(SimpleExpr, SimpleExpr)
_ -> Bool
False
below :: Word64 -> a -> Set BotSrc -> Bool
below Word64
imm a
si Set BotSrc
srcs = (Bool -> Bool
not (Bool -> Bool) -> Bool -> Bool
forall a b. (a -> b) -> a -> b
$ Set BotSrc -> Bool
forall a. Set a -> Bool
S.null Set BotSrc
srcs) Bool -> Bool -> Bool
&& (BotSrc -> Bool) -> Set BotSrc -> Bool
forall (t :: * -> *) a. Foldable t => (a -> Bool) -> t a -> Bool
all (\(Src_ImmediateAddress Word64
imm') -> Word64
imm Word64 -> Word64 -> Word64
forall a. Num a => a -> a -> a
+ a -> Word64
forall a b. (Integral a, Num b) => a -> b
fromIntegral a
si Word64 -> Word64 -> Bool
forall a. Ord a => a -> a -> Bool
< Word64
imm') Set BotSrc
srcs
is_global_src :: BotSrc -> Bool
is_global_src (Src_ImmediateAddress Word64
_) = Bool
True
is_global_src BotSrc
_ = Bool
False
necessarily_enclosed :: SimpleExpr -> a -> SimpleExpr -> a -> Bool
necessarily_enclosed SimpleExpr
a0 a
si0 SimpleExpr
a1 a
si1 =
Bool -> Bool
not (SimpleExpr -> Bool
contains_bot SimpleExpr
a0) Bool -> Bool -> Bool
&& Bool -> Bool
not (SimpleExpr -> Bool
contains_bot SimpleExpr
a1) Bool -> Bool -> Bool
&& SimpleExpr -> SimpleExpr -> Bool
enc SimpleExpr
a0 SimpleExpr
a1
where
enc :: SimpleExpr -> SimpleExpr -> Bool
enc (SE_Op (Minus Int
_) [SE_Var StatePart
v0, SE_Immediate Word64
i0])
(SE_Op (Minus Int
_) [SE_Var StatePart
v1, SE_Immediate Word64
i1]) =
StatePart
v0 StatePart -> StatePart -> Bool
forall a. Eq a => a -> a -> Bool
== StatePart
v1 Bool -> Bool -> Bool
&&
if a
si0 a -> a -> Bool
forall a. Ord a => a -> a -> Bool
<= Word64 -> a
forall a b. (Integral a, Num b) => a -> b
fromIntegral Word64
i0 Bool -> Bool -> Bool
&& a
si1 a -> a -> Bool
forall a. Ord a => a -> a -> Bool
<= Word64 -> a
forall a b. (Integral a, Num b) => a -> b
fromIntegral Word64
i1 then
Word64 -> Integer
forall a b. (Integral a, Num b) => a -> b
fromIntegral Word64
i1 Integer -> Integer -> Bool
forall a. Ord a => a -> a -> Bool
>= Word64 -> Integer
forall a b. (Integral a, Num b) => a -> b
fromIntegral Word64
i0 Bool -> Bool -> Bool
&& Word64 -> a
forall a b. (Integral a, Num b) => a -> b
fromIntegral Word64
i0 a -> a -> a
forall a. Num a => a -> a -> a
- a
si0 a -> a -> Bool
forall a. Ord a => a -> a -> Bool
>= Word64 -> a
forall a b. (Integral a, Num b) => a -> b
fromIntegral Word64
i1 a -> a -> a
forall a. Num a => a -> a -> a
- a
si1
else if a
si0 a -> a -> Bool
forall a. Ord a => a -> a -> Bool
<= Word64 -> a
forall a b. (Integral a, Num b) => a -> b
fromIntegral Word64
i0 Bool -> Bool -> Bool
&& a
si1 a -> a -> Bool
forall a. Ord a => a -> a -> Bool
> Word64 -> a
forall a b. (Integral a, Num b) => a -> b
fromIntegral Word64
i1 then
Word64 -> Integer
forall a b. (Integral a, Num b) => a -> b
fromIntegral Word64
i1 Integer -> Integer -> Bool
forall a. Ord a => a -> a -> Bool
>= Word64 -> Integer
forall a b. (Integral a, Num b) => a -> b
fromIntegral Word64
i0
else if a
si0 a -> a -> Bool
forall a. Ord a => a -> a -> Bool
> Word64 -> a
forall a b. (Integral a, Num b) => a -> b
fromIntegral Word64
i0 Bool -> Bool -> Bool
&& a
si1 a -> a -> Bool
forall a. Ord a => a -> a -> Bool
<= Word64 -> a
forall a b. (Integral a, Num b) => a -> b
fromIntegral Word64
i1 then
Bool
False
else if a
si0 a -> a -> Bool
forall a. Ord a => a -> a -> Bool
> Word64 -> a
forall a b. (Integral a, Num b) => a -> b
fromIntegral Word64
i0 Bool -> Bool -> Bool
&& a
si1 a -> a -> Bool
forall a. Ord a => a -> a -> Bool
> Word64 -> a
forall a b. (Integral a, Num b) => a -> b
fromIntegral Word64
i1 then
Word64 -> Integer
forall a b. (Integral a, Num b) => a -> b
fromIntegral Word64
i1 Integer -> Integer -> Bool
forall a. Ord a => a -> a -> Bool
>= Word64 -> Integer
forall a b. (Integral a, Num b) => a -> b
fromIntegral Word64
i0 Bool -> Bool -> Bool
&& a -> Word64
forall a b. (Integral a, Num b) => a -> b
fromIntegral a
si0 Word64 -> Word64 -> Word64
forall a. Num a => a -> a -> a
- Word64
i0 Word64 -> Word64 -> Bool
forall a. Ord a => a -> a -> Bool
<= a -> Word64
forall a b. (Integral a, Num b) => a -> b
fromIntegral a
si1 Word64 -> Word64 -> Word64
forall a. Num a => a -> a -> a
- Word64
i1
else
Bool
False
enc (SE_Op (Plus Int
_) [SE_Var StatePart
v0, SE_Immediate Word64
i0])
(SE_Op (Plus Int
_) [SE_Var StatePart
v1, SE_Immediate Word64
i1]) =
StatePart
v0 StatePart -> StatePart -> Bool
forall a. Eq a => a -> a -> Bool
== StatePart
v1 Bool -> Bool -> Bool
&& Word64
i0 Word64 -> Word64 -> Bool
forall a. Ord a => a -> a -> Bool
>= Word64
i1 Bool -> Bool -> Bool
&& Word64 -> a
forall a b. (Integral a, Num b) => a -> b
fromIntegral Word64
i0 a -> a -> a
forall a. Num a => a -> a -> a
+ a
si0 a -> a -> Bool
forall a. Ord a => a -> a -> Bool
<= Word64 -> a
forall a b. (Integral a, Num b) => a -> b
fromIntegral Word64
i1 a -> a -> a
forall a. Num a => a -> a -> a
+ a
si1
enc (SE_Op (Plus Int
_) [SE_Var StatePart
v0, SE_Immediate Word64
i0])
(SE_Var StatePart
v1) =
StatePart
v0 StatePart -> StatePart -> Bool
forall a. Eq a => a -> a -> Bool
== StatePart
v1 Bool -> Bool -> Bool
&& Word64 -> a
forall a b. (Integral a, Num b) => a -> b
fromIntegral Word64
i0 a -> a -> a
forall a. Num a => a -> a -> a
+ a
si0 a -> a -> Bool
forall a. Ord a => a -> a -> Bool
<= a
si1
enc (SE_Immediate Word64
a0) (SE_Immediate Word64
a1) =
Word64
a0 Word64 -> Word64 -> Bool
forall a. Ord a => a -> a -> Bool
>= Word64
a1 Bool -> Bool -> Bool
&& Word64
a0 Word64 -> Word64 -> Word64
forall a. Num a => a -> a -> a
+ a -> Word64
forall a b. (Integral a, Num b) => a -> b
fromIntegral a
si0 Word64 -> Word64 -> Bool
forall a. Ord a => a -> a -> Bool
<= Word64
a1 Word64 -> Word64 -> Word64
forall a. Num a => a -> a -> a
+ a -> Word64
forall a b. (Integral a, Num b) => a -> b
fromIntegral a
si1
enc SimpleExpr
_ SimpleExpr
_ = Bool
False
necessarily_separate :: FContext -> SimpleExpr -> a -> SimpleExpr -> a -> Bool
necessarily_separate FContext
ctxt SimpleExpr
a0 a
si0 SimpleExpr
a1 a
si1 =
if Bool -> Bool
not (SimpleExpr -> Bool
contains_bot SimpleExpr
a0) Bool -> Bool -> Bool
&& Bool -> Bool
not (SimpleExpr -> Bool
contains_bot SimpleExpr
a1) then
(SimpleExpr
a0,a
si0) (SimpleExpr, a) -> (SimpleExpr, a) -> Bool
forall a. Eq a => a -> a -> Bool
/= (SimpleExpr
a1,a
si1) Bool -> Bool -> Bool
&& SimpleExpr -> SimpleExpr -> Bool
sep SimpleExpr
a0 SimpleExpr
a1
else
FContext -> Bool -> SimpleExpr -> a -> SimpleExpr -> a -> Bool
forall a a.
(Integral a, Integral a) =>
FContext -> Bool -> SimpleExpr -> a -> SimpleExpr -> a -> Bool
separate_pointer_domains FContext
ctxt Bool
True SimpleExpr
a0 a
si0 SimpleExpr
a1 a
si1
where
sep :: SimpleExpr -> SimpleExpr -> Bool
sep (SE_Immediate Word64
a0)
(SE_Immediate Word64
a1) =
Word64 -> a
forall a b. (Integral a, Num b) => a -> b
fromIntegral Word64
a0 a -> a -> a
forall a. Num a => a -> a -> a
+ a
si0 a -> a -> Bool
forall a. Ord a => a -> a -> Bool
<= Word64 -> a
forall a b. (Integral a, Num b) => a -> b
fromIntegral Word64
a1 Bool -> Bool -> Bool
|| Word64 -> a
forall a b. (Integral a, Num b) => a -> b
fromIntegral Word64
a1 a -> a -> a
forall a. Num a => a -> a -> a
+ a
si1 a -> a -> Bool
forall a. Ord a => a -> a -> Bool
<= Word64 -> a
forall a b. (Integral a, Num b) => a -> b
fromIntegral Word64
a0
sep (SE_Op (Minus Int
_) [SimpleExpr
v0, SE_Immediate Word64
i0])
(SE_Op (Minus Int
_) [SimpleExpr
v1, SE_Immediate Word64
i1]) =
if SimpleExpr -> SimpleExpr -> Bool
necessarily_equal SimpleExpr
v0 SimpleExpr
v1 then
Word64 -> a
forall a b. (Integral a, Num b) => a -> b
fromIntegral Word64
i0 a -> a -> a
forall a. Num a => a -> a -> a
- a
si0 a -> a -> Bool
forall a. Ord a => a -> a -> Bool
>= Word64 -> a
forall a b. (Integral a, Num b) => a -> b
fromIntegral Word64
i1 Bool -> Bool -> Bool
|| Word64 -> a
forall a b. (Integral a, Num b) => a -> b
fromIntegral Word64
i1 a -> a -> a
forall a. Num a => a -> a -> a
- a
si1 a -> a -> Bool
forall a. Ord a => a -> a -> Bool
>= Word64 -> a
forall a b. (Integral a, Num b) => a -> b
fromIntegral Word64
i0
else
FContext -> Bool -> SimpleExpr -> a -> SimpleExpr -> a -> Bool
forall a a.
(Integral a, Integral a) =>
FContext -> Bool -> SimpleExpr -> a -> SimpleExpr -> a -> Bool
separate_pointer_domains FContext
ctxt Bool
True SimpleExpr
a0 a
si0 SimpleExpr
a1 a
si1
sep (SE_Op (Minus Int
_) [SimpleExpr
v0, SE_Immediate Word64
i0])
(SE_Op (Plus Int
_) [SimpleExpr
v1, SE_Immediate Word64
i1]) =
if SimpleExpr -> SimpleExpr -> Bool
necessarily_equal SimpleExpr
v0 SimpleExpr
v1 then
Bool
True
else
FContext -> Bool -> SimpleExpr -> a -> SimpleExpr -> a -> Bool
forall a a.
(Integral a, Integral a) =>
FContext -> Bool -> SimpleExpr -> a -> SimpleExpr -> a -> Bool
separate_pointer_domains FContext
ctxt Bool
True SimpleExpr
a0 a
si0 SimpleExpr
a1 a
si1
sep (SE_Op (Plus Int
_) [SimpleExpr
v0, SE_Immediate Word64
i0])
(SE_Op (Minus Int
_) [SimpleExpr
v1, SE_Immediate Word64
i1]) =
if SimpleExpr -> SimpleExpr -> Bool
necessarily_equal SimpleExpr
v0 SimpleExpr
v1 then
Bool
True
else
FContext -> Bool -> SimpleExpr -> a -> SimpleExpr -> a -> Bool
forall a a.
(Integral a, Integral a) =>
FContext -> Bool -> SimpleExpr -> a -> SimpleExpr -> a -> Bool
separate_pointer_domains FContext
ctxt Bool
True SimpleExpr
a0 a
si0 SimpleExpr
a1 a
si1
sep (SE_Op (Minus Int
_) [SimpleExpr
v0, SE_Immediate Word64
i0])
SimpleExpr
v1 =
if SimpleExpr -> SimpleExpr -> Bool
necessarily_equal SimpleExpr
v0 SimpleExpr
v1 then
Word64 -> a
forall a b. (Integral a, Num b) => a -> b
fromIntegral Word64
i0 a -> a -> Bool
forall a. Ord a => a -> a -> Bool
>= a
si0
else
FContext -> Bool -> SimpleExpr -> a -> SimpleExpr -> a -> Bool
forall a a.
(Integral a, Integral a) =>
FContext -> Bool -> SimpleExpr -> a -> SimpleExpr -> a -> Bool
separate_pointer_domains FContext
ctxt Bool
True SimpleExpr
a0 a
si0 SimpleExpr
a1 a
si1
sep SimpleExpr
v0
(SE_Op (Minus Int
_) [SimpleExpr
v1, SE_Immediate Word64
i1]) =
if SimpleExpr -> SimpleExpr -> Bool
necessarily_equal SimpleExpr
v0 SimpleExpr
v1 then
Word64 -> a
forall a b. (Integral a, Num b) => a -> b
fromIntegral Word64
i1 a -> a -> Bool
forall a. Ord a => a -> a -> Bool
>= a
si1
else
FContext -> Bool -> SimpleExpr -> a -> SimpleExpr -> a -> Bool
forall a a.
(Integral a, Integral a) =>
FContext -> Bool -> SimpleExpr -> a -> SimpleExpr -> a -> Bool
separate_pointer_domains FContext
ctxt Bool
True SimpleExpr
a0 a
si0 SimpleExpr
a1 a
si1
sep (SE_Op (Plus Int
_) [SimpleExpr
v0, SE_Immediate Word64
i0])
(SE_Op (Plus Int
_) [SimpleExpr
v1, SE_Immediate Word64
i1]) =
if SimpleExpr -> SimpleExpr -> Bool
necessarily_equal SimpleExpr
v0 SimpleExpr
v1 then
Word64 -> a
forall a b. (Integral a, Num b) => a -> b
fromIntegral Word64
i0 a -> a -> a
forall a. Num a => a -> a -> a
+ a
si0 a -> a -> Bool
forall a. Ord a => a -> a -> Bool
<= Word64 -> a
forall a b. (Integral a, Num b) => a -> b
fromIntegral Word64
i1 Bool -> Bool -> Bool
|| Word64 -> a
forall a b. (Integral a, Num b) => a -> b
fromIntegral Word64
i1 a -> a -> a
forall a. Num a => a -> a -> a
+ a
si1 a -> a -> Bool
forall a. Ord a => a -> a -> Bool
<= Word64 -> a
forall a b. (Integral a, Num b) => a -> b
fromIntegral Word64
i0
else
FContext -> Bool -> SimpleExpr -> a -> SimpleExpr -> a -> Bool
forall a a.
(Integral a, Integral a) =>
FContext -> Bool -> SimpleExpr -> a -> SimpleExpr -> a -> Bool
separate_pointer_domains FContext
ctxt Bool
True SimpleExpr
a0 a
si0 SimpleExpr
a1 a
si1
sep (SE_Op (Plus Int
_) [SimpleExpr
v0, SE_Immediate Word64
i0])
SimpleExpr
v1 =
if SimpleExpr -> SimpleExpr -> Bool
necessarily_equal SimpleExpr
v0 SimpleExpr
v1 then
Word64 -> a
forall a b. (Integral a, Num b) => a -> b
fromIntegral Word64
i0 a -> a -> Bool
forall a. Ord a => a -> a -> Bool
>= a
si1
else
FContext -> Bool -> SimpleExpr -> a -> SimpleExpr -> a -> Bool
forall a a.
(Integral a, Integral a) =>
FContext -> Bool -> SimpleExpr -> a -> SimpleExpr -> a -> Bool
separate_pointer_domains FContext
ctxt Bool
True SimpleExpr
a0 a
si0 SimpleExpr
a1 a
si1
sep SimpleExpr
v1
(SE_Op (Plus Int
_) [SimpleExpr
v0,SE_Immediate Word64
i0]) =
if SimpleExpr -> SimpleExpr -> Bool
necessarily_equal SimpleExpr
v0 SimpleExpr
v1 then
Word64 -> a
forall a b. (Integral a, Num b) => a -> b
fromIntegral Word64
i0 a -> a -> Bool
forall a. Ord a => a -> a -> Bool
>= a
si1
else
FContext -> Bool -> SimpleExpr -> a -> SimpleExpr -> a -> Bool
forall a a.
(Integral a, Integral a) =>
FContext -> Bool -> SimpleExpr -> a -> SimpleExpr -> a -> Bool
separate_pointer_domains FContext
ctxt Bool
True SimpleExpr
a0 a
si0 SimpleExpr
a1 a
si1
sep SimpleExpr
a0 SimpleExpr
a1 = FContext -> Bool -> SimpleExpr -> a -> SimpleExpr -> a -> Bool
forall a a.
(Integral a, Integral a) =>
FContext -> Bool -> SimpleExpr -> a -> SimpleExpr -> a -> Bool
separate_pointer_domains FContext
ctxt Bool
True SimpleExpr
a0 a
si0 SimpleExpr
a1 a
si1
necessarily_separate_stateparts :: FContext -> StatePart -> StatePart -> Bool
necessarily_separate_stateparts FContext
ctxt (SP_Reg Register
r0) (SP_Reg Register
r1) = Register
r0 Register -> Register -> Bool
forall a. Eq a => a -> a -> Bool
/= Register
r1
necessarily_separate_stateparts FContext
ctxt (SP_Mem SimpleExpr
a0 Int
si0) (SP_Mem SimpleExpr
a1 Int
si1) = FContext -> SimpleExpr -> Int -> SimpleExpr -> Int -> Bool
forall a.
Integral a =>
FContext -> SimpleExpr -> a -> SimpleExpr -> a -> Bool
necessarily_separate FContext
ctxt SimpleExpr
a0 Int
si0 SimpleExpr
a1 Int
si1
necessarily_separate_stateparts FContext
_ StatePart
_ StatePart
_ = Bool
True
necessarily_equal :: SimpleExpr -> SimpleExpr -> Bool
necessarily_equal SimpleExpr
a0 SimpleExpr
a1 = SimpleExpr
a0 SimpleExpr -> SimpleExpr -> Bool
forall a. Eq a => a -> a -> Bool
== SimpleExpr
a1 Bool -> Bool -> Bool
&& Bool -> Bool
not (SimpleExpr -> Bool
contains_bot SimpleExpr
a0) Bool -> Bool -> Bool
&& Bool -> Bool
not (SimpleExpr -> Bool
contains_bot SimpleExpr
a1)
necessarily_equal_stateparts :: StatePart -> StatePart -> Bool
necessarily_equal_stateparts (SP_Reg Register
r0) (SP_Reg Register
r1) = Register
r0 Register -> Register -> Bool
forall a. Eq a => a -> a -> Bool
== Register
r1
necessarily_equal_stateparts (SP_Mem SimpleExpr
a0 Int
si0) (SP_Mem SimpleExpr
a1 Int
si1) = Int
si0 Int -> Int -> Bool
forall a. Eq a => a -> a -> Bool
== Int
si1 Bool -> Bool -> Bool
&& SimpleExpr -> SimpleExpr -> Bool
necessarily_equal SimpleExpr
a0 SimpleExpr
a1
necessarily_equal_stateparts StatePart
_ StatePart
_ = Bool
False
crossProduct :: [[a]] -> [[a]]
crossProduct :: [[a]] -> [[a]]
crossProduct [] = [[]]
crossProduct ([a]
as:[[a]]
ass) = [ a
ba -> [a] -> [a]
forall a. a -> [a] -> [a]
:[a]
bs | a
b <- [a]
as, [a]
bs <- [[a]] -> [[a]]
forall a. [[a]] -> [[a]]
crossProduct [[a]]
ass ]
crossProduct_size :: [t a] -> Int
crossProduct_size [t a]
x = [Int] -> Int
forall (t :: * -> *) a. (Foldable t, Num a) => t a -> a
product ([t a] -> Int
forall (t :: * -> *) a. Foldable t => t a -> Int
length [t a]
x Int -> [Int] -> [Int]
forall a. a -> [a] -> [a]
: (t a -> Int) -> [t a] -> [Int]
forall a b. (a -> b) -> [a] -> [b]
map t a -> Int
forall (t :: * -> *) a. Foldable t => t a -> Int
length [t a]
x)
unfold_non_determinism :: FContext -> SimpleExpr -> [SimpleExpr]
unfold_non_determinism :: FContext -> SimpleExpr -> [SimpleExpr]
unfold_non_determinism FContext
ctxt (Bottom (FromNonDeterminism Set SimpleExpr
es)) = Set SimpleExpr -> [SimpleExpr]
forall a. Set a -> [a]
S.toList Set SimpleExpr
es
unfold_non_determinism FContext
ctxt (SE_Op Operator
op [SimpleExpr]
es) =
let es' :: [[SimpleExpr]]
es' = (SimpleExpr -> [SimpleExpr]) -> [SimpleExpr] -> [[SimpleExpr]]
forall a b. (a -> b) -> [a] -> [b]
map (FContext -> SimpleExpr -> [SimpleExpr]
unfold_non_determinism FContext
ctxt) [SimpleExpr]
es in
if [[SimpleExpr]] -> Int
forall (t :: * -> *) a. Foldable t => [t a] -> Int
crossProduct_size [[SimpleExpr]]
es' Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
> Context -> Int
ctxt_max_expr_size (FContext -> Context
f_ctxt FContext
ctxt) then [SimpleExpr
rock_bottom] else ([SimpleExpr] -> SimpleExpr) -> [[SimpleExpr]] -> [SimpleExpr]
forall a b. (a -> b) -> [a] -> [b]
map (Operator -> [SimpleExpr] -> SimpleExpr
SE_Op Operator
op) ([[SimpleExpr]] -> [SimpleExpr]) -> [[SimpleExpr]] -> [SimpleExpr]
forall a b. (a -> b) -> a -> b
$ [[SimpleExpr]] -> [[SimpleExpr]]
forall a. [[a]] -> [[a]]
crossProduct [[SimpleExpr]]
es'
unfold_non_determinism FContext
ctxt (SE_Bit Int
b SimpleExpr
e) = (SimpleExpr -> SimpleExpr) -> [SimpleExpr] -> [SimpleExpr]
forall a b. (a -> b) -> [a] -> [b]
map (Int -> SimpleExpr -> SimpleExpr
SE_Bit Int
b) ([SimpleExpr] -> [SimpleExpr]) -> [SimpleExpr] -> [SimpleExpr]
forall a b. (a -> b) -> a -> b
$ (FContext -> SimpleExpr -> [SimpleExpr]
unfold_non_determinism FContext
ctxt) SimpleExpr
e
unfold_non_determinism FContext
ctxt (SE_SExtend Int
l Int
h SimpleExpr
e) = (SimpleExpr -> SimpleExpr) -> [SimpleExpr] -> [SimpleExpr]
forall a b. (a -> b) -> [a] -> [b]
map (Int -> Int -> SimpleExpr -> SimpleExpr
SE_SExtend Int
l Int
h) ([SimpleExpr] -> [SimpleExpr]) -> [SimpleExpr] -> [SimpleExpr]
forall a b. (a -> b) -> a -> b
$ (FContext -> SimpleExpr -> [SimpleExpr]
unfold_non_determinism FContext
ctxt) SimpleExpr
e
unfold_non_determinism FContext
ctxt (SE_Overwrite Int
l SimpleExpr
a SimpleExpr
b) =
let as :: [SimpleExpr]
as = FContext -> SimpleExpr -> [SimpleExpr]
unfold_non_determinism FContext
ctxt SimpleExpr
a
bs :: [SimpleExpr]
bs = FContext -> SimpleExpr -> [SimpleExpr]
unfold_non_determinism FContext
ctxt SimpleExpr
b in
if [[SimpleExpr]] -> Int
forall (t :: * -> *) a. Foldable t => [t a] -> Int
crossProduct_size [[SimpleExpr]
as,[SimpleExpr]
bs] Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
> Context -> Int
ctxt_max_expr_size (FContext -> Context
f_ctxt FContext
ctxt) then [SimpleExpr
rock_bottom] else [ Int -> SimpleExpr -> SimpleExpr -> SimpleExpr
SE_Overwrite Int
l SimpleExpr
a' SimpleExpr
b' | SimpleExpr
a' <- [SimpleExpr]
as, SimpleExpr
b' <- [SimpleExpr]
bs ]
unfold_non_determinism FContext
ctxt SimpleExpr
e = [SimpleExpr
e]
trim_expr :: FContext -> SimpleExpr -> SimpleExpr
trim_expr FContext
ctxt SimpleExpr
e =
if SimpleExpr -> Int
expr_size SimpleExpr
e Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
> Int
get_max_expr_size then
SimpleExpr
rock_bottom
else
SimpleExpr
e
where
get_max_expr_size :: Int
get_max_expr_size = Context -> Int
ctxt_max_expr_size (Context -> Int) -> Context -> Int
forall a b. (a -> b) -> a -> b
$ FContext -> Context
f_ctxt FContext
ctxt