[GHC] #8926: GHC makes unsound references in object code
GHC
ghc-devs at haskell.org
Mon Mar 24 23:12:50 UTC 2014
#8926: GHC makes unsound references in object code
----------------------------+----------------------------------------------
Reporter: | Owner:
anton.dubovik | Status: new
Type: bug | Milestone:
Priority: normal | Version: 7.6.3
Component: Compiler | Operating System: Unknown/Multiple
Keywords: | Type of failure: GHC rejects valid program
Architecture: | Test Case:
Unknown/Multiple | Blocking:
Difficulty: Unknown |
Blocked By: |
Related Tickets: |
----------------------------+----------------------------------------------
To reproduce the bug run script `run.sh` from the attached archive.
It will:
1. install `FooPackage`
{{{
Resolving dependencies...
Configuring FooPackage-0.1...
Building FooPackage-0.1...
Preprocessing library FooPackage-0.1...
[1 of 1] Compiling FooPackage ( src\FooPackage.hs,
dist\build\FooPackage.o )
In-place registering FooPackage-0.1...
Installing library in
C:\Users\Anton\AppData\Roaming\cabal\i386-windows-
ghc-7.6.3\FooPackage-0.1
Registering FooPackage-0.1...
Installed FooPackage-0.1
}}}
2. compile executable `Client1` which depends on `FooPackage`
{{{
[1 of 3] Compiling QuxClient ( QuxClient.hs, obj\QuxClient.o )
[2 of 3] Compiling BarClient ( BarClient.hs, obj\BarClient.o )
[3 of 3] Compiling Client1 ( Client1.hs, obj\Client1.o )
Linking exes/Client1.exe ...
}}}
3. compile executable `Client2` which doesn't depend on `FooPackage`
At the third step GHC will fall with linker error:
{{{
[2 of 2] Compiling Client2 ( Client2.hs, obj\Client2.o )
Linking exes/Client2.exe ...
obj\BarClient.o:fake:(.text+0x83): undefined reference to
`FooPackagezm0zi1_FooPackage_zdsinsertzuzdsgo5_info'
obj\BarClient.o:fake:(.data+0x10): undefined reference to
`FooPackagezm0zi1_FooPackage_zdsinsertzuzdsgo5_closure'
collect2: ld returned 1 exit status
}}}
Both `Client1` and `Client2` import `BarClient` module that doesn't
depends on `FooPackage`.
`Client1` imports `QuxClient` that imports `FooPackage`:
{{{
module QuxClient where
import FooPackage(foo)
import Data.Set
qux :: Set String -> Set String
qux = foo
}}}
{{{
module BarClient where
import Data.Set
bar :: Set String -> Set String
bar s = insert "bar" s
}}}
`FooPackage` uses function `Data.Set.insert` which is marked at `Data.Set`
as `INLINABLE`:
{{{
module FooPackage where
import Data.Set
foo :: Set String -> Set String
foo s = insert "foo" s
}}}
GHC emphasizes in interface file, that `FooPackage.o` contains specialized
version of `Data.Set.insert`:
{{{
> ghc --show-iface FooPackage.hi
...
"SPEC Data.Set.Base.insert [GHC.Base.String]" [ALWAYS] forall $dOrd ::
GHC.Classes.Ord
GHC.Base.String
Data.Set.Base.insert @ [GHC.Types.Char] $dOrd = FooPackage.$sinsert
...
}}}
Later GHC see again the use of `Data.Set.insert at String` at `BarClient` and
decides to apply this specialise rule, so that `BarClient` now has
reference to `FooPackage`:
{{{
> ghc --show-iface BarClient.hi
...
bar :: Data.Set.Base.Set GHC.Base.String
-> Data.Set.Base.Set GHC.Base.String
{- Arity: 1, Strictness: S,
Unfolding: (\ s :: Data.Set.Base.Set GHC.Base.String ->
FooPackage.$sinsert_$sgo5 BarClient.bar1 s) -}
...
}}}
`Client2` doesn't depend on `FooPackage`, thus linker throws an error.
There are plenty of workarounds here, but all of them are ad hoc (1,2,3)
or could affect performance (4):
1. Change the order of `BarClient` and `QuxClient` imports in `Client1`
module.
2. Compile `Client1` and `Client2` in opposite order.
3. Add fake import at `Client2` module:
{{{
import FooPackage()
}}}
4. Build `FooPackage` with ghc-option `-fomit-interface-pragmas`. That
will eraise from `FooPackage.hi` all specialisation rules as well as
information about strictness and inlining.
Some information about the environment:
{{{
> ghc-pkg list
...
containers-0.5.0.0
base-4.6.0.1
...
> ghc --version
The Glorious Glasgow Haskell Compilation System, version 7.6.3
> cabal --version
cabal-install version 1.18.0.3
using version 1.18.1.3 of the Cabal library
}}}
--
Ticket URL: <http://ghc.haskell.org/trac/ghc/ticket/8926>
GHC <http://www.haskell.org/ghc/>
The Glasgow Haskell Compiler
More information about the ghc-tickets
mailing list