hic-0.0.0.1: test/Language/Cimple/Analysis/GlobalStructuralAnalysisSpec.hs
{-# LANGUAGE OverloadedStrings #-}
module Language.Cimple.Analysis.GlobalStructuralAnalysisSpec (spec) where
import qualified Data.Map.Strict as Map
import qualified Data.Set as Set
import Language.Cimple.Analysis.GlobalStructuralAnalysis
import Language.Cimple.Hic.InferenceSpec (mustParse)
import Test.Hspec
spec :: Spec
spec = describe "Language.Cimple.Analysis.GlobalStructuralAnalysis" $ do
it "identifies structs with void* as hotspots" $ do
prog <- mustParse ["struct My_Struct { void *p; };"]
let res = runGlobalStructuralAnalysis prog
garHotspots res `shouldBe` Set.fromList [StructHotspot "My_Struct"]
it "identifies structs with templates as hotspots" $ do
-- Template is inferred for void* in our system
prog <- mustParse ["struct My_Struct { void *p; };"]
let res = runGlobalStructuralAnalysis prog
garHotspots res `shouldBe` Set.fromList [StructHotspot "My_Struct"]
it "identifies functions with void* as hotspots" $ do
prog <- mustParse ["void my_f(void *p);"]
let res = runGlobalStructuralAnalysis prog
garHotspots res `shouldBe` Set.fromList [FunctionHotspot "my_f"]
it "does not identify simple structs as hotspots" $ do
prog <- mustParse ["struct My_Struct { int x; };"]
let res = runGlobalStructuralAnalysis prog
garHotspots res `shouldBe` Set.empty
it "identifies unions with void* as hotspots" $ do
prog <- mustParse ["union My_Union { void *p; int x; };"]
let res = runGlobalStructuralAnalysis prog
garHotspots res `shouldBe` Set.fromList [StructHotspot "My_Union"]
it "identifies functions with generic return types as hotspots" $ do
prog <- mustParse ["void *my_f(int x);"]
let res = runGlobalStructuralAnalysis prog
garHotspots res `shouldBe` Set.fromList [FunctionHotspot "my_f"]
it "identifies structs with generic arrays as hotspots" $ do
prog <- mustParse ["struct My_Struct { void *arr[10]; };"]
let res = runGlobalStructuralAnalysis prog
garHotspots res `shouldBe` Set.fromList [StructHotspot "My_Struct"]
it "propagates hotspots through typedefs" $ do
prog <- mustParse
[ "typedef void *Generic;"
, "struct My_Struct { Generic p; };"
]
let res = runGlobalStructuralAnalysis prog
garHotspots res `shouldBe` Set.fromList [StructHotspot "My_Struct"]
it "does not identify concrete pointers as hotspots" $ do
prog <- mustParse
[ "struct My_Struct { int *p; };"
, "void my_f(int *p);"
]
let res = runGlobalStructuralAnalysis prog
garHotspots res `shouldBe` Set.empty
it "does not identify concrete typedefs as hotspots" $ do
prog <- mustParse
[ "typedef int My_Int;"
, "typedef My_Int *My_Int_Ptr;"
, "struct My_Struct { My_Int_Ptr p; };"
, "void my_f(My_Int x);"
]
let res = runGlobalStructuralAnalysis prog
garHotspots res `shouldBe` Set.empty
it "does not identify forward declared concrete structs as hotspots" $ do
prog <- mustParse
[ "struct My_Struct;"
, "void my_f(struct My_Struct *s);"
, "struct My_Struct { int x; };"
]
let res = runGlobalStructuralAnalysis prog
garHotspots res `shouldBe` Set.empty
it "does not identify void functions or parameters as hotspots" $ do
prog <- mustParse
[ "void my_f(void);"
, "void my_g();"
]
let res = runGlobalStructuralAnalysis prog
garHotspots res `shouldBe` Set.empty
it "handles complex nested generic types in hotspots" $ do
prog <- mustParse
[ "struct My_Struct { int x; };"
, "void my_f(struct My_Struct *s);" -- Not generic
, "void my_g_func(void *p);" -- Generic
, "struct My_G_struct { void **pp; };" -- Generic
]
let res = runGlobalStructuralAnalysis prog
garHotspots res `shouldBe` Set.fromList [FunctionHotspot "my_g_func", StructHotspot "My_G_struct"]
it "identifies deep generic pointers as hotspots" $ do
prog <- mustParse ["typedef void *GenericPointer; struct My_Struct { GenericPointer **ppp; };"]
let res = runGlobalStructuralAnalysis prog
garHotspots res `shouldBe` Set.fromList [StructHotspot "My_Struct"]
it "identifies structs with _Owned pointers as hotspots" $ do
prog <- mustParse ["struct My_Struct { int *_Owned p; };"]
let res = runGlobalStructuralAnalysis prog
garHotspots res `shouldBe` Set.fromList [StructHotspot "My_Struct"]
it "identifies functions with _Owned parameters as hotspots" $ do
prog <- mustParse ["void my_f(int *_Owned p);"]
let res = runGlobalStructuralAnalysis prog
garHotspots res `shouldBe` Set.fromList [FunctionHotspot "my_f"]