Added some copies of the checkInitVar tests that use the new occam EDSL testing instead of the old method
This commit is contained in:
parent
f4ff507543
commit
810c798dac
|
@ -20,7 +20,7 @@ with this program. If not, see <http://www.gnu.org/licenses/>.
|
|||
-- the control-flow graph stuff, hence the use of functions that match the dictionary
|
||||
-- of functions in FlowGraph. This is also why we don't drill down into processes;
|
||||
-- the control-flow graph means that we only need to concentrate on each node that isn't nested.
|
||||
module Check (checkInitVar, usageCheckPass, checkUnusedVar) where
|
||||
module Check (checkInitVar, checkInitVarPass, usageCheckPass, checkUnusedVar) where
|
||||
|
||||
import Control.Monad.Identity
|
||||
import Control.Monad.Trans
|
||||
|
@ -183,6 +183,16 @@ showCodeExSet (NormalSet s)
|
|||
= do ss <- mapM showCode (Set.toList s)
|
||||
return $ "{" ++ concat (intersperse ", " ss) ++ "}"
|
||||
|
||||
checkInitVarPass :: Pass
|
||||
checkInitVarPass = pass "checkInitVar" [] []
|
||||
(passOnlyOnAST "checkInitVar" $
|
||||
\t -> do g' <- buildFlowGraph labelUsageFunctions t
|
||||
(g, roots) <- case g' of
|
||||
Left err -> dieP (findMeta t) err
|
||||
Right (g,rs,_) -> return (g,rs)
|
||||
mapM_ (checkInitVar (findMeta t) g) roots
|
||||
return t)
|
||||
|
||||
-- | Checks that no variable is used uninitialised. That is, it checks that every variable is written to before it is read.
|
||||
checkInitVar :: forall m. (Monad m, Die m, Warn m, CSMR m) => Meta -> FlowGraph m UsageLabel -> Node -> m ()
|
||||
checkInitVar m graph startNode
|
||||
|
@ -274,7 +284,8 @@ checkProcCallArgsUsage = mapM_ checkArgs . listify isProcCall
|
|||
checkPlainVarUsage (m, mockedupParItems)
|
||||
checkArrayUsage (m, fmap ((,) []) mockedupParItems)
|
||||
|
||||
|
||||
-- TODO in future change this back to using listify. It just so happened to make
|
||||
-- a good test for my new check stuff.
|
||||
checkUnusedVar :: CheckOptM ()
|
||||
checkUnusedVar = forAnyASTStruct doSpec
|
||||
where
|
||||
|
|
|
@ -32,6 +32,7 @@ import CompState
|
|||
import Errors
|
||||
import FlowGraph
|
||||
import Metadata
|
||||
import OccamEDSL
|
||||
import TestFramework
|
||||
import TestUtils hiding (Var)
|
||||
import UsageCheckAlgorithms
|
||||
|
@ -146,8 +147,46 @@ buildTestFlowGraph ns es start end v
|
|||
testInitVar :: Test
|
||||
testInitVar = TestList
|
||||
[
|
||||
test "No variables" $ wrap $ oSEQ []
|
||||
,test "One unused variable" $ wrap $ oSEQ [decl (return A.Int) oX []]
|
||||
,test "One written-to variable" $ wrap $
|
||||
oSEQ [
|
||||
decl (return A.Int) oX [
|
||||
oX *:= return (3::Int)
|
||||
]]
|
||||
,test "One written-to then self-assigned variable" $ wrap $
|
||||
oSEQ [
|
||||
decl (return A.Int) oX [
|
||||
oX *:= return (3::Int)
|
||||
,oX *:= oX
|
||||
]]
|
||||
,testWarn "One uninit self-assign" $ wrap $
|
||||
oSEQ [
|
||||
decl (return A.Int) oX [
|
||||
oX *:= oX
|
||||
]]
|
||||
,testWarn "One written-to variable, one uninit variable" $ wrap $
|
||||
oSEQ [
|
||||
decl (return A.Int) oX [
|
||||
decl (return A.Int) oY [
|
||||
oX *:= oY
|
||||
]]]
|
||||
,test "Two parallel written-to variables, then another init" $ wrap $
|
||||
oSEQ [
|
||||
decl (return A.Int) oX [
|
||||
decl (return A.Int) oY [
|
||||
oPAR [
|
||||
oX *:= return (3::Int)
|
||||
,oY *:= return (4::Int)
|
||||
]
|
||||
,decl (return A.Int) oZ [
|
||||
oZ *:= oX *+ oY
|
||||
,oX *:= oZ
|
||||
]
|
||||
]]]
|
||||
|
||||
-- Single node, x not touched
|
||||
testInitVarPass 0 [(0,[],[])] [] 0 0 "x"
|
||||
,testInitVarPass 0 [(0,[],[])] [] 0 0 "x"
|
||||
-- Single node, x written to
|
||||
,testInitVarPass 1 [(0,[],[variable "x"])] [] 0 0 "x"
|
||||
-- Single node, x read from (FAIL)
|
||||
|
@ -242,6 +281,13 @@ testInitVar = TestList
|
|||
|
||||
variable = Var . A.Variable emptyMeta . simpleName
|
||||
|
||||
wrap x = oPROC "foo" [] x oempty
|
||||
|
||||
test, testWarn :: String -> Occ A.AST -> Test
|
||||
test name x = testOccamPassWarn ("checkInitVar " ++ name) null x checkInitVarPass
|
||||
testWarn name x = testOccamPassWarn ("checkInitVar " ++ name) (not . null) x checkInitVarPass
|
||||
|
||||
|
||||
{-
|
||||
testReachDef :: Test
|
||||
testReachDef = TestList
|
||||
|
|
|
@ -19,10 +19,10 @@ with this program. If not, see <http://www.gnu.org/licenses/>.
|
|||
-- | The necessary components for using an occam EDSL (for building test-cases).
|
||||
module OccamEDSL (ExpInp, ExpInpT, oSEQ, oPAR, oPROC, oSKIP, oINT,
|
||||
oCASE, oCASEinput, oALT, guard,
|
||||
Occ, oA, oB, oC, oX, oY, oZ, p0, p1, p2, (*?), (*!), (*:=), decl, decl', decl'',
|
||||
Occ, oA, oB, oC, oX, oY, oZ, p0, p1, p2, (*?), (*!), (*:=), (*+), decl, decl', decl'',
|
||||
oempty, testOccamPass,
|
||||
oprocess,
|
||||
testOccamPassTransform, ExpInpC(shouldComeFrom),
|
||||
testOccamPassWarn, testOccamPassTransform, ExpInpC(shouldComeFrom),
|
||||
caseOption, inputCaseOption,
|
||||
becomes) where
|
||||
|
||||
|
@ -33,6 +33,7 @@ import Test.HUnit hiding (State)
|
|||
|
||||
import qualified AST as A
|
||||
import CompState
|
||||
import Errors
|
||||
import Metadata
|
||||
import Pass
|
||||
import Pattern
|
||||
|
@ -257,6 +258,14 @@ oZ = return $ variable "Z"
|
|||
return $ A.Only emptyMeta $ A.Assign emptyMeta [dest] (A.ExpressionList emptyMeta
|
||||
[src])
|
||||
|
||||
infix 8 *:=
|
||||
|
||||
(*+) :: (CanBeExpression e, CanBeExpression e') => e -> e' -> ExpInp (A.Expression)
|
||||
(*+) x y = do x' <- expr x
|
||||
y' <- expr y
|
||||
return (A.Dyadic emptyMeta A.Add x' y')
|
||||
|
||||
|
||||
decl :: Data a => ExpInp A.Type -> ExpInp A.Variable ->
|
||||
[O (A.Structured a)] -> O (A.Structured a)
|
||||
decl bty bvar scope = do
|
||||
|
@ -330,6 +339,21 @@ testOccamPass str code pass
|
|||
in TestCase $ testPassWithStateCheck str exp pass inp (put inpS) (assertEqual
|
||||
str (csNames expS) . csNames)
|
||||
|
||||
-- | Give back True if the result is as expected for the warnings
|
||||
testOccamPassWarn :: Data a => String -> ([WarningReport] -> Bool) -> O a -> Pass -> Test
|
||||
testOccamPassWarn str check code pass
|
||||
= let ExpInpT expm inpm = code
|
||||
(exp, expS) = runState expm emptyState
|
||||
(inp, inpS) = runState inpm emptyState
|
||||
pass' = pass {passCode = \x -> do y <- passCode pass x
|
||||
b <- lift (lift get) >>* check
|
||||
when (not b) $
|
||||
dieP emptyMeta $ str ++ " warnings not as expected"
|
||||
return y}
|
||||
in TestCase $ testPassWithStateCheck str exp pass' inp (put inpS) (assertEqual
|
||||
str (csNames expS) . csNames)
|
||||
|
||||
|
||||
-- | Like testOccamPass, but applies a transformation to the patterns (such as
|
||||
-- using stopCaringPattern) before pattern-matching
|
||||
testOccamPassTransform :: Data a => String -> (Pattern -> Pattern) -> O a -> Pass -> Test
|
||||
|
|
Loading…
Reference in New Issue
Block a user