diff options
author | Thomas Miedema <thomasmiedema@gmail.com> | 2015-03-16 18:36:59 +0100 |
---|---|---|
committer | Thomas Miedema <thomasmiedema@gmail.com> | 2015-03-16 18:38:58 +0100 |
commit | 5166ee94e439375a4e6acb80f88ec6ee65476bbd (patch) | |
tree | f79b90d82c995faea5e03c66ae2f19920b90f52f /compiler/main | |
parent | beee618c4ab8f725acd4dce3ef8a0d4ce84bb6ec (diff) | |
download | haskell-5166ee94e439375a4e6acb80f88ec6ee65476bbd.tar.gz |
Dont call unsafeGlobalDynFlags if it is not set
Parsing of static and mode flags happens before any session is started,
i.e., before the first call to 'GHC.withGhc'. Therefore, to report
errors for invalid usage of these two types of flags, we can not call
any function that needs DynFlags, as there are no DynFlags available yet
(unsafeGlobalDynFlags is not set either). So we always print "on the
commandline" as the location, which is true except for Api users, which
is probably ok.
When reporting errors for invalid usage of dynamic flags we /can/ make
use of DynFlags, and we do so explicitly in
DynFlags.parseDynamicFlagsFull.
Before, we called unsafeGlobalDynFlags when an invalid (combination of)
flag(s) was given on the commandline, resulting in panics (#9963). This
regression was introduced in 1d6124de.
Also rename showSDocSimple to showSDocUnsafe, to hopefully prevent this
from happening again.
Reviewed By: austin
Differential Revision: https://phabricator.haskell.org/D730
GHC Trac Issues: #9963
Diffstat (limited to 'compiler/main')
-rw-r--r-- | compiler/main/CmdLineParser.hs | 24 | ||||
-rw-r--r-- | compiler/main/DynFlags.hs | 10 | ||||
-rw-r--r-- | compiler/main/StaticFlags.hs | 7 |
3 files changed, 33 insertions, 8 deletions
diff --git a/compiler/main/CmdLineParser.hs b/compiler/main/CmdLineParser.hs index 422fa13eb5..dad7ea7ae2 100644 --- a/compiler/main/CmdLineParser.hs +++ b/compiler/main/CmdLineParser.hs @@ -295,8 +295,26 @@ missingArgErr f = Left ("missing argument for flag: " ++ f) -- Utils -------------------------------------------------------- -errorsToGhcException :: [Located String] -> GhcException + +-- See Note [Handling errors when parsing flags] +errorsToGhcException :: [(String, -- Location + String)] -- Error + -> GhcException errorsToGhcException errs = - UsageError $ - intercalate "\n" [ showUserSpan True l ++ ": " ++ e | L l e <- errs ] + UsageError $ intercalate "\n" $ [ l ++ ": " ++ e | (l, e) <- errs ] + +{- Note [Handling errors when parsing commandline flags] + +Parsing of static and mode flags happens before any session is started, i.e., +before the first call to 'GHC.withGhc'. Therefore, to report errors for +invalid usage of these two types of flags, we can not call any function that +needs DynFlags, as there are no DynFlags available yet (unsafeGlobalDynFlags +is not set either). So we always print "on the commandline" as the location, +which is true except for Api users, which is probably ok. + +When reporting errors for invalid usage of dynamic flags we /can/ make use of +DynFlags, and we do so explicitly in DynFlags.parseDynamicFlagsFull. +Before, we called unsafeGlobalDynFlags when an invalid (combination of) +flag(s) was given on the commandline, resulting in panics (#9963). +-} diff --git a/compiler/main/DynFlags.hs b/compiler/main/DynFlags.hs index aa6b7f9308..2c1a82c787 100644 --- a/compiler/main/DynFlags.hs +++ b/compiler/main/DynFlags.hs @@ -178,6 +178,7 @@ import {-# SOURCE #-} ErrUtils ( Severity(..), MsgDoc, mkLocMessage ) import System.IO.Unsafe ( unsafePerformIO ) import Data.IORef +import Control.Arrow ((&&&)) import Control.Monad import Control.Exception (throwIO) @@ -2108,8 +2109,10 @@ parseDynamicFlagsFull :: MonadIO m parseDynamicFlagsFull activeFlags cmdline dflags0 args = do let ((leftover, errs, warns), dflags1) = runCmdLine (processArgs activeFlags args) dflags0 - when (not (null errs)) $ liftIO $ - throwGhcExceptionIO $ errorsToGhcException errs + + -- See Note [Handling errors when parsing commandline flags] + unless (null errs) $ liftIO $ throwGhcExceptionIO $ + errorsToGhcException . map (showPpr dflags0 . getLoc &&& unLoc) $ errs -- check for disabled flags in safe haskell let (dflags2, sh_warns) = safeFlagCheck cmdline dflags1 @@ -4200,7 +4203,8 @@ makeDynFlagsConsistent dflags -- to show SDocs when tracing, but we don't always have DynFlags -- available. -- --- Do not use it if you can help it. You may get the wrong value! +-- Do not use it if you can help it. You may get the wrong value, or this +-- panic! GLOBAL_VAR(v_unsafeGlobalDynFlags, panic "v_unsafeGlobalDynFlags: not initialised", DynFlags) diff --git a/compiler/main/StaticFlags.hs b/compiler/main/StaticFlags.hs index 4b4403a3ea..914a1459df 100644 --- a/compiler/main/StaticFlags.hs +++ b/compiler/main/StaticFlags.hs @@ -1,4 +1,4 @@ -{-# LANGUAGE CPP #-} +{-# LANGUAGE CPP, TupleSections #-} {-# OPTIONS_GHC -fno-cse #-} -- -fno-cse is needed for GLOBAL_VAR's to behave properly @@ -82,7 +82,10 @@ parseStaticFlagsFull flagsAvailable args = do when ready $ throwGhcExceptionIO (ProgramError "Too late for parseStaticFlags: call it before runGhc or runGhcT") (leftover, errs, warns) <- processArgs flagsAvailable args - when (not (null errs)) $ throwGhcExceptionIO $ errorsToGhcException errs + + -- See Note [Handling errors when parsing commandline flags] + unless (null errs) $ throwGhcExceptionIO $ + errorsToGhcException . map (("on the commandline", ) . unLoc) $ errs -- see sanity code in staticOpts writeIORef v_opt_C_ready True |