Skip to content

Commit ab23a22

Browse files
committed
Support building with GHC 9.0
This contains a variety of fixes needed to make the packages in the `saw-script` repo compile with GHC 9.0: * GHC 9.0 implements simplified subsumption (see [here](https://gitlab.haskell.org/ghc/ghc/-/wikis/migration/9.0?version_id=5fcd0a50e0872efb3c38a32db140506da8310d87#simplified-subsumption)). This requires manually eta expanding some function applications to accommodate (see, for instance, the expansions of `getAllLLVM` in `SAWScript.Crucible.LLVM.MethodSpecIR`. * GHC's constraint solver now solves constraints in each top-level group sooner (see [here](https://gitlab.haskell.org/ghc/ghc/-/wikis/migration/9.0?version_id=5fcd0a50e0872efb3c38a32db140506da8310d87#the-order-of-th-splices-is-more-important)). This affects `heapster-saw`, as it uses declaration splices extensively. I did some fairly involved rearranging of data type declarations and TH-generated instances to make everything typecheck. It's not exactly pretty, but it gets the job done. * GHC 9.0 now enables `-Wstar-is-type` in `-Wall`, so this patch replaces some uses of `*` with `Data.Kind.Type` in `saw-core-what4` and `crux-mir-comp`. `Data.Kind` requires the use of GHC 8.0 or later, so this patch also updates the lower bounds on `base` to `>= 4.9` in the appropriate `.cabal` files. (I'm fairly certain that this requirement was already present implicity, but better to be explicit about it.) * The upper version bounds on `base` in `saw-remote-api` were raised to allow it to build with `base-4.15.*`, which is bundled with GHC 9.0. * The `cryptol` submodule was bumped to incorporate the changes from GaloisInc/cryptol#1233, which allow it to build with GHC 9.0.
1 parent f21c4ec commit ab23a22

File tree

17 files changed

+991
-963
lines changed

17 files changed

+991
-963
lines changed

README.md

+1-1
Original file line numberDiff line numberDiff line change
@@ -42,7 +42,7 @@ To build SAWScript and related utilities from source:
4242
* Ensure that you have the `cabal` and `ghc` executables in your
4343
`PATH`. If you don't already have them, we recommend using `ghcup`
4444
to install them: <https://www.haskell.org/ghcup/>. We recommend
45-
Cabal 3.4 or newer, and GHC 8.8 or 8.10.
45+
Cabal 3.4 or newer, and GHC 8.8, 8.10, or 9.0.
4646

4747
* Ensure that you have the C libraries and header files for
4848
`terminfo`, which generally comes as part of `ncurses` on most

crux-mir-comp/crux-mir-comp.cabal

+1-1
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@ extra-source-files: README.md
1919

2020
library
2121
default-language: Haskell2010
22-
build-depends: base >= 4.7 && < 5,
22+
build-depends: base >= 4.9 && < 5,
2323
text,
2424
prettyprinter >= 1.7.0,
2525
crucible,

crux-mir-comp/src/Mir/Compositional/Override.hs

+3-3
Original file line numberDiff line numberDiff line change
@@ -66,7 +66,7 @@ import Mir.Compositional.MethodSpec
6666
type MirOverrideMatcher sym a = forall p rorw rtp args ret.
6767
MS.OverrideMatcher' sym MIR rorw (OverrideSim (p sym) sym MIR rtp args ret) a
6868

69-
data MethodSpec = MethodSpec
69+
data MethodSpec = MethodSpec
7070
{ _msCollectionState :: CollectionState
7171
, _msSpec :: MIRMethodSpec
7272
}
@@ -244,7 +244,7 @@ runSpec cs mh ms = ovrWithBackend $ \bak ->
244244
-- TODO: see if we need any other assertions from LLVM OverrideMatcher
245245

246246

247-
-- Handle preconditions and postconditions.
247+
-- Handle preconditions and postconditions.
248248

249249
-- Convert preconditions to `osAsserts`
250250
forM_ (ms ^. MS.csPreState . MS.csConditions) $ \cond -> do
@@ -379,7 +379,7 @@ matchArg sym sc eval allocSpecs shp rv sv = go shp rv sv
379379
""
380380
go (TupleShape _ _ flds) rvs (MS.SetupStruct () False svs) = goFields flds rvs svs
381381
go (ArrayShape _ _ shp) vec (MS.SetupArray () svs) = case vec of
382-
MirVector_Vector v -> zipWithM_ (go shp) (toList v) svs
382+
MirVector_Vector v -> zipWithM_ (\x y -> go shp x y) (toList v) svs
383383
MirVector_PartialVector pv -> forM_ (zip (toList pv) svs) $ \(p, sv) -> do
384384
rv <- liftIO $ readMaybeType sym "vector element" (shapeType shp) p
385385
go shp rv sv

crux-mir-comp/src/Mir/Cryptol.hs

+3-2
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@ import Control.Monad.IO.Class
1919
import qualified Data.ByteString as BS
2020
import Data.Functor.Const
2121
import Data.IORef
22+
import qualified Data.Kind as Kind
2223
import Data.Map (Map)
2324
import qualified Data.Map as Map
2425
import Data.String (fromString)
@@ -241,10 +242,10 @@ loadCryptolFunc col sig modulePath name = do
241242
cryptolRun sc (Text.unpack fnName) argShps retShp (SAW.ttTerm tt)
242243

243244
where
244-
listToCtx :: forall k (f :: k -> *). [Some f] -> Some (Assignment f)
245+
listToCtx :: forall k (f :: k -> Kind.Type). [Some f] -> Some (Assignment f)
245246
listToCtx xs = go xs (Some Empty)
246247
where
247-
go :: forall k (f :: k -> *). [Some f] -> Some (Assignment f) -> Some (Assignment f)
248+
go :: forall k (f :: k -> Kind.Type). [Some f] -> Some (Assignment f) -> Some (Assignment f)
248249
go [] acc = acc
249250
go (Some x : xs) (Some acc) = go xs (Some $ acc :> x)
250251

heapster-saw/heapster-saw.cabal

+1
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,7 @@ library
3838
filepath,
3939
language-rust,
4040
hobbits ^>= 1.4,
41+
extra,
4142
hs-source-dirs: src
4243
build-tool-depends:
4344
alex:alex,

heapster-saw/src/Verifier/SAW/Heapster/CruUtil.hs

+12-12
Original file line numberDiff line numberDiff line change
@@ -371,8 +371,8 @@ $(mkNuMatching [t| UB.PtrComparisonOperator |])
371371
$(mkNuMatching [t| forall v. NuMatching v => StorageTypeF v |])
372372
$(mkNuMatching [t| StorageType |])
373373

374-
$(mkNuMatching [t| forall f. NuMatchingAny1 f => UB.UndefinedBehavior f |])
375374
$(mkNuMatching [t| forall f. NuMatchingAny1 f => Poison.Poison f |])
375+
$(mkNuMatching [t| forall f. NuMatchingAny1 f => UB.UndefinedBehavior f |])
376376
-- $(mkNuMatching [t| forall f. NuMatchingAny1 f => BadBehavior f |])
377377
-- $(mkNuMatching [t| forall f. NuMatchingAny1 f => LLVMSafetyAssertion f |])
378378
$(mkNuMatching [t| forall f. NuMatchingAny1 f => LLVMSideCondition f |])
@@ -390,17 +390,6 @@ instance NuMatchingAny1 (EmptyExprExtension f) where
390390

391391
$(mkNuMatching [t| AVXOp1 |])
392392
$(mkNuMatching [t| forall f tp. NuMatchingAny1 f => ExtX86 f tp |])
393-
$(mkNuMatching [t| forall f tp. NuMatchingAny1 f =>
394-
LLVMExtensionExpr f tp |])
395-
396-
instance NuMatchingAny1 f => NuMatchingAny1 (LLVMExtensionExpr f) where
397-
nuMatchingAny1Proof = nuMatchingProof
398-
399-
{-
400-
$(mkNuMatching [t| forall w f tp. NuMatchingAny1 f => LLVMStmt w f tp |])
401-
-}
402-
403-
$(mkNuMatching [t| forall tp. GlobalVar tp |])
404393

405394
instance NuMatching (Nonce s tp) where
406395
nuMatchingProof = unsafeMbTypeRepr
@@ -411,6 +400,17 @@ instance Closable (Nonce s tp) where
411400
instance Liftable (Nonce s tp) where
412401
mbLift = unClosed . mbLift . fmap toClosed
413402

403+
$(mkNuMatching [t| forall tp. GlobalVar tp |])
404+
$(mkNuMatching [t| forall f tp. NuMatchingAny1 f =>
405+
LLVMExtensionExpr f tp |])
406+
407+
instance NuMatchingAny1 f => NuMatchingAny1 (LLVMExtensionExpr f) where
408+
nuMatchingAny1Proof = nuMatchingProof
409+
410+
{-
411+
$(mkNuMatching [t| forall w f tp. NuMatchingAny1 f => LLVMStmt w f tp |])
412+
-}
413+
414414
instance Closable (BV.BV w) where
415415
toClosed = unsafeClose
416416

heapster-saw/src/Verifier/SAW/Heapster/Implication.hs

+33-24
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,7 @@ import qualified Data.BitVector.Sized as BV
3737
import GHC.TypeLits
3838
import Control.Lens hiding ((:>), ix)
3939
import Control.Applicative
40+
import Control.Monad.Extra (concatMapM)
4041
import Control.Monad.State.Strict hiding (ap)
4142

4243
import qualified Data.Type.RList as RL
@@ -1512,22 +1513,40 @@ idLocalPermImpl = LocalPermImpl $ PermImpl_Done $ LocalImplRet Refl
15121513

15131514
-- type IsLLVMPointerTypeList w ps = RAssign ((:~:) (LLVMPointerType w)) ps
15141515

1515-
$(mkNuMatching [t| forall a. EqPerm a |])
1516-
$(mkNuMatching [t| forall ps a. NuMatching a => EqProofStep ps a |])
1517-
$(mkNuMatching [t| forall ps a. NuMatching a => EqProof ps a |])
1518-
$(mkNuMatching [t| forall ps_in ps_out. SimplImpl ps_in ps_out |])
1519-
$(mkNuMatching [t| forall ps_in ps_outs. PermImpl1 ps_in ps_outs |])
1520-
$(mkNuMatching [t| forall r bs_pss. NuMatchingAny1 r => MbPermImpls r bs_pss |])
1521-
$(mkNuMatching [t| forall r ps. NuMatchingAny1 r => PermImpl r ps |])
1522-
$(mkNuMatching [t| forall ps_in ps_out. LocalPermImpl ps_in ps_out |])
1523-
$(mkNuMatching [t| forall ps ps'. LocalImplRet ps ps' |])
1524-
15251516
instance NuMatchingAny1 EqPerm where
15261517
nuMatchingAny1Proof = nuMatchingProof
15271518

15281519
instance NuMatchingAny1 (LocalImplRet ps) where
15291520
nuMatchingAny1Proof = nuMatchingProof
15301521

1522+
-- Many of these types are mutually recursive. Moreover, Template Haskell
1523+
-- declaration splices strictly separate top-level groups, so if we were to
1524+
-- write each $(mkNuMatching [t| ... |]) splice individually, the splices
1525+
-- involving mutually recursive types would not typecheck. As a result, we
1526+
-- must put everything into a single splice so that it forms a single top-level
1527+
-- group.
1528+
$(concatMapM mkNuMatching
1529+
[ [t| forall a. EqPerm a |]
1530+
, [t| forall ps a. NuMatching a => EqProofStep ps a |]
1531+
, [t| forall ps a. NuMatching a => EqProof ps a |]
1532+
, [t| forall ps_in ps_out. SimplImpl ps_in ps_out |]
1533+
, [t| forall ps_in ps_outs. PermImpl1 ps_in ps_outs |]
1534+
, [t| forall r bs_pss. NuMatchingAny1 r => MbPermImpls r bs_pss |]
1535+
, [t| forall r ps. NuMatchingAny1 r => PermImpl r ps |]
1536+
, [t| forall ps_in ps_out. LocalPermImpl ps_in ps_out |]
1537+
, [t| forall ps ps'. LocalImplRet ps ps' |]
1538+
])
1539+
1540+
-- | A splitting of an existential list of permissions into a prefix, a single
1541+
-- variable plus permission, and then a suffix
1542+
data DistPermsSplit ps where
1543+
DistPermsSplit :: RAssign Proxy ps1 -> RAssign Proxy ps2 ->
1544+
DistPerms (ps1 :++: ps2) ->
1545+
ExprVar a -> ValuePerm a ->
1546+
DistPermsSplit (ps1 :> a :++: ps2)
1547+
1548+
$(mkNuMatching [t| forall ps. DistPermsSplit ps |])
1549+
15311550

15321551
-- | Compile-time flag for whether to prune failure branches in 'implCatchM'
15331552
pruneFailingBranches :: Bool
@@ -6245,7 +6264,7 @@ proveVarLLVMArrayH x first_p _ ps mb_ap =
62456264

62466265
-- | Prove an array permission by proving its first cell and then its remaining
62476266
-- cells and appending them together
6248-
proveVarLLVMArray_FromHead ::
6267+
proveVarLLVMArray_FromHead ::
62496268
(1 <= w, KnownNat w, NuMatchingAny1 r) =>
62506269
ExprVar (LLVMPointerType w) -> Mb vars (LLVMArrayPerm w) ->
62516270
ImplM vars s r (ps :> LLVMPointerType w) ps ()
@@ -7063,7 +7082,7 @@ proveVarLLVMBlocks2 x ps psubst mb_bp mb_sh mb_bps
70637082
-- Prove the corresponding field permission
70647083
proveVarImplInt x (mbValPerm_LLVMField mb_fp) >>>
70657084
getTopDistPerm x >>>= \(ValPerm_LLVMField fp) ->
7066-
7085+
70677086
-- Finally, convert the field perm to a block and move it into position
70687087
implSimplM Proxy (SImpl_IntroLLVMBlockField x fp) >>>
70697088
implSwapInsertConjM x (Perm_LLVMBlock $ llvmFieldPermToBlock fp) ps' 0
@@ -7081,7 +7100,7 @@ proveVarLLVMBlocks2 x ps psubst mb_bp mb_sh mb_bps
70817100
proveVarImplInt x (mbMapCl $(mkClosed [| ValPerm_LLVMArray . fromJust .
70827101
llvmBlockPermToArray |]) mb_bp) >>>
70837102
getTopDistPerm x >>>= \(ValPerm_LLVMArray ap) ->
7084-
7103+
70857104
-- Finally, convert the array perm to a block and move it into position
70867105
implSimplM Proxy (SImpl_IntroLLVMBlockArray x ap) >>>
70877106
implSwapInsertConjM x (Perm_LLVMBlock $ fromJust $
@@ -7124,7 +7143,7 @@ proveVarLLVMBlocks2 x ps psubst mb_bp mb_sh mb_bps
71247143

71257144

71267145
-- If proving a tagged union shape, first prove an equality permission for the
7127-
-- tag and then use that equality permission to
7146+
-- tag and then use that equality permission to
71287147
proveVarLLVMBlocks2 x ps psubst mb_bp _ mb_bps
71297148
| Just [nuP| SomeTaggedUnionShape mb_tag_u |] <- mbLLVMBlockToTaggedUnion mb_bp
71307149
, mb_shs <- mbTaggedUnionDisjs mb_tag_u
@@ -8125,14 +8144,6 @@ funPermExDistIns fun_perm args =
81258144
fmap (varSubst (permVarSubstOfNames args)) $ mbSeparate args $
81268145
mbValuePermsToDistPerms $ funPermIns fun_perm
81278146

8128-
-- | A splitting of an existential list of permissions into a prefix, a single
8129-
-- variable plus permission, and then a suffix
8130-
data DistPermsSplit ps where
8131-
DistPermsSplit :: RAssign Proxy ps1 -> RAssign Proxy ps2 ->
8132-
DistPerms (ps1 :++: ps2) ->
8133-
ExprVar a -> ValuePerm a ->
8134-
DistPermsSplit (ps1 :> a :++: ps2)
8135-
81368147
-- | Make a "base case" 'DistPermsSplit' where the split is at the end
81378148
baseDistPermsSplit :: DistPerms ps -> ExprVar a -> ValuePerm a ->
81388149
DistPermsSplit (ps :> a)
@@ -8418,5 +8429,3 @@ proveVarsImplVarEVars mb_ps =
84188429
proveVarImpl :: NuMatchingAny1 r => ExprVar a -> Mb vars (ValuePerm a) ->
84198430
ImplM vars s r (ps :> a) ps ()
84208431
proveVarImpl x mb_p = proveVarsImplAppend $ fmap (distPerms1 x) mb_p
8421-
8422-
$(mkNuMatching [t| forall ps. DistPermsSplit ps |])

0 commit comments

Comments
 (0)