[GHC] #11475: Lint should check for inexhaustive alternatives
GHC
ghc-devs at haskell.org
Thu Jan 21 14:03:25 UTC 2016
#11475: Lint should check for inexhaustive alternatives
-------------------------------------+-------------------------------------
Reporter: simonpj | Owner:
Type: bug | Status: new
Priority: normal | Milestone:
Component: Compiler | Version: 7.10.3
Resolution: | Keywords:
Operating System: Unknown/Multiple | Architecture:
| Unknown/Multiple
Type of failure: None/Unknown | Test Case:
Blocked By: | Blocking:
Related Tickets: | Differential Rev(s):
Wiki Page: |
-------------------------------------+-------------------------------------
Description changed by simonpj:
@@ -20,2 +20,6 @@
- Right Thing. Trac #11172 turned out to be a bug in the pruning, which led
- to something like
+ Right Thing. Yet, lacking such a check, a program can pass Lint and then
+ seg-fault, which is Very Bad.
+
+
+ Trac #11172 is an example. It turned out to be a bug in the pruning,
+ which led to something like
New description:
GHC's simplifier prunes inaccessible alternatives from case expressions.
E.g.
{{{
case x of
A y -> e1
_ -> ....(case x of
A y -> r1
B -> r2
C -> r3) ...
}}}
It'll prune the `A` alternative from the inner case to get
{{{
case x of
A y -> e1
_ -> ....(case x of
B -> r2
C -> r3) ...
}}}
BUT, there is no independent check from Lint that this pruning does the
Right Thing. Yet, lacking such a check, a program can pass Lint and then
seg-fault, which is Very Bad.
Trac #11172 is an example. It turned out to be a bug in the pruning,
which led to something like
{{{
case x of
Left y -> e1
}}}
but in fact `x` ended up being bound to `(Right v)` for some value `v`.
But because there is only a single alternative left, GHC does not test the
tag, but instead goes ahead and accesses it the `Right` value as if it was
a `Left` value. And because of pointer-tagging, it'll assume the wrong tag
on the pointer, and very soon you are in seg-fault land.
So this ticket is to suggest: make Core Lint do it's best to check that
all cases are in fact exhaustive. There are two ways in which we prune
cases:
* Enclosing pattern matches (as above)
* GADT pattern matches may be exhaustive even when they don't mention all
constructors.
For the latter, it's impossible for Lint to reproduce all the reasoning of
the type checker, but I bet that in 99.5% of the cases the existing
function `dataConCantMatch` will do the job.
So if Lit
* Maintains an environment saying what each variable can't match (as the
simplifier does)
* Does a simple-minded `dataConCantMatch` test based on the typ of the
scrutinee
I think we'd be a long way forward. It's possible that a valid program
could trigger a Lint report, but let's see.
Any volunteers?
--
--
Ticket URL: <http://ghc.haskell.org/trac/ghc/ticket/11475#comment:1>
GHC <http://www.haskell.org/ghc/>
The Glasgow Haskell Compiler
More information about the ghc-tickets
mailing list