Opened 2 years ago

Closed 20 months ago

#8037 closed bug (fixed)

GHC panic when compiling unsafeCoerce

Reported by: ghc@… Owned by:
Priority: normal Milestone:
Component: Compiler Version: 7.6.1
Keywords: Cc:
Operating System: MacOS X Architecture: Unknown/Multiple
Type of failure: None/Unknown Test Case: stranal/should_compile/T8037
Blocked By: Blocking:
Related Tickets: Differential Revisions:

Description

The GHC compiler crashes on the following program.

module Test where

import Unsafe.Coerce
import Graphics.Rendering.OpenGL (color, Color3, GLdouble)

data D4 = D4 Double Double Double Double

crash :: D4 -> IO ()
crash c = color (invalidCast c)

invalidCast :: D4 -> Color3 GLdouble
invalidCast = unsafeCoerce

With the following output:

[1 of 1] Compiling Test             ( Test.hs, Test.o )
ghc: panic! (the 'impossible' happened)
  (GHC version 7.6.1 for x86_64-apple-darwin):
	cgLookupPanic (probably invalid Core; try -dcore-lint)
    ww_s28U{v} [lid]
    static binds for:
    local binds for:

I've made several attempts to make the input program smaller, but all modifications will result in successful compilation.

The cast is invalid but should produce an runtime error, not a compile time error.

Changes I made that somehow prevent this bug from appearing:

  • Changing the crash functions into point free style color . invalidCast.
  • Decreasing the amount of doubles in the D4 datatype.
  • Inlining the exact definitions from the OpenGL package.
  • Using the print function instead of the color function.

(btw, I know I shouldn't use unsafeCoerce)

Change History (11)

comment:1 Changed 2 years ago by simonpj

  • difficulty set to Unknown

Can you give a test case that doesn't depend on OpenGL? Eg make a stub module that has the relevant bits of OpenGL in it?

comment:2 Changed 2 years ago by ghc@…

I tried really hard to do this, but that didn't work out. Every change I made the program compile again.

comment:3 Changed 2 years ago by monoidal

I can't reproduce on Linux, GHC 7.6.3, OpenGL-2.6 or OpenGL-2.8. What version of OpenGL do you use? Also what happens when you compile with -dcore-lint?

comment:4 Changed 2 years ago by monoidal

  • Status changed from new to infoneeded

comment:5 Changed 22 months ago by bgamari

I can reproduce a perhaps related issue with GHC 7.7 and OpenGL-2.9.0.0,

$ ghc -O Test.hs
[1 of 1] Compiling Test             ( Test.hs, Test.o )
ghc: panic! (the 'impossible' happened)
  (GHC version 7.7.20130919 for x86_64-unknown-linux):
	StgCmmEnv: variable not found
    ww_s3rs{v} [lid]
    local binds for:
    main:Test.crash{v r1pI} [gid]
    main:Test.invalidCast{v r1pJ} [gid]
    main:Test.crash1{v r3ss} [gid]
    main:Test.$wa{v r3st} [gid]
    ww{v s3tT} [lid]
    ww1{v s3tU} [lid]
    ww2{v s3tV} [lid]
    sat_s3tX{v} [lid]
    sat_s3tY{v} [lid]
    sat_s3tZ{v} [lid]

comment:6 Changed 22 months ago by monoidal

  • Status changed from infoneeded to new

Great, I can now reproduce. I looked into internals of OpenGL and OpenGLRaw and here's a version which does not have the dependency. Compile with -O to get the panic, both 7.6 and HEAD. (edit: made it smaller)

module Test where

import Unsafe.Coerce
import Foreign.C.Types
import System.IO.Unsafe

data D4 = D4 CInt CInt CInt
data Color3 = Color3 CInt CInt

crash :: D4 -> IO ()
crash = color . unsafeCoerce

color :: Color3 -> IO ()
color (Color3 r g) = f (unsafePerformIO undefined) r g

foreign import ccall f :: CInt -> CInt -> CInt -> IO ()
Last edited 22 months ago by monoidal (previous) (diff)

comment:7 Changed 22 months ago by simonpj

Great test case.

You'll see that it unsafely converts a data value with three fields to one with four. I grant that this shouldn't make GHC fail, but it's very likely to lead to a runtime crash. If this is what OpenGL is really doing, I am highly dubious!

Simon

comment:8 Changed 22 months ago by monoidal

OpenGL doesn't have the invalid cast; the original reporter wrote it him/herself. So it's a problem that GHC panics on a rather artificial program.

comment:9 Changed 20 months ago by Simon Peyton Jones <simonpj@…>

In a1b6932419a2d425b2a3b7672926a0f9c368f234/ghc:

Make worker/wrapper robust to bogus unsafeCorece

Fixes Trac #8037

comment:10 Changed 20 months ago by Simon Peyton Jones <simonpj@…>

comment:11 Changed 20 months ago by simonpj

  • Resolution set to fixed
  • Status changed from new to closed
  • Test Case set to stranal/should_compile/T8037

Thanks. I've robustified this.

Simon

Note: See TracTickets for help on using tickets.