Admin message

Due to a large amount of spam we do not allow new users to create repositories, they are "external" users. If you are a new user and want to create a repository, for example for forking GHC, open a new issue on ghc/ghc using the "get-verified" issue template

capi foreign imports involving pointers to pointers to non-primitive types don't compile with recent C compilers
## Summary Recent versions of `gcc` and `clang` treat `-Wincompatible-pointer-types` as an error by default. The problem with this is that `capi` compiles pointers of types that aren't obvious primitives to void pointers. Most of the time this is fine, since `-Wincompatible-pointer-types` includes an exception that allows passing void pointers to functions that accept more specific pointers, however that exception does *not* include passing `void**` to functions that accept pointers to more specific pointers, so the C compiler will still fail in that case. ## Steps to reproduce Define a C header `example.h` ```c typedef struct abstract abstract; void blah(abstract** x) {} ``` And import it in a Haskell module with `capi` ```hs {-# LANGUAGE CApiFFI #-} module Example where import Foreign (Ptr) import Foreign.C (CUInt) data Abstract foreign import capi "example.h blah" blah :: Ptr (Ptr Abstract) -> IO () ``` Which produces the following error message: ``` [1 of 1] Compiling Example ( Example.hs, Example.o ) [Source file changed] /tmp/ghc63201_tmp_5_0/ghc_tmp_5_2.c: In function ‘ghczuwrapperZC0ZCmainZCExampleZCblah’: /tmp/ghc63201_tmp_5_0/ghc_tmp_5_2.c:8:60: error: error: passing argument 1 of ‘blah’ from incompatible pointer type [-Wincompatible-pointer-types] 8 | void ghczuwrapperZC0ZCmainZCExampleZCblah(void** a1) {blah(a1);} | ^~ | | | void ** | 8 | void ghczuwrapperZC0ZCmainZCExampleZCblah(void** a1) {blah(a1);} | ^ In file included from /tmp/ghc63201_tmp_5_0/ghc_tmp_5_2.c:7:0: error: example.h:3:22: error: note: expected ‘abstract **’ but argument is of type ‘void **’ 3 | void blah(abstract** x) {} | ~~~~~~~~~~~^ | 3 | void blah(abstract** x) {} | ^ <no location info>: error: `gcc' failed in phase `C Compiler'. (Exit code: 1) ``` ## Expected behavior I think there are two sensible solutions here: 1) Turn off `-Wincompatible-pointer-types` for `capi` wrappers. This essentially mirrors the old behavior before it was on by default. The drawback here is that there are cases where the error *does* catch genuine mistakes (such as declaring an argument of type `int*` as `Ptr Int`, which would become `HSInt*` in C) that would be a bit unfortunate to lose. 2) Compile pointers to types that would become void pointers (or pointers to ... to void pointers) to a single layer of void pointer. This way, whenever the exact C type of the pointee is not known, ghc would take the conservative option and ensure that the `void*` exception of `-Wincompatible-pointer-types` applies. In most normal cases this shouldn't make a difference, although it might be possible to construct a macro such that a `capi` binding to it compiles with the current behavior but not with this translation. ## Environment * GHC version used: 9.14.1 * GCC version used: 15.2.1
issue