diff --git a/README.md b/README.md
--- a/README.md
+++ b/README.md
@@ -42,8 +42,52 @@
 
 #### GHC compatibility
 
-Argon is compatible with GHC 7.8 and 7.10, it's tested against those versions
-only.
+Argon is compatible with GHC version 8.0.2 and above. In the
+[releases](https://github.com/rubik/argon/releases) page you can find binaries
+for older versions of `argon` which support GHC versions 7.8 and 7.10.
+
+### About the complexity being measured
+
+`argon` will compute the [cyclomatic
+complexity](https://en.wikipedia.org/wiki/Cyclomatic_complexity) of Haskell
+functions, which is the number of decisions in a block of code plus 1. For
+instance the following function:
+
+```haskell
+func n = case n of
+           2 -> 3
+           4 -> 6
+           _ -> 42
+```
+
+has a cyclomatic complexity of 3.
+
+The boolean operators `&&` and `||` also affect the this number. For instance
+the following function:
+
+```haskell
+g n = n < 68 && n `mod` 3 == 2 && n > 49
+```
+has a cyclomatic complexity of 3.
+
+As a last example, the following function:
+
+```haskell
+func n = case n of
+           2 -> 3
+           4 -> 6
+           _ -> if 0 < n
+                then 7
+                else 8
+```
+
+has a cyclomatic complexity of 5.
+
+Cyclomatic complexity provides a very shallow metric of code complexity: a high
+cyclomatic complexity number does not necessarily mean that the function is
+complex, and conversely, a low number does not necessarily indicate that the
+function is simple. However, this number it can be useful for highlighting
+potential maintainability issues.
 
 ### Running
 
diff --git a/argon.cabal b/argon.cabal
--- a/argon.cabal
+++ b/argon.cabal
@@ -1,5 +1,5 @@
 name:                argon
-version:             0.4.1.0
+version:             0.4.2.0
 synopsis:            Measure your code's complexity
 homepage:            http://github.com/rubik/argon
 bug-reports:         http://github.com/rubik/argon/issues
@@ -10,7 +10,7 @@
 copyright:           2015 Michele Lacchia
 category:            Development, Static Analysis
 build-type:          Simple
-cabal-version:       >=1.18
+cabal-version:       1.18
 description:
     Argon performs static analysis on your code in order to compute cyclomatic
     complexity. It is a quantitative measure of the number of linearly
@@ -21,7 +21,6 @@
     JSON.
 extra-source-files:
     stack.yaml
-    stack-7.8.yaml
     README.md
     CHANGELOG.md
     USAGE.txt
@@ -33,7 +32,7 @@
     test/tree/*.txt
     test/tree/sub/*.hs
     test/tree/sub2/*.hs
-tested-with: GHC >= 7.8 && < 8
+tested-with: GHC >= 8.0.2 && < 9
 
 library
   hs-source-dirs:      src
@@ -49,24 +48,31 @@
                        Argon.SYB.Utils
                        Argon.Walker
   build-depends:       base             >=4.7    && <5
-                     , ansi-terminal    >=0.6
-                     , aeson            >=0.8
-                     , bytestring       >=0.10
-                     , pipes            >=4.1
-                     , pipes-group      >=1.0
-                     , pipes-files      >=0.1
-                     , pipes-safe       >=2.2
-                     , pipes-bytestring >=2.1
-                     , lens-simple      >=0.1
-                     , ghc              >=7.8    && <8
-                     , ghc-paths        >=0.1
-                     , ghc-syb-utils    >=0.2
-                     , syb              >=0.4
-                     , Cabal            >=1.18
-                     , containers       >=0.5
-                     , directory        >=1.2
+                     , ansi-terminal
+                     , aeson
+                     , bytestring
+                     , pipes
+                     , pipes-group
+                     , pipes-safe
+                     , pipes-bytestring
+                     , lens-simple
+                     , ghc
+                     , ghc-boot
+                     , ghc-paths
+                     , ghc-syb-utils
+                     , syb
+                     , Cabal
+                     , containers
+                     , directory
+                     , system-filepath
+                     , dirstream
+                     , filepath
   default-language:    Haskell2010
   ghc-options:         -Wall
+                       -Wcompat
+                       -Wincomplete-record-updates
+                       -Wincomplete-uni-patterns
+                       -Wredundant-constraints
   if impl(ghc < 7.8)
     buildable: False
 
@@ -89,16 +95,18 @@
   main-is:             Spec.hs
   other-modules:       ArgonSpec
   build-depends:       base             >=4.7    && <5
-                     , argon            -any
-                     , ansi-terminal    >=0.6
-                     , ghc              >=7.8    && <8
-                     , aeson            >=0.8
-                     , hspec            >=2.1
-                     , QuickCheck       -any
-                     , filepath         >=1.3
-                     , pipes            >=4.1
-                     , pipes-safe       >=2.2
-  ghc-options:         -Wall -threaded -rtsopts -with-rtsopts=-N
+                     , argon
+                     , ansi-terminal
+                     , ghc
+                     , aeson
+                     , hspec
+                     , QuickCheck
+                     , filepath
+                     , pipes
+                     , pipes-safe
+  ghc-options:         -Wall
+                       -threaded -rtsopts -with-rtsopts=-N
+
   default-language:    Haskell2010
   if impl(ghc < 7.8)
     buildable: False
@@ -107,8 +115,8 @@
   type:                exitcode-stdio-1.0
   hs-source-dirs:      test
   main-is:             HLint.hs
-  build-depends:       base  ==4.*
-                     , hlint ==1.*
+  build-depends:       base             >=4.7   &&  <5
+                     , hlint
   default-language:    Haskell2010
   ghc-options:         -Wall
 
diff --git a/src/Argon.hs b/src/Argon.hs
--- a/src/Argon.hs
+++ b/src/Argon.hs
@@ -23,7 +23,6 @@
     , analyze
     , parseModule
     , parseExts
-    , flagsMap
     -- * Manipulating results
     , order
     , filterResults
@@ -40,7 +39,7 @@
 
 import Argon.Parser (LModule, analyze, parseModule)
 import Argon.Results (order, filterResults, filterNulls, exportStream)
-import Argon.Cabal (flagsMap, parseExts)
+import Argon.Cabal (parseExts)
 import Argon.Types
 import Argon.Loc
 import Argon.Walker (allFiles)
diff --git a/src/Argon/Cabal.hs b/src/Argon/Cabal.hs
--- a/src/Argon/Cabal.hs
+++ b/src/Argon/Cabal.hs
@@ -1,46 +1,34 @@
 {-# LANGUAGE CPP #-}
-module Argon.Cabal (flagsMap, parseExts)
+module Argon.Cabal (parseExts)
     where
 
-import Data.Maybe (mapMaybe)
-import Data.Map.Strict (Map)
-import qualified Data.Map.Strict as M
+import           Data.List                             (nub)
 #if __GLASGOW_HASKELL__ < 710
-import Control.Applicative ((<$>))
-#else
-import Control.Arrow ((&&&))
+import           Control.Applicative                   ((<$>))
 #endif
 
-import qualified DynFlags as GHC
-import qualified Language.Haskell.Extension            as Dist
-import qualified Distribution.Verbosity                as Dist
 import qualified Distribution.PackageDescription       as Dist
 import qualified Distribution.PackageDescription.Parse as Dist
+import qualified Distribution.Verbosity                as Dist
+import qualified Language.Haskell.Extension            as Dist
 
 
--- | A 'Map' from extensions names to extensions flags
-flagsMap :: Map String GHC.ExtensionFlag
-flagsMap = M.fromList $ map specToPair GHC.xFlags
-
 -- | Parse the given Cabal file generate a list of GHC extension flags. The
 --   extension names are read from the default-extensions field in the library
 --   section.
-parseExts :: FilePath -> IO [GHC.ExtensionFlag]
+parseExts :: FilePath -> IO [String]
+#if __GLASGOW_HASKELL__ < 802
 parseExts path = extract <$> Dist.readPackageDescription Dist.silent path
+#else
+parseExts path = extract <$> Dist.readGenericPackageDescription Dist.silent path
+#endif
     where extract pkg = maybe [] extFromBI $
-            (Dist.libBuildInfo . Dist.condTreeData) <$> Dist.condLibrary pkg
+            Dist.libBuildInfo . Dist.condTreeData <$> Dist.condLibrary pkg
 
-extFromBI :: Dist.BuildInfo -> [GHC.ExtensionFlag]
-extFromBI = mapMaybe (get . toString) . Dist.defaultExtensions
-    where get = flip M.lookup flagsMap
-          toString (Dist.UnknownExtension ext) = ext
+extFromBI :: Dist.BuildInfo -> [String]
+extFromBI binfo = map toString . nub $ allExts
+    where toString (Dist.UnknownExtension ext) = ext
           toString (Dist.EnableExtension  ext) = show ext
           toString (Dist.DisableExtension ext) = show ext
-
-#if __GLASGOW_HASKELL__ < 710
-specToPair :: (String, GHC.ExtensionFlag, a) -> (String, GHC.ExtensionFlag)
-specToPair (a, b, _) = (a, b)
-#else
-specToPair :: GHC.FlagSpec GHC.ExtensionFlag -> (String, GHC.ExtensionFlag)
-specToPair = GHC.flagSpecName &&& GHC.flagSpecFlag
-#endif
+          allExts = concatMap ($ binfo)
+              [Dist.defaultExtensions, Dist.otherExtensions, Dist.oldExtensions]
diff --git a/src/Argon/Parser.hs b/src/Argon/Parser.hs
--- a/src/Argon/Parser.hs
+++ b/src/Argon/Parser.hs
@@ -2,7 +2,6 @@
 module Argon.Parser (LModule, analyze, parseModule)
     where
 
-import Data.List (foldl')
 import Control.Monad (void)
 import qualified Control.Exception as E
 
@@ -11,6 +10,7 @@
 import qualified Lexer        as GHC
 import qualified Parser       as GHC
 import qualified DynFlags     as GHC
+import qualified GHC.LanguageExtensions as GHC
 import qualified HeaderInfo   as GHC
 import qualified MonadUtils   as GHC
 import qualified Outputable   as GHC
@@ -61,7 +61,7 @@
 parseModuleWithCpp conf cppOptions file =
     GHC.runGhc (Just libdir) $ do
       dflags <- initDynFlags conf file
-      let useCpp = GHC.xopt GHC.Opt_Cpp dflags
+      let useCpp = GHC.xopt GHC.Cpp dflags
       (fileContents, dflags1) <-
         if useCpp
            then getPreprocessedSrcDirect cppOptions file
@@ -86,15 +86,16 @@
 initDynFlags :: GHC.GhcMonad m => Config -> FilePath -> m GHC.DynFlags
 initDynFlags conf file = do
     dflags0 <- GHC.getSessionDynFlags
-    src_opts <- GHC.liftIO $ GHC.getOptionsFromFile dflags0 file
-    (dflags1, _, _) <- GHC.parseDynamicFilePragma dflags0 src_opts
-    let cabalized = foldl' GHC.xopt_set dflags1 $ exts conf
-    let dflags2 = cabalized { GHC.log_action = customLogAction }
-    void $ GHC.setSessionDynFlags dflags2
-    return dflags2
+    (dflags1,_,_) <- GHC.parseDynamicFlagsCmdLine dflags0
+        [GHC.L GHC.noSrcSpan ("-X" ++ e) | e <- exts conf]
+    src_opts <- GHC.liftIO $ GHC.getOptionsFromFile dflags1 file
+    (dflags2, _, _) <- GHC.parseDynamicFilePragma dflags1 src_opts
+    let dflags3 = dflags2 { GHC.log_action = customLogAction }
+    void $ GHC.setSessionDynFlags dflags3
+    return dflags3
 
 customLogAction :: GHC.LogAction
-customLogAction dflags severity srcSpan _ m =
+customLogAction dflags _ severity srcSpan _ m =
     case severity of
       GHC.SevFatal -> throwError
       GHC.SevError -> throwError
diff --git a/src/Argon/Types.hs b/src/Argon/Types.hs
--- a/src/Argon/Types.hs
+++ b/src/Argon/Types.hs
@@ -15,7 +15,6 @@
 import Data.Typeable
 import Control.Exception (Exception)
 
-import qualified DynFlags as GHC
 import Argon.Loc
 
 
@@ -38,8 +37,8 @@
 data Config = Config {
     -- | Minimum complexity a block has to have to be shown in results.
     minCC       :: Int
-    -- | Path to the main Cabal file
-  , exts        :: [GHC.ExtensionFlag]
+    -- | Extension to activate
+  , exts        :: [String]
     -- | Header files to be automatically included before preprocessing
   , headers     :: [FilePath]
     -- | Additional include directories for the C preprocessor
diff --git a/src/Argon/Visitor.hs b/src/Argon/Visitor.hs
--- a/src/Argon/Visitor.hs
+++ b/src/Argon/Visitor.hs
@@ -1,16 +1,17 @@
+{-# LANGUAGE CPP #-}
 module Argon.Visitor (funcsCC)
     where
 
-import Data.Generics (Data, Typeable, mkQ)
-import Argon.SYB.Utils (Stage(..), everythingStaged)
-import Control.Arrow ((&&&))
+import           Argon.SYB.Utils (Stage (..), everythingStaged)
+import           Control.Arrow   ((&&&))
+import           Data.Generics   (Data, mkQ)
 
 import qualified GHC
-import qualified RdrName as GHC
-import qualified OccName as GHC
+import qualified OccName         as GHC
+import qualified RdrName         as GHC
 
-import Argon.Loc
-import Argon.Types (ComplexityBlock(..))
+import           Argon.Loc
+import           Argon.Types     (ComplexityBlock (..))
 
 type Exp = GHC.HsExpr GHC.RdrName
 type Function = GHC.HsBindLR GHC.RdrName GHC.RdrName
@@ -18,16 +19,16 @@
 
 
 -- | Compute cyclomatic complexity of every function binding in the given AST.
-funcsCC :: (Data from, Typeable from) => from -> [ComplexityBlock]
+funcsCC :: (Data from) => from -> [ComplexityBlock]
 funcsCC = map funCC . getBinds
 
 funCC :: Function -> ComplexityBlock
 funCC f = CC (getLocation $ GHC.fun_id f, getFuncName f, complexity f)
 
-getBinds :: (Data from, Typeable from) => from -> [Function]
+getBinds :: (Data from) => from -> [Function]
 getBinds = everythingStaged Parser (++) [] $ mkQ [] visit
     where visit fun@GHC.FunBind {} = [fun]
-          visit _ = []
+          visit _                  = []
 
 getLocation :: GHC.Located a -> Loc
 getLocation = srcSpanToLoc . GHC.getLoc
@@ -39,11 +40,17 @@
 complexity f = let matches = getMatches f
                    query = everythingStaged Parser (+) 0 $ 0 `mkQ` visit
                    visit = uncurry (+) . (visitExp &&& visitOp)
-                in length matches + sumWith query matches
+                in length matches + sumWith getGRHSsFromMatch matches + sumWith query matches
 
 getMatches :: Function -> [GHC.LMatch GHC.RdrName MatchBody]
-getMatches = GHC.mg_alts . GHC.fun_matches
+getMatches = GHC.unLoc . GHC.mg_alts . GHC.fun_matches
 
+getGRHSsFromMatch :: GHC.LMatch GHC.RdrName MatchBody -> Int
+getGRHSsFromMatch match = length (getGRHSs' match) - 1
+  where
+    getGRHSs' :: GHC.LMatch GHC.RdrName MatchBody -> [GHC.LGRHS GHC.RdrName MatchBody]
+    getGRHSs' = GHC.grhssGRHSs . GHC.m_grhss . GHC.unLoc
+
 getName :: GHC.RdrName -> String
 getName = GHC.occNameString . GHC.rdrNameOcc
 
@@ -51,15 +58,20 @@
 sumWith f = sum . map f
 
 visitExp :: Exp -> Int
-visitExp GHC.HsIf {} = 1
+visitExp GHC.HsIf {}            = 1
 visitExp (GHC.HsMultiIf _ alts) = length alts - 1
-visitExp (GHC.HsLamCase _ alts) = length (GHC.mg_alts alts) - 1
-visitExp (GHC.HsCase _ alts)    = length (GHC.mg_alts alts) - 1
-visitExp _ = 0
+#if __GLASGOW_HASKELL__ < 802
+visitExp (GHC.HsCase _ alts)    = length (GHC.unLoc . GHC.mg_alts $ alts) - 1
+visitExp (GHC.HsLamCase _ alts) = length (GHC.unLoc . GHC.mg_alts $ alts) - 1
+#else
+visitExp (GHC.HsLamCase mg)     = length (GHC.unLoc . GHC.mg_alts $ mg) - 1
+visitExp (GHC.HsCase _ mg)      = length (GHC.unLoc . GHC.mg_alts $ mg) - 1
+#endif
+visitExp _                      = 0
 
 visitOp :: Exp -> Int
 visitOp (GHC.OpApp _ (GHC.L _ (GHC.HsVar op)) _ _) =
-    case getName op of
+    case getName (GHC.unLoc op) of
       "||" -> 1
       "&&" -> 1
       _    -> 0
diff --git a/src/Argon/Walker.hs b/src/Argon/Walker.hs
--- a/src/Argon/Walker.hs
+++ b/src/Argon/Walker.hs
@@ -1,14 +1,17 @@
+{-# LANGUAGE OverloadedStrings #-}
 module Argon.Walker (allFiles)
     where
 
-import Pipes
-import Pipes.Files
-import Pipes.Safe
-import qualified Pipes.Prelude as P
-import Data.Monoid ((<>))
-import Data.List (isSuffixOf)
-import System.Directory (doesFileExist)
-
+import           Data.DirStream            (childOf)
+import           Data.List                 (isSuffixOf)
+import           Filesystem.Path.CurrentOS (decodeString, encodeString)
+import           Pipes                     (ListT, MonadIO, Producer, each,
+                                            every, liftIO, (>->))
+import qualified Pipes.Prelude             as P
+import           Pipes.Safe
+import           System.Directory          (doesDirectoryExist, doesFileExist,
+                                            pathIsSymbolicLink)
+import           System.FilePath           (takeExtension)
 
 -- | Starting from a path, generate a sequence of paths corresponding
 --   to Haskell files. The filesystem is traversed depth-first.
@@ -16,4 +19,16 @@
 allFiles path = do
     isFile <- liftIO $ doesFileExist path
     if isFile then each [path] >-> P.filter (".hs" `isSuffixOf`)
-              else find path (glob "*.hs" <> regular)
+              else every $ hsFilesIn path
+
+-- | List the regular files in a directory.
+hsFilesIn :: MonadSafe m => FilePath -> ListT m FilePath
+hsFilesIn path = do
+  child <- encodeString <$> childOf (decodeString path)
+  isDir <- liftIO $ doesDirectoryExist child
+  isSymLink <- liftIO $ pathIsSymbolicLink child
+  if isDir && not isSymLink
+    then hsFilesIn child
+    else if not isSymLink && takeExtension child == ".hs"
+         then return child
+         else mempty
diff --git a/stack-7.8.yaml b/stack-7.8.yaml
deleted file mode 100644
--- a/stack-7.8.yaml
+++ /dev/null
@@ -1,15 +0,0 @@
-flags: {}
-extra-package-dbs: []
-packages:
-- '.'
-extra-deps:
-- docopt-0.7.0.4
-- syb-0.4.4
-- ghc-7.8.4
-- lens-simple-0.1.0.8
-- lens-family-1.2.0
-- pipes-files-0.1.1
-- hierarchy-0.3.1
-- posix-paths-0.2.1.0
-- free-4.12.1
-resolver: lts-2.22
diff --git a/stack.yaml b/stack.yaml
--- a/stack.yaml
+++ b/stack.yaml
@@ -1,13 +1,4 @@
-flags: {}
-extra-package-dbs: []
-packages:
-- '.'
-extra-deps:
-- docopt-0.7.0.4
-- hierarchy-0.3.1
-- pipes-files-0.1.1
-- posix-paths-0.2.1.0
-- aeson-0.11.0.0
-- fail-4.9.0.0
-- semigroups-0.16.2.2
-resolver: lts-5.2
+resolver: lts-11.6
+
+extra-deps: [dirstream-1.0.3]
+
diff --git a/test/ArgonSpec.hs b/test/ArgonSpec.hs
--- a/test/ArgonSpec.hs
+++ b/test/ArgonSpec.hs
@@ -1,28 +1,33 @@
 {-# OPTIONS_GHC -fno-warn-orphans #-}
-{-# LANGUAGE CPP #-}
+{-# LANGUAGE CPP               #-}
 {-# LANGUAGE OverloadedStrings #-}
 
 module ArgonSpec (spec)
     where
 
-import Data.List (sort, isPrefixOf)
-import Data.Aeson (encode)
-import Text.Printf (printf)
+import           Data.Aeson          (encode)
+import           Data.List           (sort)
+import           GHC.Stack           (HasCallStack)
+import           Text.Printf         (printf)
 #if __GLASGOW_HASKELL__ < 710
-import Control.Applicative ((<$>), (<*>))
+import           Control.Applicative ((<$>), (<*>))
 #endif
-import Test.Hspec
-import Test.QuickCheck
-import System.FilePath ((</>))
-import System.IO.Unsafe (unsafePerformIO)
-import System.Console.ANSI
-import qualified SrcLoc     as GHC
-import qualified FastString as GHC
-import Pipes
---import Pipes.Safe (SafeT, runSafeT)
-import qualified Pipes.Prelude as P
+import qualified FastString          as GHC
+import           Pipes               (Producer, (>->), each)
+import qualified SrcLoc              as GHC
+import           System.Console.ANSI (Color (..), ConsoleIntensity(BoldIntensity), setSGRCode,
+                                      SGR(SetColor, SetConsoleIntensity),
+                                      ConsoleLayer(Foreground), ColorIntensity(Dull))
+import           System.FilePath     ((</>))
+import           System.IO.Unsafe    (unsafePerformIO)
+import           Test.Hspec          (describe, it, Expectation, shouldBe,
+                                      shouldContain, Spec, expectationFailure,
+                                      shouldReturn)
+import           Test.QuickCheck     (Arbitrary, arbitrary, shrink, property, elements)
+import qualified Pipes.Prelude       as P
+import           Data.Foldable       (traverse_)
 
-import Argon
+import           Argon
 
 instance Arbitrary ComplexityBlock where
     arbitrary = (\a b c -> CC (a, b, c)) <$> arbitrary
@@ -31,7 +36,7 @@
     shrink (CC t) = map CC $ shrink t
 
 instance Arbitrary OutputMode where
-
+    arbitrary = elements [BareText, Colored, JSON]
 
 ones :: Loc
 ones = (1, 1)
@@ -43,17 +48,20 @@
 realSpan a b = GHC.mkSrcSpan (mkLoc a b) $ mkLoc (-a) (b + 24)
     where mkLoc = GHC.mkSrcLoc (GHC.mkFastString "real loc")
 
-errStartsWith :: String -> (FilePath, AnalysisResult) -> Bool
-errStartsWith _ (_, Right _)  = False
-errStartsWith p (_, Left msg) = p `isPrefixOf` msg
+shouldContainErrors :: HasCallStack => FilePath -> [String] -> Expectation
+shouldContainErrors f errs = do
+    r <- analyze defaultConfig (path f)
+    case r of
+        (_, Right _)  -> expectationFailure $ "Test did not fail" ++ show r
+        (_, Left msg) -> traverse_ (msg `shouldContain`) errs
 
 path :: String -> FilePath
 path f = "test" </> "data" </> f
 
-shouldAnalyze :: String -> AnalysisResult -> Expectation
+shouldAnalyze :: HasCallStack => String -> AnalysisResult -> Expectation
 shouldAnalyze f = shouldAnalyzeC (f, defaultConfig)
 
-shouldAnalyzeC :: (String, Config) -> AnalysisResult -> Expectation
+shouldAnalyzeC :: HasCallStack => (String, Config) -> AnalysisResult -> Expectation
 shouldAnalyzeC (f, config) r = analyze config p `shouldReturn` (p, r)
     where p = path f
 
@@ -138,26 +146,27 @@
                 "arrows.hs" `shouldAnalyze` Right [CC (lo 7, "getAnchor", 1)]
         describe "errors" $ do
             it "catches syntax errors" $
-                "syntaxerror.hs" `shouldAnalyze`
-                    Left ("2:1 parse error (possibly incorrect indentation" ++
-                          " or mismatched brackets)")
+                "syntaxerror.hs" `shouldContainErrors`
+                ["parse error (possibly incorrect indentation or mismatched brackets)"]
             it "catches syntax errors (missing CPP)" $
                 "missingcpp.hs" `shouldAnalyze`
+#if __GLASGOW_HASKELL__ < 800
                     Left "1:2 lexical error at character 'i'"
+#else
+                    Left "1:1 parse error on input \8216#\8217"
+#endif
+#if __GLASGOW_HASKELL__ < 800
+-- The analysis of "missingmacros.hs" will succeed in newest GHC versions.
             it "catches syntax errors (missing cabal macros)" $
-                unsafePerformIO (analyze defaultConfig (path "missingmacros.hs"))
-                    `shouldSatisfy`
-                    errStartsWith ("2:0  error: missing binary operator " ++
-                                   "before token ")
+                "missingmacros.hs" `shouldContainErrors`
+                ["error: missing binary operator before token "]
+#endif
             it "catches syntax errors (missing include dir)" $
-                unsafePerformIO (analyze defaultConfig (path "missingincluded.hs"))
-                    `shouldSatisfy`
-                    errStartsWith ("2:0  fatal error: necessaryInclude.h: "
-                                  ++ "No such file or directory")
+                "missingincluded.hs" `shouldContainErrors`
+                ["fatal error", "necessaryInclude.h"]
             it "catches CPP parsing errors" $
-                unsafePerformIO (analyze defaultConfig (path "cpp-error.hs"))
-                    `shouldSatisfy`
-                    errStartsWith "2:0  error: unterminated #else"
+                 "cpp-error.hs" `shouldContainErrors`
+                 ["error: unterminated"]
         describe "config" $ do
             it "reads default extensions from Cabal file" $
                 ("missingcpp.hs", unsafePerformIO
@@ -165,10 +174,24 @@
                         return $ defaultConfig { exts = loadedExts }))
                     `shouldAnalyzeC`
                     Right [CC (lo 4, "f", 1)]
+            it "reads other extensions from Cabal file" $
+                ("missingcpp.hs", unsafePerformIO
+                    (do loadedExts <- parseExts $ path "test-other.cabal"
+                        return $ defaultConfig { exts = loadedExts }))
+                    `shouldAnalyzeC`
+                    Right [CC (lo 4, "f", 1)]
+            it "reads old extensions from Cabal file" $
+                ("missingcpp.hs", unsafePerformIO
+                    (do loadedExts <- parseExts $ path "test-old.cabal"
+                        return $ defaultConfig { exts = loadedExts }))
+                    `shouldAnalyzeC`
+                    Right [CC (lo 4, "f", 1)]
+#if __GLASGOW_HASKELL__ < 800
             it "includes Cabal macros for preprocessing" $
                 ( "missingmacros.hs"
                 , defaultConfig { headers = [path "cabal_macros.h"] }
                 ) `shouldAnalyzeC` Right [CC (lo 3, "f", 2)]
+#endif
             it "includes directory from include-dir for preprocessing" $
                 ( "missingincluded.hs"
                 , defaultConfig { includeDirs = [path "include"] }
diff --git a/test/data/test-old.cabal b/test/data/test-old.cabal
new file mode 100644
--- /dev/null
+++ b/test/data/test-old.cabal
@@ -0,0 +1,18 @@
+name:                ftw
+version:             0.0
+author:              Michele Lacchia
+build-type:          Simple
+cabal-version:       >=1.18
+
+library
+  hs-source-dirs:      .
+  extensions:          CPP
+  build-depends:       base             >=4.7    && <5
+  default-language:    Haskell2010
+  ghc-options:         -Wall
+  if impl(ghc < 7.8)
+    buildable: False
+
+source-repository head
+  type:     git
+  location: https://github.com/rubik/argon
diff --git a/test/data/test-other.cabal b/test/data/test-other.cabal
new file mode 100644
--- /dev/null
+++ b/test/data/test-other.cabal
@@ -0,0 +1,18 @@
+name:                ftw
+version:             0.0
+author:              Michele Lacchia
+build-type:          Simple
+cabal-version:       >=1.18
+
+library
+  hs-source-dirs:      .
+  other-extensions:    CPP
+  build-depends:       base             >=4.7    && <5
+  default-language:    Haskell2010
+  ghc-options:         -Wall
+  if impl(ghc < 7.8)
+    buildable: False
+
+source-repository head
+  type:     git
+  location: https://github.com/rubik/argon
