Opened 3 years ago

Closed 3 years ago

#7506 closed bug (fixed)

adding extra arguments to a foreign import statement can cause ghc to panic

Reported by: jwlato Owned by:
Priority: normal Milestone:
Component: Compiler (FFI) Version: 7.6.1
Keywords: Cc:
Operating System: Unknown/Multiple Architecture: Unknown/Multiple
Type of failure: Compile-time crash Test Case: ffi/should_fail/T7506
Blocked By: Blocking:
Related Tickets: Differential Rev(s):
Wiki Page:


When defining a "FunPtr" of a C import, adding extra arguments outside the "FunPtr" causes ghc to panic.

{-# LANGUAGE ForeignFunctionInterface #-}

module Foo where

import Foreign.Ptr
foreign import ccall "stdio.h &putchar" c_putchar :: () -> FunPtr (Char -> IO ())

compiling results in

[1 of 1] Compiling Foo              ( foo.hs, foo.o )
ghc: panic! (the 'impossible' happened)
  (GHC version for x86_64-unknown-linux):
    ghc-prim:GHC.Tuple.(){(w) tc 40}
    -> base:GHC.Ptr.FunPtr{tc 33D}
         (ghc-prim:GHC.Types.Char{(w) tc 3o}
          -> ghc-prim:GHC.Types.IO{tc 32I} ghc-prim:GHC.Tuple.(){(w) tc 40})

Ideally, a solution to this would allow for partially applying a value that would be accessed within the FunPtr, although that's probably not trivial to support.

Change History (2)

comment:1 Changed 3 years ago by simonpj@…

commit 942939c050b0649430a2e41b026499efb46d5f17

Author: Simon Peyton Jones <[email protected]>
Date:   Wed Dec 19 13:23:21 2012 +0000

    Fix Trac #7506 (missing check for form of FFI type)

 compiler/typecheck/TcForeign.lhs |   12 ++++++++----
 1 files changed, 8 insertions(+), 4 deletions(-)

comment:2 Changed 3 years ago by simonpj

  • difficulty set to Unknown
  • Resolution set to fixed
  • Status changed from new to closed
  • Test Case set to ffi/should_fail/T7506

The problem here is simply that a foreign import with a "&" should not have an arrow in its type. See the FFI spec.

GHC should not crash though. Now it says

    Unacceptable type in foreign declaration: Int -> IO ()
    A foreign-imported address (via &foo) must have type (Ptr a) or (FunPtr a)
    When checking declaration:
      foreign import ccall safe "static stdio.h &putchar" c_putchar
        :: Int -> IO ()
Note: See TracTickets for help on using tickets.