#1171: GHC generates incorrect code with -O for Haskell 98 program
----------------------+-----------------------------------------------------
 Reporter:  neil      |          Owner:          
     Type:  bug       |         Status:  closed  
 Priority:  normal    |      Milestone:  6.6.1   
Component:  Compiler  |        Version:  6.6     
 Severity:  major     |     Resolution:  invalid 
 Keywords:            |     Difficulty:  Unknown 
 Testcase:  cg059     |   Architecture:  Multiple
       Os:  Multiple  |  
----------------------+-----------------------------------------------------
Changes (by simonmar):

  * resolution:  => invalid
  * status:  new => closed

Comment:

 Not a bug!!!!

 Let's look at the code:

 {{{
            case (local,res) of
                 ([x], _) -> return ()
                 (_, [x]) -> return ()
                 ([], []) -> raiseError $ ErrorFileNone
                 (as, bs) -> if as++bs == [] then error "Empty as++bs" else
 raiseError $ ErrorFileMany file
 }}}

 The last two branches are both `_|_`.  If the value of an expression is
 definitely `_|_`, then any `_|_` will do: in this case you get the "Empty
 as++bs" error instead of the one you were expecting.  To fix the program
 you need to use `ioError` instead of `error`.

 The way this works is like this: after the first two alternatives have
 been eliminated, we're left with

 {{{
            case (local,res) of
                 ([], []) -> raiseError $ ErrorFileNone
                 (as, bs) -> if as++bs == [] then error "Empty as++bs" else
 raiseError $ ErrorFileMany file
 }}}

 which is semantically equivalent to `_|_`, and GHC can detect that.
 However, we don't gratuitously replace it with undefined, of course; in
 fact GHC compiles this expression:

 {{{
        let z = if as++bs == [] then error "Empty as++bs"
                                else raiseError $ ErrorFileMany file
        in z `seq`
            case (local,res) of
                 ([], []) -> raiseError $ ErrorFileNone
                 (as, bs) -> z
 }}}

 It's safe to evaluate `z` eagerly, because the whole expression is known
 to be `_|_`.  So there you go.

 I don't know whether it's possible to modify the simplifier to get a more
 expected result here; I suspect not without sacrificing some performance.

-- 
Ticket URL: <http://hackage.haskell.org/trac/ghc/ticket/1171>
GHC <http://www.haskell.org/ghc/>
The Glasgow Haskell Compiler
_______________________________________________
Glasgow-haskell-bugs mailing list
[email protected]
http://www.haskell.org/mailman/listinfo/glasgow-haskell-bugs

Reply via email to