summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorErik de Castro Lopo <erikd@mega-nerd.com>2016-10-22 19:01:49 +1100
committerErik de Castro Lopo <erikd@mega-nerd.com>2016-10-22 20:18:13 +1100
commit767ee632167271475eb40b1c8bc53ac54c7031e4 (patch)
tree8c7bf06e8cdef8799d3d96d0d5fa56897d3f4334
parentf41a8a369796985a75dd618b969292e1e7033112 (diff)
downloadhaskell-wip/erikd/cpp-undef.tar.gz
Add -Wcpp-undef warning flagwip/erikd/cpp-undef
Summary: When enabled, this new warning flag passes `-Wundef` to the C pre-processor which causes the pre-processor to warn on uses of the `#if` directive on undefined identifiers. It is not currently enabled in any of the standard warning groups. Test Plan: Add a test to this commit and make sure the test passes on all major platforms. Reviewers: bgamari, hvr, austin, Phyx, carter Subscribers: thomie Differential Revision: https://phabricator.haskell.org/D2626 GHC Trac Issues: #12752
-rw-r--r--compiler/main/DynFlags.hs2
-rw-r--r--compiler/main/SysTools.hs5
-rw-r--r--docs/users_guide/using-warnings.rst6
-rw-r--r--testsuite/tests/driver/T12752pass.hs9
-rw-r--r--testsuite/tests/driver/all.T4
-rw-r--r--testsuite/tests/driver/should_fail/T12752.hs10
-rw-r--r--testsuite/tests/driver/should_fail/all.T2
7 files changed, 34 insertions, 4 deletions
diff --git a/compiler/main/DynFlags.hs b/compiler/main/DynFlags.hs
index 7978c03352..cd8dc41ceb 100644
--- a/compiler/main/DynFlags.hs
+++ b/compiler/main/DynFlags.hs
@@ -619,6 +619,7 @@ data WarningFlag =
| Opt_WarnMissingPatternSynonymSignatures -- since 8.0
| Opt_WarnUnrecognisedWarningFlags -- since 8.0
| Opt_WarnSimplifiableClassConstraints -- Since 8.2
+ | Opt_WarnCPPUndef -- Since 8.2
deriving (Eq, Show, Enum)
data Language = Haskell98 | Haskell2010
@@ -3287,6 +3288,7 @@ wWarningFlagsDeps = [
"it has no effect",
depFlagSpec "auto-orphans" Opt_WarnAutoOrphans
"it has no effect",
+ flagSpec "cpp-undef" Opt_WarnCPPUndef,
flagSpec "deferred-type-errors" Opt_WarnDeferredTypeErrors,
flagSpec "deferred-out-of-scope-variables"
Opt_WarnDeferredOutOfScopeVariables,
diff --git a/compiler/main/SysTools.hs b/compiler/main/SysTools.hs
index dd98883cb5..d5fd0c5c29 100644
--- a/compiler/main/SysTools.hs
+++ b/compiler/main/SysTools.hs
@@ -403,9 +403,8 @@ runCpp :: DynFlags -> [Option] -> IO ()
runCpp dflags args = do
let (p,args0) = pgm_P dflags
args1 = map Option (getOpts dflags opt_P)
- args2 = if gopt Opt_WarnIsError dflags
- then [Option "-Werror"]
- else []
+ args2 = [Option "-Werror" | gopt Opt_WarnIsError dflags]
+ ++ [Option "-Wundef" | wopt Opt_WarnCPPUndef dflags]
mb_env <- getGccEnv args2
runSomethingFiltered dflags id "C pre-processor" p
(args0 ++ args1 ++ args2 ++ args) mb_env
diff --git a/docs/users_guide/using-warnings.rst b/docs/users_guide/using-warnings.rst
index c07058a4ef..c9216b9307 100644
--- a/docs/users_guide/using-warnings.rst
+++ b/docs/users_guide/using-warnings.rst
@@ -1007,6 +1007,12 @@ of ``-W(no-)*``.
be inlined before the rule has a chance to fire. See
:ref:`rules-inline`.
+.. ghc-flag:: -Wcpp-undef
+
+ This flag passes ``-Wundef`` to the C pre-processor (if its being used)
+ which causes the pre-processor to warn on uses of the `#if` directive on
+ undefined identifiers.
+
If you're feeling really paranoid, the :ghc-flag:`-dcore-lint` option is a good choice.
It turns on heavyweight intra-pass sanity-checking within GHC. (It checks GHC's
sanity, not yours.)
diff --git a/testsuite/tests/driver/T12752pass.hs b/testsuite/tests/driver/T12752pass.hs
new file mode 100644
index 0000000000..5826d48b88
--- /dev/null
+++ b/testsuite/tests/driver/T12752pass.hs
@@ -0,0 +1,9 @@
+{-# LANGUAGE CPP #-}
+
+#if SHOULD_PASS
+message :: String
+message = "Hello!"
+#endif
+
+main :: IO ()
+main = putStrLn message
diff --git a/testsuite/tests/driver/all.T b/testsuite/tests/driver/all.T
index c6283df156..8cd5c2f968 100644
--- a/testsuite/tests/driver/all.T
+++ b/testsuite/tests/driver/all.T
@@ -491,9 +491,11 @@ test('T12135',
run_command,
['$MAKE -s --no-print-directory T12135'])
-test('T12192', normal, run_command, ['mkdir foo && (cd foo && {compiler} -v0 ../T12192)'])
+test('T12192', normal, run_command, ['mkdir foo && (cd foo && {compiler} -v0 ../T12192)'])
test('T10923',
extra_clean(['T10923.o', 'T10923.hi']),
run_command,
['$MAKE -s --no-print-directory T10923'])
+
+test('T12752pass', normal, compile, ['-DSHOULD_PASS=1 -Wcpp-undef'])
diff --git a/testsuite/tests/driver/should_fail/T12752.hs b/testsuite/tests/driver/should_fail/T12752.hs
new file mode 100644
index 0000000000..3560d00894
--- /dev/null
+++ b/testsuite/tests/driver/should_fail/T12752.hs
@@ -0,0 +1,10 @@
+{-# LANGUAGE CPP #-}
+
+-- This should fail to compile with "ghc -Wcpp-undef -Werror ...".
+#if this_cpp_identifier_does_not_exist
+message :: String
+message = "This is wrong!"
+#endif
+
+main :: IO ()
+main = putStrLn "Hello"
diff --git a/testsuite/tests/driver/should_fail/all.T b/testsuite/tests/driver/should_fail/all.T
index f068d6516d..3d0708b285 100644
--- a/testsuite/tests/driver/should_fail/all.T
+++ b/testsuite/tests/driver/should_fail/all.T
@@ -1,2 +1,4 @@
# --make -o without Main should be an error, not a warning.
test('T10895', normal, multimod_compile_fail, ['T10895.hs', '-v0 -o dummy'])
+
+test('T12752', expect_fail, compile, ['-Wcpp-undef -Werror'])