Opened 4 years ago

Closed 4 years ago

#5573 closed bug (fixed)

Returning nested unboxed tuples crashes the code generator on x86_64 Linux

Reported by: manzyuk Owned by:
Priority: normal Milestone:
Component: Compiler Version: 7.0.3
Keywords: Cc: axch@…
Operating System: Linux Architecture: x86_64 (amd64)
Type of failure: Compile-time crash Test Case: typecheck/should_fail/T5573a, T5573b
Blocked By: Blocking:
Related Tickets: Differential Revisions:

Description

Compiling the following program with GHC 7.0.3 running on a 64 bit Linux machine crashes with a GHC panic:

$ uname -a
Linux pandora 2.6.32-5-amd64 #1 SMP Fri Sep 9 20:23:16 UTC 2011 x86_64 GNU/Linux
$ ghc --version
The Glorious Glasgow Haskell Compilation System, version 7.0.3
$ cat unboxed.hs
{-# LANGUAGE MagicHash, UnboxedTuples, BangPatterns #-}

import GHC.Exts

foo :: Double# -> (# (# Double#, Double# #), Double# #)
foo x = (# (# x, x #), x #)
{-# NOINLINE foo #-}

main :: IO ()
main = print $ let !(# !(# y, z #), w #) = foo 10.0##
               in D# (y +## z +## w)
$ ghc unboxed.hs
[1 of 1] Compiling Main             ( unboxed.hs, unboxed.o )
ghc: panic! (the 'impossible' happened)
  (GHC version 7.0.3 for x86_64-unknown-linux):
	cgPanic
    sat_siH{v} [lid]
    static binds for:
    local binds for:
    x{v siq} [lid]
    SRT label foo{v rcY}_srt

Please report this as a GHC bug:  http://www.haskell.org/ghc/reportabug

The expected behavior is compiling correctly and outputting 30.0. In fact, this is what happens if we remove the NOINLINE pragma or flatten the tuple.

Compiling this program with -dcore-lint produces:

$ ghc unboxed.hs -dcore-lint
[1 of 1] Compiling Main             ( unboxed.hs, unboxed.o )
*** Core Lint errors : in result of Desugar ***
<no location info>:
    In a case alternative: ((#,#) ds_dil :: (# GHC.Prim.Double#,
                                               GHC.Prim.Double# #),
                                  w_ad4 :: GHC.Prim.Double#)
    A variable has unboxed tuple type: ds_dil
    Binder's type: (# GHC.Prim.Double#, GHC.Prim.Double# #)
*** Offending Program ***
Main.foo [InlPrag=NOINLINE]
  :: GHC.Prim.Double#
     -> (# (# GHC.Prim.Double#, GHC.Prim.Double# #), GHC.Prim.Double# #)
[LclId]
Main.foo =
  \ (x_ad1 :: GHC.Prim.Double#) -> (# (# x_ad1, x_ad1 #), x_ad1 #)

Main.main :: GHC.Types.IO ()
[LclIdX]
Main.main =
  GHC.Base.$
    @ GHC.Types.Double
    @ (GHC.Types.IO ())
    (System.IO.print @ GHC.Types.Double GHC.Float.$fShowDouble)
    (case Main.foo 10.0 of _ { (# ds_dil, w_ad4 #) ->
     case ds_dil of _ { (# y_ad2, z_ad3 #) ->
     GHC.Types.D# (GHC.Prim.+## (GHC.Prim.+## y_ad2 z_ad3) w_ad4)
     }
     })

:Main.main :: GHC.Types.IO ()
[LclIdX]
:Main.main = GHC.TopHandler.runMainIO @ () Main.main

*** End of Offense ***


<no location info>: 
Compilation had errors

GHC 6.12.1 running on a 32 Linux machine rejects the program:

$ uname -a
Linux golconda 2.6.32-5-686 #1 SMP Mon Jun 13 04:13:06 UTC 2011 i686 GNU/Linux
$ ghc --version
The Glorious Glasgow Haskell Compilation System, version 6.12.1
$ ghc unboxed.hs 

unboxed.hs:6:11:
    Couldn't match kind `(#)' against `??'
    When matching the kinds of `(# Double#, Double# #) :: (#)' and
                               `t :: ??'
      Expected type: t
      Inferred type: (# Double#, Double# #)
    In the expression: (# x, x #)

This is also not the expected behavior, as the documentation says that unboxed tuples should be able to contain an object of any type. Also, this error message is less than maximally helpful.

By the way, the reason we are trying to nest unboxed tuples in the first place is because we are experimenting with using GHC as a compilation target, and our code generator wanted to emit a long unboxed tuple. We got a nice error message saying that the length limit on unboxed tuples was 62; would we please nest them? and on trying to nest them we tripped over this.

Change History (2)

comment:1 Changed 4 years ago by simonpj@…

commit b653231468f4f166133ca91bc7ca2f5717e5d726

Author: Simon Peyton Jones <[email protected]>
Date:   Sat Oct 22 12:03:11 2011 +0100

    Fix kind-checking for unboxed tuples (fixes Trac #5573)
    
    In particular we don't allow *nested* unboxed tuples, but the
    typechecker wasn't actually enforcing that, which confused the
    later stages of the compiler.
    
    I also updated the documentation on unboxed tuples.

 compiler/prelude/TysPrim.lhs      |    5 +++--
 compiler/prelude/TysWiredIn.lhs   |    6 +++---
 compiler/typecheck/TcHsType.lhs   |   36 ++++++++++++++++++++----------------
 docs/users_guide/glasgow_exts.xml |   10 ++++++++--
 4 files changed, 34 insertions(+), 23 deletions(-)

comment:2 Changed 4 years ago by simonpj

  • Resolution set to fixed
  • Status changed from new to closed
  • Test Case set to typecheck/should_fail/T5573a, T5573b

Thanks for reporting this; now fixed!

Simon

Note: See TracTickets for help on using tickets.