`withForeignPtr` is currently unsound
While looking at the keepAlive#
work I noticed that today, even ignoring #17760 (closed), withForeignPtr
is wrong. Specifically looking at the test program from #17746 compiled with GHC 8.8.2 and -O1
, withForeignPtr
produces a touch#
application like the following:
case touch#
@ 'GHC.Types.LiftedRep
@ ForeignPtrContents
(GHC.ForeignPtr.MallocPtr ipv3_a2dc ipv1_a2d7)
s4_a2mp
of s'_a2jQ
{ __DEFAULT ->
(# s'_a2jQ, GHC.Tuple.() #)
}
It reboxed the ForeignPtrContents
! The problem here appears to be that both mallocForeignPtrBytes
and withForeignPtr
inlined, allowing case-of-known-constructor to eliminate not just the ForeignPtr
constructor but also the ForeignPtrContents
. Consequently, when we finally do need the a real ForeignPtrContents
constructor in the touch#
we allocate a fresh one. Awful!
Really, withForeignPtr
shouldn't be touch#
ing a constructor. We need some other object (with identity and not subject to elimination via simplification) to touch.