[GHC] #14647: Invalid C in the via-C backend due to EFF_

#14647: Invalid C in the via-C backend due to EFF_ -------------------------------------+------------------------------------- Reporter: | Owner: (none) ElvishJerricco | Type: bug | Status: new Priority: normal | Milestone: Component: Compiler | Version: 8.3 Keywords: | Operating System: Unknown/Multiple Architecture: | Type of failure: Other Unknown/Multiple | Test Case: | Blocked By: Blocking: | Related Tickets: #8965 #11395 Differential Rev(s): | Wiki Page: -------------------------------------+------------------------------------- {{{ // Stg.h #define EFF_(f) void f() /* See Note [External function prototypes] */ }}} Whenever Cmm uses a foreign C symbol, the generated C will declare the symbol with `EFF_`. Later, it will cast it to the appropriate type before calling it, often casting it to `void *` beforehand. `EFF_` is used in case the symbol is needed multiple times at incompatible types. This is invalid and discouraged in standard C for a number of reasons. - Even with incomplete args lists, it is invalid to declare a function with an inaccurate return type. - Incomplete args lists is considered "an obsolescent feature" of C. - It is invalid to call a function declared with an incomplete args list at multiple incompatible types. - It is invalid to cast a function to `void *`, as function pointers can technically have different width than regular pointers. This one obviously doesn't matter very much. - Using incomplete args lists to declare a function implemented with varargs is invalid, though this isn't really solvable for `foreign import ccall` without requiring the user to annotate such imports as varargs functions. On all the platforms GHC currently supports, this happens to work out fine. The C ABI on most platforms makes all of this compatible. But I've been working on making GHC target WebAssembly with via-C, and WebAssembly does not currently support this. Although it is [https://bugs.llvm.org/show_bug.cgi?id=35385 an LLVM bug] that incomplete args lists are unsupported on WebAssembly, it's fair-game that the inaccurate return type and liberal casting is broken. The fix is to declare externs with the proper types. We shouldn't use top level extern declarations in case the same symbol needs to be declared with multiple incompatible types (though frankly, I can't think of a good reason for this to occur, aside from varargs symbols, which is already invalid). We can use local externs to avoid the type incompatibilities. {{{ void foo() { extern int bar(int, int); ... } }}} The difficulty here is that Cmm doesn't carry the information necessary to make such declarations. {{{ module Test where foreign import ccall unsafe "testCSymbol" testHaskellSymbol :: Int -> Int -> Int -> Int }}} {{{ ghc -c Test.hs -o Test.o -ddump-cmm-raw }}} {{{ ... _s17E::I64 = I64[_s17D::P64 + 7]; _c188::I64 = testCSymbol; _c189::I64 = _s17A::I64; _c18a::I64 = _s17C::I64; _c18b::I64 = _s17E::I64; (_s17I::I64) = call "ccall" arg hints: [‘signed’, ‘signed’, ‘signed’] result hints: [‘signed’] (_c188::I64)(_c189::I64, _c18a::I64, _c18b::I64); ... }}} Cmm does not make any forward declaration of `testCSymbol`. It just uses the name ad-hoc, assigning it to the `c188` variable, eventually calling that variable at the proper type. This makes it nontrival to infer `testCSymbol`'s type (probably undecidable, considering anything can theoretically happen to these variables). It seems to me that Cmm needs to outlaw implicit declarations of foreign C symbols, `EFF_` needs to be removed, and there needs to be a local extern declaration syntax in Cmm. -- Ticket URL: http://ghc.haskell.org/trac/ghc/ticket/14647 GHC http://www.haskell.org/ghc/ The Glasgow Haskell Compiler

#14647: Invalid C in the via-C backend due to EFF_ -------------------------------------+------------------------------------- Reporter: ElvishJerricco | Owner: (none) Type: bug | Status: new Priority: normal | Milestone: Component: Compiler | Version: 8.3 Resolution: | Keywords: Operating System: Unknown/Multiple | Architecture: | Unknown/Multiple Type of failure: Other | Test Case: Blocked By: | Blocking: Related Tickets: #8965 #11395 | Differential Rev(s): Wiki Page: | -------------------------------------+------------------------------------- Changes (by ElvishJerricco): * Attachment "ghc.patch" added. -- Ticket URL: http://ghc.haskell.org/trac/ghc/ticket/14647 GHC http://www.haskell.org/ghc/ The Glasgow Haskell Compiler

#14647: Invalid C in the via-C backend due to EFF_ -------------------------------------+------------------------------------- Reporter: ElvishJerricco | Owner: (none) Type: bug | Status: new Priority: normal | Milestone: Component: Compiler | Version: 8.3 Resolution: | Keywords: Operating System: Unknown/Multiple | Architecture: | Unknown/Multiple Type of failure: Other | Test Case: Blocked By: | Blocking: Related Tickets: #8965 #11395 | Differential Rev(s): Wiki Page: | -------------------------------------+------------------------------------- Comment (by ElvishJerricco): This patch is not pretty yet, and is fairly incomplete. It just fixes Stg->Cmm->C. It doesn't work with any of the handwritten Cmm that makes foreign C calls yet. Also, none of the other code generators work yet, but I just want to get the via-C working first. -- Ticket URL: http://ghc.haskell.org/trac/ghc/ticket/14647#comment:1 GHC http://www.haskell.org/ghc/ The Glasgow Haskell Compiler
participants (1)
-
GHC