packages feed

crux-llvm 0.8 → 0.9

raw patch · 8 files changed

+189/−159 lines, 8 filesdep ~basedep ~crucibledep ~crucible-llvmnew-uploaderPVP ok

version bump matches the API change (PVP)

Dependency ranges changed: base, crucible, crucible-llvm, crucible-symio, crux

API changes (from Hackage documentation)

- Crux.LLVM.Overrides: cbmcOverrides :: (IsSymInterface sym, HasLLVMAnn sym, HasPtrWidth wptr, wptr ~ ArchWidth arch, ?lc :: TypeContext, ?intrinsicsOpts :: IntrinsicsOptions, ?memOpts :: MemOptions) => Proxy# arch -> [OverrideTemplate (personality sym) sym arch rtp l a]
+ Crux.LLVM.Overrides: cbmcOverrides :: (IsSymInterface sym, HasLLVMAnn sym, HasPtrWidth wptr, wptr ~ ArchWidth arch, ?lc :: TypeContext, ?intrinsicsOpts :: IntrinsicsOptions, ?memOpts :: MemOptions) => Proxy# arch -> [OverrideTemplate (personality sym) sym ext arch]
- Crux.LLVM.Overrides: cruxLLVMOverrides :: (IsSymInterface sym, HasLLVMAnn sym, HasPtrWidth wptr, wptr ~ ArchWidth arch, ?lc :: TypeContext, ?intrinsicsOpts :: IntrinsicsOptions, ?memOpts :: MemOptions) => Proxy# arch -> [OverrideTemplate (personality sym) sym arch rtp l a]
+ Crux.LLVM.Overrides: cruxLLVMOverrides :: (IsSymInterface sym, HasLLVMAnn sym, HasPtrWidth wptr, wptr ~ ArchWidth arch, ?lc :: TypeContext, ?intrinsicsOpts :: IntrinsicsOptions, ?memOpts :: MemOptions) => Proxy# arch -> [OverrideTemplate (personality sym) sym ext arch]
- Crux.LLVM.Overrides: svCompOverrides :: (IsSymInterface sym, HasLLVMAnn sym, HasPtrWidth wptr) => [OverrideTemplate (personality sym) sym arch rtp l a]
+ Crux.LLVM.Overrides: svCompOverrides :: (IsSymInterface sym, HasLLVMAnn sym, HasPtrWidth wptr) => [OverrideTemplate (personality sym) sym ext arch]

Files

CHANGELOG.md view
@@ -1,3 +1,8 @@+# 0.9 -- 2024-08-30++* Add support for GHC 9.8+* The type signatures in `Crux.LLVM.Overrides` now use fewer type parameters in the `OverrideTemplates` that they return, in accordance with downstream changes from `crucible-llvm`.+ # 0.8 -- 2024-02-05  * Add support for LLVM bitcode files generated by Apple Clang on macOS.
README.md view
@@ -42,8 +42,8 @@    * `echo 'export PATH="/usr/local/opt/llvm/bin:$PATH"' >> ~/.bash_profile`    * run `crux-llvm` in a new console to reload `.bash_profile` -We have tested `crux-llvm` most heavily with GHC 8.10.7, GHC 9.2.7, GHC 9.4.4,-and `cabal` version 3.8.1.0. We recommend Yices 2.6.x, and Z3+We have tested `crux-llvm` most heavily with GHC 9.4, GHC 9.6, GHC 9.8,+and `cabal` version 3.10. We recommend Yices 2.6.x, and Z3 4.8.x. Technically, only one of Yices or Z3 is required, and CVC4 is also supported. However, in practice, having both tends to be convenient. Finally, LLVM versions from 3.6 through 16 are likely to
crux-llvm.cabal view
@@ -1,6 +1,6 @@ Cabal-version: 2.2 Name:          crux-llvm-Version:       0.8+Version:       0.9 Author:        Galois Inc. Maintainer:    rscott@galois.com, kquick@galois.com, langston@galois.com Copyright:     (c) Galois, Inc 2014-2022@@ -55,7 +55,7 @@                -Wincomplete-uni-patterns   ghc-prof-options: -O2   default-language: Haskell2010-  build-depends:    base >= 4.8 && < 4.19+  build-depends:    base >= 4.8 && < 4.20                   , bytestring                   , containers                   , crucible
src/Crux/LLVM/Compile.hs view
@@ -30,6 +30,7 @@ import           What4.Interface import           What4.ProgramLoc +import           Lang.Crucible.Panic ( panic ) import           Lang.Crucible.Simulator.SimError  import           Crux@@ -124,13 +125,20 @@   Log.SupportsCruxLLVMLogMessage msgs =>   CruxOptions -> LLVMOptions -> IO FilePath genBitCode cruxOpts llvmOpts =-  -- n.b. use of head here is OK because inputFiles should not be-  -- empty (and was previously verified as such in CruxLLVMMain).   if noCompile llvmOpts-  then return (head (Crux.inputFiles cruxOpts))+  then return headInputFile   else do-    let ofn = "crux~" <> (takeFileName $ head $ Crux.inputFiles cruxOpts) -<.> ".bc"+    let ofn = "crux~" <> takeFileName headInputFile -<.> ".bc"     genBitCodeToFile ofn (Crux.inputFiles cruxOpts) cruxOpts llvmOpts False+  where+    -- n.b. the use of partiality here is OK because inputFiles should not be+    -- empty (and was previously verified as such in CruxLLVMMain).+    headInputFile =+      case Crux.inputFiles cruxOpts of+        inputFile:_ -> inputFile+        [] -> panic+                "genBitCode"+                ["Unexpected empty list of files"]  -- | Given the target filename and a list of input files, along with -- the crux and llvm options, bitcode-compile each input .c file and
src/Crux/LLVM/Config.hs view
@@ -208,6 +208,9 @@                              , "'unstable-symbolic', which causes each read from uninitialized"                              , "memory to return a fresh symbolic value."                              ])+                       noSatisfyingWriteFreshConstant <-+                         Crux.section "no-satisfying-write-fresh-constant" Crux.yesOrNoSpec True+                           "Make a fresh constant for the NoSatisfyingWrite annotation."                        return MemOptions{..}           transOpts <- do laxArith <-
src/Crux/LLVM/Overrides.hs view
@@ -34,7 +34,7 @@ import What4.ProgramLoc( Position(..), ProgramLoc(..) ) import What4.Symbol(userSymbol, emptySymbol, safeSymbol) import What4.Interface-          (freshConstant, bvLit, bvAdd, asBV, predToBV,+          (freshConstant, bvLit, bvOne, bvAdd, asBV, predToBV,           getCurrentProgramLoc, printSymExpr, arrayUpdate, bvIsNonzero)  import Lang.Crucible.Types@@ -43,13 +43,14 @@ import Lang.Crucible.Simulator.ExecutionTree( printHandle ) import Lang.Crucible.Simulator.OverrideSim         ( getContext+        , getSymInterface         , readGlobal         , writeGlobal         , ovrWithBackend         ) import Lang.Crucible.Simulator.SimError (SimErrorReason(..),SimError(..)) import Lang.Crucible.Backend-          ( IsSymInterface, IsSymBackend, addDurableAssertion+          ( IsSymInterface, addDurableAssertion           , addAssumption, LabeledPred(..), CrucibleAssumption(..)           , backendGetSym           )@@ -82,7 +83,7 @@   ( IsSymInterface sym, HasLLVMAnn sym, HasPtrWidth wptr, wptr ~ ArchWidth arch   , ?lc :: TypeContext, ?intrinsicsOpts :: IntrinsicsOptions, ?memOpts :: MemOptions ) =>   Proxy# arch ->-  [OverrideTemplate (personality sym) sym arch rtp l a]+  [OverrideTemplate (personality sym) sym ext arch] cruxLLVMOverrides arch =   [ basic_llvm_override $         [llvmOvr| i8 @crucible_int8_t( i8* ) |]@@ -146,7 +147,7 @@    , basic_llvm_override $         [llvmOvr| void @crucible_dump_memory( ) |]-        (\mvar _sym _args ->+        (\mvar _args ->           do mem <- readGlobal mvar              h <- printHandle <$> getContext              liftIO (doDumpMem h mem))@@ -157,7 +158,7 @@   ( IsSymInterface sym, HasLLVMAnn sym, HasPtrWidth wptr, wptr ~ ArchWidth arch   , ?lc :: TypeContext, ?intrinsicsOpts :: IntrinsicsOptions, ?memOpts :: MemOptions ) =>   Proxy# arch ->-  [OverrideTemplate (personality sym) sym arch rtp l a]+  [OverrideTemplate (personality sym) sym ext arch] cbmcOverrides arch =   [ basic_llvm_override $       [llvmOvr| void @__CPROVER_assume( i32 ) |]@@ -259,7 +260,7 @@  svCompOverrides ::   (IsSymInterface sym, HasLLVMAnn sym, HasPtrWidth wptr) =>-  [OverrideTemplate (personality sym) sym arch rtp l a]+  [OverrideTemplate (personality sym) sym ext arch] svCompOverrides =   [ basic_llvm_override $         [llvmOvr| i64 @__VERIFIER_nondet_longlong() |]@@ -363,208 +364,200 @@        return (BS8.unpack (BS.pack bytes))  sv_comp_fresh_bits ::-  (IsSymBackend sym bak, 1 <= w) =>+  (IsSymInterface sym, 1 <= w) =>   NatRepr w ->   GlobalVar Mem ->-  bak ->   Assignment (RegEntry sym) EmptyCtx ->   OverM personality sym ext (RegValue sym (BVType w))-sv_comp_fresh_bits w _mvar _bak Empty = Crux.mkFresh (safeSymbol "X") (BaseBVRepr w)+sv_comp_fresh_bits w _mvar Empty = Crux.mkFresh (safeSymbol "X") (BaseBVRepr w)  sv_comp_fresh_float ::-  (IsSymBackend sym bak) =>+  IsSymInterface sym =>   FloatInfoRepr fi ->   GlobalVar Mem ->-  bak ->   Assignment (RegEntry sym) EmptyCtx ->   OverM personality sym ext (RegValue sym (FloatType fi))-sv_comp_fresh_float fi _mvar _bak Empty = Crux.mkFreshFloat (safeSymbol "X") fi+sv_comp_fresh_float fi _mvar Empty = Crux.mkFreshFloat (safeSymbol "X") fi  fresh_bits ::-  ( ArchOk arch, HasLLVMAnn sym, IsSymBackend sym bak, 1 <= w+  ( ArchOk arch, IsSymInterface sym, HasLLVMAnn sym, 1 <= w   , ?memOpts :: MemOptions ) =>   Proxy# arch ->   NatRepr w ->   GlobalVar Mem ->-  bak ->   Assignment (RegEntry sym) (EmptyCtx ::> TPtr arch) ->   OverM personality sym ext (RegValue sym (BVType w))-fresh_bits arch w mvar _ (Empty :> pName) =+fresh_bits arch w mvar (Empty :> pName) =   do name <- lookupString arch mvar pName      Crux.mkFresh (safeSymbol name) (BaseBVRepr w)  fresh_float ::-  ( ArchOk arch, IsSymBackend sym bak, HasLLVMAnn sym+  ( ArchOk arch, IsSymInterface sym, HasLLVMAnn sym   , ?memOpts :: MemOptions ) =>   Proxy# arch ->   FloatInfoRepr fi ->   GlobalVar Mem ->-  bak ->   Assignment (RegEntry sym) (EmptyCtx ::> TPtr arch) ->   OverM personality sym ext (RegValue sym (FloatType fi))-fresh_float arch fi mvar _ (Empty :> pName) =+fresh_float arch fi mvar (Empty :> pName) =   do name <- lookupString arch mvar pName      Crux.mkFreshFloat (safeSymbol name) fi  fresh_str ::-  ( ArchOk arch, IsSymBackend sym bak, HasLLVMAnn sym+  ( ArchOk arch, HasLLVMAnn sym   , ?memOpts :: MemOptions ) =>   Proxy# arch ->   GlobalVar Mem ->-  bak ->   Assignment (RegEntry sym) (EmptyCtx ::> TPtr arch ::> BVType (ArchWidth arch)) ->   OverM personality sym ext (RegValue sym (TPtr arch))-fresh_str arch mvar bak (Empty :> pName :> maxLen) =-  do let sym = backendGetSym bak-     name <- lookupString arch mvar pName+fresh_str arch mvar (Empty :> pName :> maxLen) =+  ovrWithBackend $ \bak -> do +    let sym = backendGetSym bak+    name <- lookupString arch mvar pName -     -- Compute the allocation length, which is the requested length plus one-     -- to hold the NUL terminator-     one <- liftIO $ bvLit sym ?ptrWidth (BV.one ?ptrWidth)-     -- maxLenBV <- liftIO $ projectLLVM_bv sym (regValue maxLen)-     len <- liftIO $ bvAdd sym (regValue maxLen) one-     mem0 <- readGlobal mvar+    -- Compute the allocation length, which is the requested length plus one+    -- to hold the NUL terminator+    one <- liftIO $ bvOne sym ?ptrWidth+    -- maxLenBV <- liftIO $ projectLLVM_bv sym (regValue maxLen)+    len <- liftIO $ bvAdd sym (regValue maxLen) one+    mem0 <- readGlobal mvar -     -- Allocate memory to hold the string-     (ptr, mem1) <- liftIO $ doMalloc bak HeapAlloc Mutable name mem0 len noAlignment+    -- Allocate memory to hold the string+    (ptr, mem1) <- liftIO $ doMalloc bak HeapAlloc Mutable name mem0 len noAlignment -     -- Allocate contents for the string - we want to make each byte symbolic,-     -- so we allocate a fresh array (which has unbounded length) with symbolic-     -- contents and write it into our allocation.  This write does not cover-     -- the NUL terminator.-     contentsName <- case userSymbol (name ++ "_contents") of-       Left err -> fail (show err)-       Right nm -> return nm-     let arrayRep = BaseArrayRepr (Empty :> BaseBVRepr ?ptrWidth) (BaseBVRepr (knownNat @8))-     initContents <- liftIO $ freshConstant sym contentsName arrayRep-     zeroByte <- liftIO $ bvLit sym (knownNat @8) (BV.zero knownNat)-     -- Put the NUL terminator in place-     initContentsZ <- liftIO $ arrayUpdate sym initContents (singleton (regValue maxLen)) zeroByte-     mem2 <- liftIO $ doArrayConstStore bak mem1 ptr noAlignment initContentsZ len+    -- Allocate contents for the string - we want to make each byte symbolic,+    -- so we allocate a fresh array (which has unbounded length) with symbolic+    -- contents and write it into our allocation.  This write does not cover+    -- the NUL terminator.+    contentsName <- case userSymbol (name ++ "_contents") of+      Left err -> fail (show err)+      Right nm -> return nm+    let arrayRep = BaseArrayRepr (Empty :> BaseBVRepr ?ptrWidth) (BaseBVRepr (knownNat @8))+    initContents <- liftIO $ freshConstant sym contentsName arrayRep+    zeroByte <- liftIO $ bvLit sym (knownNat @8) (BV.zero knownNat)+    -- Put the NUL terminator in place+    initContentsZ <- liftIO $ arrayUpdate sym initContents (singleton (regValue maxLen)) zeroByte+    mem2 <- liftIO $ doArrayConstStore bak mem1 ptr noAlignment initContentsZ len -     writeGlobal mvar mem2-     return ptr+    writeGlobal mvar mem2+    return ptr  do_assume ::-  ( ArchOk arch, IsSymBackend sym bak, HasLLVMAnn sym+  ( ArchOk arch, HasLLVMAnn sym   , ?memOpts :: MemOptions ) =>   Proxy# arch ->   GlobalVar Mem ->-  bak ->   Assignment (RegEntry sym) (EmptyCtx ::> TBits 8 ::> TPtr arch ::> TBits 32) ->   OverM personality sym ext (RegValue sym UnitType)-do_assume arch mvar bak (Empty :> p :> pFile :> line) =-  do let sym = backendGetSym bak-     cond <- liftIO $ bvIsNonzero sym (regValue p)-     file <- lookupString arch mvar pFile-     l <- case asBV (regValue line) of-            Just (BV.BV l)  -> return (fromInteger l)-            Nothing -> return 0-     let pos = SourcePos (T.pack file) l 0-     loc <- liftIO $ getCurrentProgramLoc sym-     let loc' = loc{ plSourceLoc = pos }-     liftIO $ addAssumption bak (GenericAssumption loc' "crucible_assume" cond)+do_assume arch mvar (Empty :> p :> pFile :> line) =+  ovrWithBackend $ \bak -> do +    let sym = backendGetSym bak+    cond <- liftIO $ bvIsNonzero sym (regValue p)+    file <- lookupString arch mvar pFile+    l <- case asBV (regValue line) of+           Just (BV.BV l)  -> return (fromInteger l)+           Nothing -> return 0+    let pos = SourcePos (T.pack file) l 0+    loc <- liftIO $ getCurrentProgramLoc sym+    let loc' = loc{ plSourceLoc = pos }+    liftIO $ addAssumption bak (GenericAssumption loc' "crucible_assume" cond)  do_assert ::-  ( ArchOk arch, IsSymBackend sym bak, HasLLVMAnn sym+  ( ArchOk arch, HasLLVMAnn sym   , ?intrinsicsOpts :: IntrinsicsOptions, ?memOpts :: MemOptions ) =>   Proxy# arch ->   GlobalVar Mem ->-  bak ->   Assignment (RegEntry sym) (EmptyCtx ::> TBits 8 ::> TPtr arch ::> TBits 32) ->   OverM personality sym ext (RegValue sym UnitType)-do_assert arch mvar bak (Empty :> p :> pFile :> line) =+do_assert arch mvar (Empty :> p :> pFile :> line) =   when (abnormalExitBehavior ?intrinsicsOpts == AlwaysFail) $-  do let sym = backendGetSym bak-     cond <- liftIO $ bvIsNonzero sym (regValue p)-     file <- lookupString arch mvar pFile-     l <- case asBV (regValue line) of-            Just (BV.BV l)  -> return (fromInteger l)-            Nothing -> return 0-     let pos = SourcePos (T.pack file) l 0-     loc <- liftIO $ getCurrentProgramLoc sym-     let loc' = loc{ plSourceLoc = pos }-     let msg = GenericSimError "crucible_assert"-     liftIO $ addDurableAssertion bak (LabeledPred cond (SimError loc' msg))+  ovrWithBackend $ \bak -> do+    let sym = backendGetSym bak+    cond <- liftIO $ bvIsNonzero sym (regValue p)+    file <- lookupString arch mvar pFile+    l <- case asBV (regValue line) of+           Just (BV.BV l)  -> return (fromInteger l)+           Nothing -> return 0+    let pos = SourcePos (T.pack file) l 0+    loc <- liftIO $ getCurrentProgramLoc sym+    let loc' = loc{ plSourceLoc = pos }+    let msg = GenericSimError "crucible_assert"+    liftIO $ addDurableAssertion bak (LabeledPred cond (SimError loc' msg)) -do_print_uint32 ::-  (IsSymBackend sym bak) =>+do_print_uint32 :: +  IsSymInterface sym =>   GlobalVar Mem ->-  bak ->   Assignment (RegEntry sym) (EmptyCtx ::> TBits 32) ->   OverM personality sym ext (RegValue sym UnitType)-do_print_uint32 _mvar _bak (Empty :> x) =+do_print_uint32 _mvar (Empty :> x) =   do h <- printHandle <$> getContext      liftIO $ hPutStrLn h (show (printSymExpr (regValue x)))  do_havoc_memory ::-  (ArchOk arch, IsSymBackend sym bak, HasLLVMAnn sym) =>+  (ArchOk arch, IsSymInterface sym, HasLLVMAnn sym) =>   Proxy# arch ->   GlobalVar Mem ->-  bak ->   Assignment (RegEntry sym) (EmptyCtx ::> TPtr arch ::> TBits (ArchWidth arch)) ->   OverM personality sym ext (RegValue sym UnitType)-do_havoc_memory _ mvar bak (Empty :> ptr :> len) =-  do let sym = backendGetSym bak-     let tp = BaseArrayRepr (Empty :> BaseBVRepr ?ptrWidth) (BaseBVRepr (knownNat @8))-     mem <- readGlobal mvar-     mem' <- liftIO $ do-               arr <- freshConstant sym emptySymbol tp-               doArrayStore bak mem (regValue ptr) noAlignment arr (regValue len)-     writeGlobal mvar mem'+do_havoc_memory _ mvar (Empty :> ptr :> len) =+  ovrWithBackend $ \bak ->+    do let sym = backendGetSym bak+       let tp = BaseArrayRepr (Empty :> BaseBVRepr ?ptrWidth) (BaseBVRepr (knownNat @8))+       mem <- readGlobal mvar+       mem' <- liftIO $ do+                 arr <- freshConstant sym emptySymbol tp+                 doArrayStore bak mem (regValue ptr) noAlignment arr (regValue len)+       writeGlobal mvar mem'  cprover_assume ::-  (IsSymBackend sym bak) =>   GlobalVar Mem ->-  bak ->   Assignment (RegEntry sym) (EmptyCtx ::> TBits 32) ->   OverM personality sym ext (RegValue sym UnitType)-cprover_assume _mvar bak (Empty :> p) = liftIO $-  do let sym = backendGetSym bak-     cond <- bvIsNonzero sym (regValue p)-     loc  <- getCurrentProgramLoc sym-     addAssumption bak (GenericAssumption loc "__CPROVER_assume" cond)+cprover_assume _mvar (Empty :> p) =+  ovrWithBackend $ \bak -> liftIO $ do+    let sym = backendGetSym bak+    cond <- bvIsNonzero sym (regValue p)+    loc  <- getCurrentProgramLoc sym+    addAssumption bak (GenericAssumption loc "__CPROVER_assume" cond)   cprover_assert ::-  ( ArchOk arch, IsSymBackend sym bak, HasLLVMAnn sym+  ( ArchOk arch, HasLLVMAnn sym   , ?intrinsicsOpts :: IntrinsicsOptions, ?memOpts :: MemOptions ) =>   Proxy# arch ->   GlobalVar Mem ->-  bak ->   Assignment (RegEntry sym) (EmptyCtx ::> TBits 32 ::> TPtr arch) ->   OverM personality sym ext (RegValue sym UnitType)-cprover_assert arch mvar bak (Empty :> p :> pMsg) =+cprover_assert arch mvar (Empty :> p :> pMsg) =   when (abnormalExitBehavior ?intrinsicsOpts == AlwaysFail) $-  do let sym = backendGetSym bak-     cond <- liftIO $ bvIsNonzero sym (regValue p)-     str <- lookupString arch mvar pMsg-     loc <- liftIO $ getCurrentProgramLoc sym-     let msg = AssertFailureSimError "__CPROVER_assert" str-     liftIO $ addDurableAssertion bak (LabeledPred cond (SimError loc msg))+  ovrWithBackend $ \bak ->+    do let sym = backendGetSym bak+       cond <- liftIO $ bvIsNonzero sym (regValue p)+       str <- lookupString arch mvar pMsg+       loc <- liftIO $ getCurrentProgramLoc sym+       let msg = AssertFailureSimError "__CPROVER_assert" str+       liftIO $ addDurableAssertion bak (LabeledPred cond (SimError loc msg))  cprover_r_ok ::-  (ArchOk arch, IsSymBackend sym bak, HasLLVMAnn sym) =>+  (ArchOk arch, IsSymInterface sym, HasLLVMAnn sym) =>   Proxy# arch ->   GlobalVar Mem ->-  bak ->   Assignment (RegEntry sym) (EmptyCtx ::> TPtr arch ::>  BVType (ArchWidth arch)) ->   OverM personality sym ext (RegValue sym (BVType 1))-cprover_r_ok _ mvar bak (Empty :> (regValue -> p) :> (regValue -> sz)) =-  do let sym = backendGetSym bak+cprover_r_ok _ mvar (Empty :> (regValue -> p) :> (regValue -> sz)) =+  do sym <- getSymInterface      mem <- readGlobal mvar      x <- liftIO $ isAllocatedAlignedPointer sym PtrWidth noAlignment Immutable p (Just sz) mem      liftIO $ predToBV sym x knownNat  cprover_w_ok ::-  (ArchOk arch, IsSymBackend sym bak, HasLLVMAnn sym) =>+  (ArchOk arch, IsSymInterface sym, HasLLVMAnn sym) =>   Proxy# arch ->   GlobalVar Mem ->-  bak ->   Assignment (RegEntry sym) (EmptyCtx ::> TPtr arch ::>  BVType (ArchWidth arch)) ->   OverM personality sym ext (RegValue sym (BVType 1))-cprover_w_ok _ mvar bak (Empty :> (regValue -> p) :> (regValue -> sz)) =-  do let sym = backendGetSym bak+cprover_w_ok _ mvar (Empty :> (regValue -> p) :> (regValue -> sz)) =+  do sym <- getSymInterface      mem <- readGlobal mvar      x <- liftIO $ isAllocatedAlignedPointer sym PtrWidth noAlignment Mutable p (Just sz) mem      liftIO $ predToBV sym x knownNat
src/Crux/LLVM/Simulate.hs view
@@ -13,7 +13,6 @@  module Crux.LLVM.Simulate where -import qualified Data.BitVector.Sized as BV import Data.String (fromString) import qualified Data.Map.Strict as Map import Data.IORef@@ -37,7 +36,7 @@  -- what4 import qualified What4.Expr.Builder as WEB-import What4.Interface (bvLit, natLit)+import What4.Interface (bvLit, bvZero)  -- crucible import Lang.Crucible.Backend@@ -66,8 +65,8 @@         ( Mem, MemImpl, mkMemVar, withPtrWidth, memAllocCount, memWriteCount         , MemOptions(..), HasLLVMAnn, LLVMAnnMap         , explainCex, CexExplanation(..), doAlloca-        , pattern LLVMPointer, pattern LLVMPointerRepr, LLVMPointerType-        , pattern PtrRepr, pattern PtrWidth+        , pattern LLVMPointerRepr, LLVMPointerType+        , pattern PtrRepr, pattern PtrWidth, llvmPointer_bv         ) import Lang.Crucible.LLVM.MemModel.CallStack (ppCallStack) import Lang.Crucible.LLVM.MemType (MemType(..), SymType(..), i8, memTypeAlign, memTypeSize)@@ -140,13 +139,13 @@          ?memOpts = memOpts llvmOpts       -- register the callable override functions-     register_llvm_overrides llvm_module []-       (concat [ cruxLLVMOverrides proxy#-               , svCompOverrides-               , cbmcOverrides proxy#-               , maybe [] symio_overrides fs0-               ])-       llvm_ctx+     _ <- register_llvm_overrides llvm_module []+            (concat [ cruxLLVMOverrides proxy#+                    , svCompOverrides+                    , cbmcOverrides proxy#+                    , maybe [] symio_overrides fs0+                    ])+            llvm_ctx       -- register all the functions defined in the LLVM module      registerLazyModule sayTranslationWarning mtrans@@ -339,7 +338,7 @@       mem <- case lookupGlobal memVar gs of                Just mem -> pure mem                Nothing  -> fail "checkFun.checkMainWithArguments: Memory missing from global vars"-      argc <- liftIO $ LLVMPointer <$> natLit sym 0 <*> bvLit sym w (BV.zero w)+      argc <- liftIO $ llvmPointer_bv sym =<< bvZero sym w       sz   <- liftIO $ bvLit sym PtrWidth $ bytesToBV PtrWidth tp_sz       (argv, mem') <- liftIO $ doAlloca bak mem sz alignment loc       stateTree.actFrame.gpGlobals %= insertGlobal memVar mem'
test/Test.hs view
@@ -12,7 +12,7 @@ import qualified Data.ByteString.Lazy as BSIO import qualified Data.ByteString.Lazy.Char8 as BSC import           Data.Char ( isLetter, isSpace )-import           Data.List.Extra ( isInfixOf, isPrefixOf )+import           Data.List.Extra ( isInfixOf ) import           Data.Maybe ( catMaybes, fromMaybe ) import qualified Data.Text as T import           Data.Versions ( Versioning, versioning, prettyV, major )@@ -21,6 +21,7 @@ import           System.Environment ( withArgs, lookupEnv ) import           System.Exit ( ExitCode(..) ) import           System.FilePath ( (-<.>) )+import qualified System.Info as Info import           System.IO import           System.Process ( readProcess ) import           Text.Read ( readMaybe )@@ -31,6 +32,8 @@ import           Test.Tasty.HUnit ( testCase, assertFailure ) import qualified Test.Tasty.Sugar as TS +import qualified Lang.Crucible.Panic as P+ import qualified CruxLLVMMain as C  @@ -42,6 +45,7 @@                  , TS.validParams = [ ("solver", Just ["z3", "cvc5"])                                     , ("loop-merging", Just ["loopmerge", "loop"])                                     , ("clang-range", Just [ "recent-clang"+                                                           , "pre-clang9"                                                            , "pre-clang11"                                                            , "pre-clang12"                                                            , "pre-clang13"@@ -101,7 +105,7 @@ getClangVersion = do   -- Determine which version of clang will be used for these tests.   -- An exception (E.g. in the readProcess if clang is not found) will-  -- result in termination (test failure).  Uses partial 'head' but+  -- result in termination (test failure).  Uses partiality, but   -- this is just tests, and failure is captured.   clangBin <- fromMaybe "clang" <$> lookupEnv "CLANG"   let isVerLine = isInfixOf "clang version"@@ -110,10 +114,27 @@       -- as tildes (cf. https://github.com/fosskers/versions/issues/62).       -- These have been observed in the wild (e.g., 12.0.0-3ubuntu1~20.04.5).       scrubProblemChars = filter (/= '~')++      headVersionLine :: [String] -> String+      headVersionLine ls =+        case ls of+          l:_ -> l+          [] -> P.panic+                  "getClangVersion"+                  ["`clang --version` output does not contain line with version"]++      headVersionWord :: [String] -> String+      headVersionWord ws =+        case ws of+          w:_ -> w+          [] -> P.panic+                  "getClangVersion"+                  ["`clang --version` output does not contain numeric version"]+       getVer (Right inp) =         -- example inp: "clang version 10.0.1"-        scrubProblemChars $ head $ dropLetter $ words $-        head $ filter isVerLine $ lines inp+        scrubProblemChars $ headVersionWord $ dropLetter $ words $+        headVersionLine $ filter isVerLine $ lines inp       getVer (Left full) = full   mkVC "clang" . getVer <$> readProcessVersion clangBin @@ -121,9 +142,9 @@ getZ3Version =   let getVer (Right inp) =         -- example inp: "Z3 version 4.8.7 - 64 bit"-        let w = words inp-        in if and [ length w > 2, head w == "Z3" ]-           then w !! 2 else "?"+        case words inp of+          "Z3":_:verNum:_ -> verNum+          _ -> "?"       getVer (Left full) = full   in mkVC "z3" . getVer <$> readProcessVersion "z3" @@ -131,9 +152,9 @@ getYicesVersion =   let getVer (Right inp) =         -- example inp: "Yices 2.6.1\nCopyright ..."-        let w = words inp-        in if and [ length w > 1, head w == "Yices" ]-           then w !! 1 else "?"+        case words inp of+          "Yices":verNum:_ -> verNum+          _ -> "?"       getVer (Left full) = full   in mkVC "yices" . getVer <$> readProcessVersion "yices" @@ -141,11 +162,9 @@ getSTPVersion =   let getVer (Right inp) =         -- example inp: "STP version 2.3.3\n..."-        let w = words inp-        in if and [ length w > 2-                  , head w == "STP"-                  , w !! 1 == "version" ]-           then w !! 2 else "?"+        case words inp of+          "STP":"version":verNum:_ -> verNum+          _ -> "?"       getVer (Left full) = full   in mkVC "stp" . getVer <$> readProcessVersion "stp" @@ -153,11 +172,9 @@ getCVC4Version =   let getVer (Right inp) =         -- example inp: "This is CVC4 version 1.8\ncompiled ..."-        let w = words inp-        in if and [ length w > 4-                  , "This is CVC4 version" `isPrefixOf` inp-                  ]-           then w !! 4 else "?"+        case words inp of+          "This":"is":"CVC4":"version":verNum:_ -> verNum+          _ -> "?"       getVer (Left full) = full   in mkVC "cvc4" . getVer <$> readProcessVersion "cvc4" @@ -165,11 +182,9 @@ getCVC5Version =   let getVer (Right inp) =         -- example inp: "This is cvc5 version 1.0.2\ncompiled ..."-        let w = words inp-        in if and [ length w > 4-                  , "This is cvc5 version" `isPrefixOf` inp-                  ]-           then w !! 4 else "?"+        case words inp of+          "This":"is":"cvc5":"version":verNum:_ -> verNum+          _ -> "?"       getVer (Left full) = full   in mkVC "cvc5" . getVer <$> readProcessVersion "cvc5" @@ -177,8 +192,9 @@ getBoolectorVersion =   let getVer (Right inp) =         -- example inp: "3.2.1"-        let w = words inp-        in if not (null w) then head w else "?"+        case words inp of+          verNum:_ -> verNum+          [] -> "?"       getVer (Left full) = full   in mkVC "boolector" . getVer <$> readProcessVersion "boolector" @@ -375,13 +391,19 @@                        , TS.rootBaseName sweet == "nested_unsafe"                        ] +    -- T972-fail requires an x86-64 compiler, so skip it on non-x86-64+    -- architectures.+    let skipX86_64Tests =+          Info.arch /= "x86_64" &&+          TS.rootBaseName sweet == "T972-fail"+     -- If a .good file begins with SKIP_TEST, skip that test entirely. For test     -- cases that require a minimum Clang version, this technique is used to     -- prevent running the test on older Clang versions.      skipTest <- ("SKIP_TEST" `BSIO.isPrefixOf`) <$> BSIO.readFile (TS.expectedFile expct) -    if or [ skipTest, testLevel == "0" && longTests ]+    if or [ skipTest, skipX86_64Tests, testLevel == "0" && longTests ]       then do         when (testLevel == "0" && longTests) $           putStrLn "*** Longer running test skipped; set CI_TEST_LEVEL=1 env var to enable"