packages feed

llvm-analysis-0.3.0: tests/ReturnTests.hs

module Main ( main ) where

import Data.Functor.Identity
import Data.Foldable ( toList )
import Data.HashSet ( HashSet )
import Data.Monoid
import Data.Set ( Set )
import qualified Data.Set as S
import System.FilePath ( (<.>) )
import System.Environment ( getArgs, withArgs )
import Test.HUnit ( assertEqual )

import LLVM.Analysis
import LLVM.Analysis.CFG
import LLVM.Analysis.CallGraph
import LLVM.Analysis.CallGraphSCCTraversal
import LLVM.Analysis.PointsTo.TrivialFunction
import LLVM.Analysis.NoReturn
import LLVM.Analysis.Util.Testing
import LLVM.Parse

main :: IO ()
main = do
  args <- getArgs
  let pattern = case args of
        [] -> "tests/noreturn/*.c"
        [infile] -> infile
  let testDescriptors = [ TestDescriptor { testPattern = pattern
                                         , testExpectedMapping = (<.> "expected")
                                         , testResultBuilder = analyzeReturns
                                         , testResultComparator = assertEqual
                                         }
                        ]

  withArgs [] $ testAgainstExpected opts parser testDescriptors
  where
    opts = ["-mem2reg", "-basicaa", "-gvn"]
    parser = parseLLVMFile defaultParserOptions

exitTest :: (Monad m) => ExternalFunction -> m Bool
exitTest ef = return $ "@exit" == efname
  where
    efname = show (externalFunctionName ef)

nameToString :: Function -> String
nameToString = show . functionName

runNoReturnAnalysis :: CallGraph -> (ExternalFunction -> Identity Bool) -> [Function]
runNoReturnAnalysis cg extSummary =
  let analysis :: [CFG] -> HashSet Function -> HashSet Function
      analysis = callGraphAnalysisM runIdentity (noReturnAnalysis extSummary)
      res = callGraphSCCTraversal cg analysis mempty
  in toList res


analyzeReturns :: Module -> Set String
analyzeReturns m = S.fromList $ map nameToString nrs
  where
    nrs = runNoReturnAnalysis cg exitTest -- runIdentity (noReturnAnalysis cg exitTest)
    pta = runPointsToAnalysis m
    cg = callGraph m pta []