Marge Bot pushed to branch master at Glasgow Haskell Compiler / GHC
Commits:
1ca4b49a by Cheng Shao at 2025-12-18T13:23:11-05:00
compiler/rts: fix ABI mismatch in barf() invocations
This patch fixes a long-standing issue of ABI mismatch in `barf()`
invocations, both in compiler-emitted code and in hand written Cmm
code:
- In RTS, we have `barf()` which reports a fatal internal error
message and exits the program.
- `barf()` is a variadic C function! When used as a callee of a
foreign call with `ccall` calling convention instead of `capi`,
there is an ABI mismatch between the caller and the callee!
- Unfortunately, both the compiler and the Cmm sources contain many
places where we call `barf()` via `ccall` convention!! Like, when
you write `foreign "C" barf("foo object (%p) entered!", R1)`, it
totally doesn't do what you think it'll do at all!! The second
argument `R1` is not properly passed in `va_list`, and the behavior
is completely undefined!!
- Even more unfortunately, this issue has been sitting around long
enough because the ABI mismatch is subtle enough on normie platforms
like x64 and arm64.
- But there are platforms like wasm32 that are stricter about ABI, and
the broken `barf()` invocations already causes trouble for wasm
backend: we had to use ugly hacks like `barf(errmsg, NULL)` to make
`wasm-ld` happy, and even with this band-aid, compiler-generated
`barf()` invocations are still broken, resulting in regressions in
certain debug-related functionality, e.g. `-dtag-inference-checks`
is broken on wasm32 (#22882).
This patch properly fixes the issue:
- We add non-variadic `barf` wrappers in the RTS that can be used as
`ccall` callees
- Both the compiler `emitBarf` logic and the hand-written Cmm are
changed to call these wrappers
- `emitBarf` now also properly annotates the foreign call as
`CmmNeverReturns` to indicate it's a noreturn call to enable more
efficient code generation
`-dtag-inference-checks` now works on wasm. Closes #22882.
Co-authored-by: Codex
- - - - -
14 changed files:
- compiler/GHC/StgToCmm/Bind.hs
- compiler/GHC/StgToCmm/Utils.hs
- rts/Apply.cmm
- rts/Compact.cmm
- rts/ContinuationOps.cmm
- rts/Exception.cmm
- rts/Jumps.h
- rts/PrimOps.cmm
- rts/RtsMessages.c
- rts/StgMiscClosures.cmm
- rts/StgStartup.cmm
- rts/include/rts/Messages.h
- testsuite/tests/simplStg/should_compile/all.T
- utils/genapply/Main.hs
Changes:
=====================================
compiler/GHC/StgToCmm/Bind.hs
=====================================
@@ -866,7 +866,7 @@ link_caf node = do
; let profile = stgToCmmProfile cfg
; let platform = profilePlatform profile
; bh <- newTemp (bWord platform)
- ; emitRtsCallGen [(bh,AddrHint)] newCAF_lbl
+ ; emitRtsCallGen [(bh,AddrHint)] newCAF_lbl CmmMayReturn
[ (baseExpr platform, AddrHint),
(CmmReg (CmmLocal node), AddrHint) ]
False
=====================================
compiler/GHC/StgToCmm/Utils.hs
=====================================
@@ -186,23 +186,27 @@ tagToClosure platform tycon tag
emitBarf :: String -> FCode ()
emitBarf msg = do
strLbl <- newStringCLit msg
- emitRtsCall rtsUnitId (fsLit "barf") [(CmmLit strLbl,AddrHint)] False
+ emitRtsCallGen [] (mkCmmCodeLabel rtsUnitId (fsLit "sbarf"))
+ CmmNeverReturns
+ [(CmmLit strLbl, AddrHint)] False
emitRtsCall :: UnitId -> FastString -> [(CmmExpr,ForeignHint)] -> Bool -> FCode ()
-emitRtsCall pkg fun = emitRtsCallGen [] (mkCmmCodeLabel pkg fun)
+emitRtsCall pkg fun = emitRtsCallGen [] (mkCmmCodeLabel pkg fun) CmmMayReturn
emitRtsCallWithResult :: LocalReg -> ForeignHint -> UnitId -> FastString
-> [(CmmExpr,ForeignHint)] -> Bool -> FCode ()
-emitRtsCallWithResult res hint pkg = emitRtsCallGen [(res,hint)] . mkCmmCodeLabel pkg
+emitRtsCallWithResult res hint pkg =
+ \fun -> emitRtsCallGen [(res,hint)] (mkCmmCodeLabel pkg fun) CmmMayReturn
-- Make a call to an RTS C procedure
emitRtsCallGen
:: [(LocalReg,ForeignHint)]
-> CLabel
+ -> CmmReturnInfo
-> [(CmmExpr,ForeignHint)]
-> Bool -- True <=> CmmSafe call
-> FCode ()
-emitRtsCallGen res lbl args safe
+emitRtsCallGen res lbl ret_info args safe
= do { platform <- getPlatform
; updfr_off <- getUpdFrameOff
; let (caller_save, caller_load) = callerSaveVolatileRegs platform
@@ -214,7 +218,7 @@ emitRtsCallGen res lbl args safe
if safe then
emit =<< mkCmmCall fun_expr res' args' updfr_off
else do
- let conv = ForeignConvention CCallConv arg_hints res_hints CmmMayReturn
+ let conv = ForeignConvention CCallConv arg_hints res_hints ret_info
emit $ mkUnsafeCall (ForeignTarget fun_expr conv) res' args'
(args', arg_hints) = unzip args
(res', res_hints) = unzip res
=====================================
rts/Apply.cmm
=====================================
@@ -250,7 +250,7 @@ again:
-------------------------------------------------------------------------- */
INFO_TABLE(stg_PAP,/*special layout*/0,0,PAP,"PAP","PAP")
-{ ccall barf("PAP object (%p) entered!", R1) never returns; }
+{ ccall pbarf("PAP object (%p) entered!", R1 "ptr") never returns; }
stg_PAP_apply /* no args => explicit stack */
{
=====================================
rts/Compact.cmm
=====================================
@@ -282,7 +282,7 @@ eval:
goto constructor;
}}
- ccall barf("stg_compactWorkerzh", NULL);
+ ccall sbarf("stg_compactWorkerzh") never returns;
}
//
=====================================
rts/ContinuationOps.cmm
=====================================
@@ -36,7 +36,7 @@ import CLOSURE ghc_hs_iface;
-------------------------------------------------------------------------- */
INFO_TABLE(stg_PROMPT_TAG,0,0,PRIM,"PROMPT_TAG","PROMPT_TAG")
-{ foreign "C" barf("PROMPT_TAG object (%p) entered!", R1) never returns; }
+{ ccall pbarf("PROMPT_TAG object (%p) entered!", R1 "ptr") never returns; }
stg_newPromptTagzh()
{
=====================================
rts/Exception.cmm
=====================================
@@ -666,11 +666,11 @@ stg_raiseOverflowzh ()
*/
stg_paniczh (W_ str)
{
- ccall barf(str, NULL) never returns;
+ ccall sbarf(str "ptr") never returns;
}
// See Note [Compiler error functions] in GHC.Prim.Panic
stg_absentErrorzh (W_ str)
{
- ccall barf("Oops! Entered absent arg %s", str) never returns;
+ ccall ssbarf("Oops! Entered absent arg %s", str "ptr") never returns;
}
=====================================
rts/Jumps.h
=====================================
@@ -70,7 +70,7 @@ INFO_TABLE_RET (MK_FUN_NM(stg_stack_underflow_frame), UNDERFLOW_FRAME,
jump %ENTRY_CODE(Sp(ret_off)) ALL_ARG_REGS;
#else
- ccall barf("stg_stack_underflow_frame: unsupported register", NULL) never returns;
+ ccall sbarf("stg_stack_underflow_frame: unsupported register") never returns;
#endif
}
@@ -96,6 +96,6 @@ INFO_TABLE_RET (MK_FUN_NM(stg_restore_cccs), RET_SMALL, W_ info_ptr, W_ cccs)
jump %ENTRY_CODE(Sp(0)) ALL_ARG_REGS;
#else
- ccall barf("stg_restore_cccs: unsupported register", NULL) never returns;
+ ccall sbarf("stg_restore_cccs: unsupported register") never returns;
#endif
}
=====================================
rts/PrimOps.cmm
=====================================
@@ -2332,7 +2332,7 @@ stg_asyncReadzh ( W_ fd, W_ is_sock, W_ len, W_ buf )
CInt reqID;
#if defined(THREADED_RTS)
- ccall barf("asyncRead# on threaded RTS") never returns;
+ ccall sbarf("asyncRead# on threaded RTS") never returns;
#else
/* could probably allocate this on the heap instead */
@@ -2358,7 +2358,7 @@ stg_asyncWritezh ( W_ fd, W_ is_sock, W_ len, W_ buf )
CInt reqID;
#if defined(THREADED_RTS)
- ccall barf("asyncWrite# on threaded RTS") never returns;
+ ccall sbarf("asyncWrite# on threaded RTS") never returns;
#else
("ptr" ares) = ccall stgMallocBytes(SIZEOF_StgAsyncIOResult,
@@ -2384,7 +2384,7 @@ stg_asyncDoProczh ( W_ proc, W_ param )
CInt reqID;
#if defined(THREADED_RTS)
- ccall barf("asyncDoProc# on threaded RTS") never returns;
+ ccall sbarf("asyncDoProc# on threaded RTS") never returns;
#else
/* could probably allocate this on the heap instead */
=====================================
rts/RtsMessages.c
=====================================
@@ -58,6 +58,24 @@ vbarf(const char*s, va_list ap)
stg_exit(EXIT_INTERNAL_ERROR); // just in case fatalInternalErrorFn() returns
}
+void
+sbarf(const char*s)
+{
+ barf("%s", s);
+}
+
+void
+pbarf(const char*fmt, void *p)
+{
+ barf(fmt, p);
+}
+
+void
+ssbarf(const char *fmt, const char *s)
+{
+ barf(fmt, s);
+}
+
void
_assertFail(const char*filename, unsigned int linenum)
{
=====================================
rts/StgMiscClosures.cmm
=====================================
@@ -473,7 +473,7 @@ INFO_TABLE_RET( stg_dead_thread, RET_SMALL,
W_ info_ptr,
PROF_HDR_FIELDS(W_,p1,p2)
P_ result )
-{ foreign "C" barf("stg_dead_thread entered!", NULL) never returns; }
+{ ccall sbarf("stg_dead_thread entered!") never returns; }
/* ----------------------------------------------------------------------------
Entry code for a BCO
@@ -631,11 +631,11 @@ INFO_TABLE(__stg_EAGER_BLACKHOLE,1,0,BLACKHOLE,"BLACKHOLE","BLACKHOLE")
}
INFO_TABLE(stg_BLOCKING_QUEUE_CLEAN,4,0,BLOCKING_QUEUE,"BLOCKING_QUEUE","BLOCKING_QUEUE")
-{ foreign "C" barf("BLOCKING_QUEUE_CLEAN object (%p) entered!", R1) never returns; }
+{ ccall pbarf("BLOCKING_QUEUE_CLEAN object (%p) entered!", R1 "ptr") never returns; }
INFO_TABLE(stg_BLOCKING_QUEUE_DIRTY,4,0,BLOCKING_QUEUE,"BLOCKING_QUEUE","BLOCKING_QUEUE")
-{ foreign "C" barf("BLOCKING_QUEUE_DIRTY object (%p) entered!", R1) never returns; }
+{ ccall pbarf("BLOCKING_QUEUE_DIRTY object (%p) entered!", R1 "ptr") never returns; }
/* ----------------------------------------------------------------------------
@@ -673,7 +673,7 @@ loop:
ACQUIRE_FENCE_ON(node + OFFSET_StgHeader_info);
jump %ENTRY_CODE(info) (node);
#else
- ccall barf("WHITEHOLE object (%p) entered!", R1) never returns;
+ ccall pbarf("WHITEHOLE object (%p) entered!", R1 "ptr") never returns;
#endif
}
@@ -684,10 +684,10 @@ loop:
------------------------------------------------------------------------- */
INFO_TABLE(stg_TSO, 0,0,TSO, "TSO", "TSO")
-{ foreign "C" barf("TSO object (%p) entered!", R1) never returns; }
+{ ccall pbarf("TSO object (%p) entered!", R1 "ptr") never returns; }
INFO_TABLE(stg_STACK, 0,0, STACK, "STACK", "STACK")
-{ foreign "C" barf("STACK object (%p) entered!", R1) never returns; }
+{ ccall pbarf("STACK object (%p) entered!", R1 "ptr") never returns; }
/* ----------------------------------------------------------------------------
Weak pointers
@@ -698,7 +698,7 @@ INFO_TABLE(stg_STACK, 0,0, STACK, "STACK", "STACK")
------------------------------------------------------------------------- */
INFO_TABLE(stg_WEAK,1,4,WEAK,"WEAK","WEAK")
-{ foreign "C" barf("WEAK object (%p) entered!", R1) never returns; }
+{ ccall pbarf("WEAK object (%p) entered!", R1 "ptr") never returns; }
/*
* It's important when turning an existing WEAK into a DEAD_WEAK
@@ -707,7 +707,7 @@ INFO_TABLE(stg_WEAK,1,4,WEAK,"WEAK","WEAK")
* DEAD_WEAK 5 non-pointer fields.
*/
INFO_TABLE_CONSTR(stg_DEAD_WEAK,0,5,0,CONSTR,"DEAD_WEAK","DEAD_WEAK")
-{ foreign "C" barf("DEAD_WEAK object (%p) entered!", R1) never returns; }
+{ ccall pbarf("DEAD_WEAK object (%p) entered!", R1 "ptr") never returns; }
/* ----------------------------------------------------------------------------
C finalizer lists
@@ -716,7 +716,7 @@ INFO_TABLE_CONSTR(stg_DEAD_WEAK,0,5,0,CONSTR,"DEAD_WEAK","DEAD_WEAK")
------------------------------------------------------------------------- */
INFO_TABLE_CONSTR(stg_C_FINALIZER_LIST,1,4,0,CONSTR,"C_FINALIZER_LIST","C_FINALIZER_LIST")
-{ foreign "C" barf("C_FINALIZER_LIST object (%p) entered!", R1) never returns; }
+{ ccall pbarf("C_FINALIZER_LIST object (%p) entered!", R1 "ptr") never returns; }
/* ----------------------------------------------------------------------------
NO_FINALIZER
@@ -726,7 +726,7 @@ INFO_TABLE_CONSTR(stg_C_FINALIZER_LIST,1,4,0,CONSTR,"C_FINALIZER_LIST","C_FINALI
------------------------------------------------------------------------- */
INFO_TABLE_CONSTR(stg_NO_FINALIZER,0,0,0,CONSTR_NOCAF,"NO_FINALIZER","NO_FINALIZER")
-{ foreign "C" barf("NO_FINALIZER object (%p) entered!", R1) never returns; }
+{ ccall pbarf("NO_FINALIZER object (%p) entered!", R1 "ptr") never returns; }
CLOSURE(stg_NO_FINALIZER_closure,stg_NO_FINALIZER);
@@ -735,7 +735,7 @@ CLOSURE(stg_NO_FINALIZER_closure,stg_NO_FINALIZER);
------------------------------------------------------------------------- */
INFO_TABLE(stg_STABLE_NAME,0,1,PRIM,"STABLE_NAME","STABLE_NAME")
-{ foreign "C" barf("STABLE_NAME object (%p) entered!", R1) never returns; }
+{ ccall pbarf("STABLE_NAME object (%p) entered!", R1 "ptr") never returns; }
/* ----------------------------------------------------------------------------
MVars
@@ -745,38 +745,38 @@ INFO_TABLE(stg_STABLE_NAME,0,1,PRIM,"STABLE_NAME","STABLE_NAME")
------------------------------------------------------------------------- */
INFO_TABLE(stg_MVAR_CLEAN,3,0,MVAR_CLEAN,"MVAR","MVAR")
-{ foreign "C" barf("MVAR object (%p) entered!", R1) never returns; }
+{ ccall pbarf("MVAR object (%p) entered!", R1 "ptr") never returns; }
INFO_TABLE(stg_MVAR_DIRTY,3,0,MVAR_DIRTY,"MVAR","MVAR")
-{ foreign "C" barf("MVAR object (%p) entered!", R1) never returns; }
+{ ccall pbarf("MVAR object (%p) entered!", R1 "ptr") never returns; }
/* -----------------------------------------------------------------------------
STM
-------------------------------------------------------------------------- */
INFO_TABLE(stg_TVAR_CLEAN, 2, 1, TVAR, "TVAR", "TVAR")
-{ foreign "C" barf("TVAR_CLEAN object (%p) entered!", R1) never returns; }
+{ ccall pbarf("TVAR_CLEAN object (%p) entered!", R1 "ptr") never returns; }
INFO_TABLE(stg_TVAR_DIRTY, 2, 1, TVAR, "TVAR", "TVAR")
-{ foreign "C" barf("TVAR_DIRTY object (%p) entered!", R1) never returns; }
+{ ccall pbarf("TVAR_DIRTY object (%p) entered!", R1 "ptr") never returns; }
INFO_TABLE(stg_TVAR_WATCH_QUEUE, 3, 0, MUT_PRIM, "TVAR_WATCH_QUEUE", "TVAR_WATCH_QUEUE")
-{ foreign "C" barf("TVAR_WATCH_QUEUE object (%p) entered!", R1) never returns; }
+{ ccall pbarf("TVAR_WATCH_QUEUE object (%p) entered!", R1 "ptr") never returns; }
INFO_TABLE(stg_TREC_CHUNK, 0, 0, TREC_CHUNK, "TREC_CHUNK", "TREC_CHUNK")
-{ foreign "C" barf("TREC_CHUNK object (%p) entered!", R1) never returns; }
+{ ccall pbarf("TREC_CHUNK object (%p) entered!", R1 "ptr") never returns; }
INFO_TABLE(stg_TREC_HEADER, 2, 1, MUT_PRIM, "TREC_HEADER", "TREC_HEADER")
-{ foreign "C" barf("TREC_HEADER object (%p) entered!", R1) never returns; }
+{ ccall pbarf("TREC_HEADER object (%p) entered!", R1 "ptr") never returns; }
INFO_TABLE_CONSTR(stg_END_STM_WATCH_QUEUE,0,0,0,CONSTR_NOCAF,"END_STM_WATCH_QUEUE","END_STM_WATCH_QUEUE")
-{ foreign "C" barf("END_STM_WATCH_QUEUE object (%p) entered!", R1) never returns; }
+{ ccall pbarf("END_STM_WATCH_QUEUE object (%p) entered!", R1 "ptr") never returns; }
INFO_TABLE_CONSTR(stg_END_STM_CHUNK_LIST,0,0,0,CONSTR_NOCAF,"END_STM_CHUNK_LIST","END_STM_CHUNK_LIST")
-{ foreign "C" barf("END_STM_CHUNK_LIST object (%p) entered!", R1) never returns; }
+{ ccall pbarf("END_STM_CHUNK_LIST object (%p) entered!", R1 "ptr") never returns; }
INFO_TABLE_CONSTR(stg_NO_TREC,0,0,0,CONSTR_NOCAF,"NO_TREC","NO_TREC")
-{ foreign "C" barf("NO_TREC object (%p) entered!", R1) never returns; }
+{ ccall pbarf("NO_TREC object (%p) entered!", R1 "ptr") never returns; }
CLOSURE(stg_END_STM_WATCH_QUEUE_closure,stg_END_STM_WATCH_QUEUE);
@@ -791,52 +791,52 @@ CLOSURE(stg_NO_TREC_closure,stg_NO_TREC);
------------------------------------------------------------------------- */
INFO_TABLE_CONSTR(stg_SRT_1, 1, 0, 0, CONSTR_1_0, "SRT_1", "SRT_1")
-{ foreign "C" barf("SRT_1 object (%p) entered!", R1) never returns; }
+{ ccall pbarf("SRT_1 object (%p) entered!", R1 "ptr") never returns; }
INFO_TABLE_CONSTR(stg_SRT_2, 2, 0, 0, CONSTR_2_0, "SRT_2", "SRT_2")
-{ foreign "C" barf("SRT_2 object (%p) entered!", R1) never returns; }
+{ ccall pbarf("SRT_2 object (%p) entered!", R1 "ptr") never returns; }
INFO_TABLE_CONSTR(stg_SRT_3, 3, 0, 0, CONSTR, "SRT_3", "SRT_3")
-{ foreign "C" barf("SRT_3 object (%p) entered!", R1) never returns; }
+{ ccall pbarf("SRT_3 object (%p) entered!", R1 "ptr") never returns; }
INFO_TABLE_CONSTR(stg_SRT_4, 4, 0, 0, CONSTR, "SRT_4", "SRT_4")
-{ foreign "C" barf("SRT_4 object (%p) entered!", R1) never returns; }
+{ ccall pbarf("SRT_4 object (%p) entered!", R1 "ptr") never returns; }
INFO_TABLE_CONSTR(stg_SRT_5, 5, 0, 0, CONSTR, "SRT_5", "SRT_5")
-{ foreign "C" barf("SRT_5 object (%p) entered!", R1) never returns; }
+{ ccall pbarf("SRT_5 object (%p) entered!", R1 "ptr") never returns; }
INFO_TABLE_CONSTR(stg_SRT_6, 6, 0, 0, CONSTR, "SRT_6", "SRT_6")
-{ foreign "C" barf("SRT_6 object (%p) entered!", R1) never returns; }
+{ ccall pbarf("SRT_6 object (%p) entered!", R1 "ptr") never returns; }
INFO_TABLE_CONSTR(stg_SRT_7, 7, 0, 0, CONSTR, "SRT_7", "SRT_7")
-{ foreign "C" barf("SRT_7 object (%p) entered!", R1) never returns; }
+{ ccall pbarf("SRT_7 object (%p) entered!", R1 "ptr") never returns; }
INFO_TABLE_CONSTR(stg_SRT_8, 8, 0, 0, CONSTR, "SRT_8", "SRT_8")
-{ foreign "C" barf("SRT_8 object (%p) entered!", R1) never returns; }
+{ ccall pbarf("SRT_8 object (%p) entered!", R1 "ptr") never returns; }
INFO_TABLE_CONSTR(stg_SRT_9, 9, 0, 0, CONSTR, "SRT_9", "SRT_9")
-{ foreign "C" barf("SRT_9 object (%p) entered!", R1) never returns; }
+{ ccall pbarf("SRT_9 object (%p) entered!", R1 "ptr") never returns; }
INFO_TABLE_CONSTR(stg_SRT_10, 10, 0, 0, CONSTR, "SRT_10", "SRT_10")
-{ foreign "C" barf("SRT_10 object (%p) entered!", R1) never returns; }
+{ ccall pbarf("SRT_10 object (%p) entered!", R1 "ptr") never returns; }
INFO_TABLE_CONSTR(stg_SRT_11, 11, 0, 0, CONSTR, "SRT_11", "SRT_11")
-{ foreign "C" barf("SRT_11 object (%p) entered!", R1) never returns; }
+{ ccall pbarf("SRT_11 object (%p) entered!", R1 "ptr") never returns; }
INFO_TABLE_CONSTR(stg_SRT_12, 12, 0, 0, CONSTR, "SRT_12", "SRT_12")
-{ foreign "C" barf("SRT_12 object (%p) entered!", R1) never returns; }
+{ ccall pbarf("SRT_12 object (%p) entered!", R1 "ptr") never returns; }
INFO_TABLE_CONSTR(stg_SRT_13, 13, 0, 0, CONSTR, "SRT_13", "SRT_13")
-{ foreign "C" barf("SRT_13 object (%p) entered!", R1) never returns; }
+{ ccall pbarf("SRT_13 object (%p) entered!", R1 "ptr") never returns; }
INFO_TABLE_CONSTR(stg_SRT_14, 14, 0, 0, CONSTR, "SRT_14", "SRT_14")
-{ foreign "C" barf("SRT_14 object (%p) entered!", R1) never returns; }
+{ ccall pbarf("SRT_14 object (%p) entered!", R1 "ptr") never returns; }
INFO_TABLE_CONSTR(stg_SRT_15, 15, 0, 0, CONSTR, "SRT_15", "SRT_15")
-{ foreign "C" barf("SRT_15 object (%p) entered!", R1) never returns; }
+{ ccall pbarf("SRT_15 object (%p) entered!", R1 "ptr") never returns; }
INFO_TABLE_CONSTR(stg_SRT_16, 16, 0, 0, CONSTR, "SRT_16", "SRT_16")
-{ foreign "C" barf("SRT_16 object (%p) entered!", R1) never returns; }
+{ ccall pbarf("SRT_16 object (%p) entered!", R1 "ptr") never returns; }
/* --------------------------------------------------------------------------- Messages
------------------------------------------------------------------------- */
@@ -844,20 +844,20 @@ INFO_TABLE_CONSTR(stg_SRT_16, 16, 0, 0, CONSTR, "SRT_16", "SRT_16")
// PRIM rather than CONSTR, because PRIM objects cannot be duplicated by the GC.
INFO_TABLE_CONSTR(stg_MSG_TRY_WAKEUP,2,0,0,PRIM,"MSG_TRY_WAKEUP","MSG_TRY_WAKEUP")
-{ foreign "C" barf("MSG_TRY_WAKEUP object (%p) entered!", R1) never returns; }
+{ ccall pbarf("MSG_TRY_WAKEUP object (%p) entered!", R1 "ptr") never returns; }
INFO_TABLE_CONSTR(stg_MSG_THROWTO,4,0,0,PRIM,"MSG_THROWTO","MSG_THROWTO")
-{ foreign "C" barf("MSG_THROWTO object (%p) entered!", R1) never returns; }
+{ ccall pbarf("MSG_THROWTO object (%p) entered!", R1 "ptr") never returns; }
INFO_TABLE_CONSTR(stg_MSG_BLACKHOLE,3,0,0,PRIM,"MSG_BLACKHOLE","MSG_BLACKHOLE")
-{ foreign "C" barf("MSG_BLACKHOLE object (%p) entered!", R1) never returns; }
+{ ccall pbarf("MSG_BLACKHOLE object (%p) entered!", R1 "ptr") never returns; }
// used to overwrite a MSG_THROWTO when the message has been used/revoked
INFO_TABLE_CONSTR(stg_MSG_NULL,1,0,0,PRIM,"MSG_NULL","MSG_NULL")
-{ foreign "C" barf("MSG_NULL object (%p) entered!", R1) never returns; }
+{ ccall pbarf("MSG_NULL object (%p) entered!", R1 "ptr") never returns; }
INFO_TABLE_CONSTR(stg_MSG_CLONE_STACK,3,0,0,PRIM,"MSG_CLONE_STACK","MSG_CLONE_STACK")
-{ foreign "C" barf("stg_MSG_CLONE_STACK object (%p) entered!", R1) never returns; }
+{ ccall pbarf("stg_MSG_CLONE_STACK object (%p) entered!", R1 "ptr") never returns; }
/* ----------------------------------------------------------------------------
END_TSO_QUEUE
@@ -867,7 +867,7 @@ INFO_TABLE_CONSTR(stg_MSG_CLONE_STACK,3,0,0,PRIM,"MSG_CLONE_STACK","MSG_CLONE_ST
------------------------------------------------------------------------- */
INFO_TABLE_CONSTR(stg_END_TSO_QUEUE,0,0,0,CONSTR_NOCAF,"END_TSO_QUEUE","END_TSO_QUEUE")
-{ foreign "C" barf("END_TSO_QUEUE object (%p) entered!", R1) never returns; }
+{ ccall pbarf("END_TSO_QUEUE object (%p) entered!", R1 "ptr") never returns; }
CLOSURE(stg_END_TSO_QUEUE_closure,stg_END_TSO_QUEUE);
@@ -876,7 +876,7 @@ CLOSURE(stg_END_TSO_QUEUE_closure,stg_END_TSO_QUEUE);
------------------------------------------------------------------------- */
INFO_TABLE_CONSTR(stg_GCD_CAF,0,0,0,CONSTR_NOCAF,"GCD_CAF","GCD_CAF")
-{ foreign "C" barf("Evaluated a CAF (%p) that was GC'd!", R1) never returns; }
+{ ccall pbarf("Evaluated a CAF (%p) that was GC'd!", R1 "ptr") never returns; }
/* ----------------------------------------------------------------------------
STM_AWOKEN
@@ -886,7 +886,7 @@ INFO_TABLE_CONSTR(stg_GCD_CAF,0,0,0,CONSTR_NOCAF,"GCD_CAF","GCD_CAF")
------------------------------------------------------------------------- */
INFO_TABLE_CONSTR(stg_STM_AWOKEN,0,0,0,CONSTR_NOCAF,"STM_AWOKEN","STM_AWOKEN")
-{ foreign "C" barf("STM_AWOKEN object (%p) entered!", R1) never returns; }
+{ ccall pbarf("STM_AWOKEN object (%p) entered!", R1 "ptr") never returns; }
CLOSURE(stg_STM_AWOKEN_closure,stg_STM_AWOKEN);
@@ -906,40 +906,40 @@ CLOSURE(stg_STM_AWOKEN_closure,stg_STM_AWOKEN);
------------------------------------------------------------------------- */
INFO_TABLE(stg_ARR_WORDS, 0, 0, ARR_WORDS, "ARR_WORDS", "ARR_WORDS")
-{ foreign "C" barf("ARR_WORDS object (%p) entered!", R1) never returns; }
+{ ccall pbarf("ARR_WORDS object (%p) entered!", R1 "ptr") never returns; }
INFO_TABLE(stg_MUT_ARR_PTRS_CLEAN, 0, 0, MUT_ARR_PTRS_CLEAN, "MUT_ARR_PTRS_CLEAN", "MUT_ARR_PTRS_CLEAN")
-{ foreign "C" barf("MUT_ARR_PTRS_CLEAN object (%p) entered!", R1) never returns; }
+{ ccall pbarf("MUT_ARR_PTRS_CLEAN object (%p) entered!", R1 "ptr") never returns; }
INFO_TABLE(stg_MUT_ARR_PTRS_DIRTY, 0, 0, MUT_ARR_PTRS_DIRTY, "MUT_ARR_PTRS_DIRTY", "MUT_ARR_PTRS_DIRTY")
-{ foreign "C" barf("MUT_ARR_PTRS_DIRTY object (%p) entered!", R1) never returns; }
+{ ccall pbarf("MUT_ARR_PTRS_DIRTY object (%p) entered!", R1 "ptr") never returns; }
INFO_TABLE(stg_MUT_ARR_PTRS_FROZEN_CLEAN, 0, 0, MUT_ARR_PTRS_FROZEN_CLEAN, "MUT_ARR_PTRS_FROZEN_CLEAN", "MUT_ARR_PTRS_FROZEN_CLEAN")
-{ foreign "C" barf("MUT_ARR_PTRS_FROZEN_CLEAN object (%p) entered!", R1) never returns; }
+{ ccall pbarf("MUT_ARR_PTRS_FROZEN_CLEAN object (%p) entered!", R1 "ptr") never returns; }
INFO_TABLE(stg_MUT_ARR_PTRS_FROZEN_DIRTY, 0, 0, MUT_ARR_PTRS_FROZEN_DIRTY, "MUT_ARR_PTRS_FROZEN_DIRTY", "MUT_ARR_PTRS_FROZEN_DIRTY")
-{ foreign "C" barf("MUT_ARR_PTRS_FROZEN_DIRTY object (%p) entered!", R1) never returns; }
+{ ccall pbarf("MUT_ARR_PTRS_FROZEN_DIRTY object (%p) entered!", R1 "ptr") never returns; }
INFO_TABLE(stg_SMALL_MUT_ARR_PTRS_CLEAN, 0, 0, SMALL_MUT_ARR_PTRS_CLEAN, "SMALL_MUT_ARR_PTRS_CLEAN", "SMALL_MUT_ARR_PTRS_CLEAN")
-{ foreign "C" barf("SMALL_MUT_ARR_PTRS_CLEAN object (%p) entered!", R1) never returns; }
+{ ccall pbarf("SMALL_MUT_ARR_PTRS_CLEAN object (%p) entered!", R1 "ptr") never returns; }
INFO_TABLE(stg_SMALL_MUT_ARR_PTRS_DIRTY, 0, 0, SMALL_MUT_ARR_PTRS_DIRTY, "SMALL_MUT_ARR_PTRS_DIRTY", "SMALL_MUT_ARR_PTRS_DIRTY")
-{ foreign "C" barf("SMALL_MUT_ARR_PTRS_DIRTY object (%p) entered!", R1) never returns; }
+{ ccall pbarf("SMALL_MUT_ARR_PTRS_DIRTY object (%p) entered!", R1 "ptr") never returns; }
INFO_TABLE(stg_SMALL_MUT_ARR_PTRS_FROZEN_CLEAN, 0, 0, SMALL_MUT_ARR_PTRS_FROZEN_CLEAN, "SMALL_MUT_ARR_PTRS_FROZEN_CLEAN", "SMALL_MUT_ARR_PTRS_FROZEN_CLEAN")
-{ foreign "C" barf("SMALL_MUT_ARR_PTRS_FROZEN_CLEAN object (%p) entered!", R1) never returns; }
+{ ccall pbarf("SMALL_MUT_ARR_PTRS_FROZEN_CLEAN object (%p) entered!", R1 "ptr") never returns; }
INFO_TABLE(stg_SMALL_MUT_ARR_PTRS_FROZEN_DIRTY, 0, 0, SMALL_MUT_ARR_PTRS_FROZEN_DIRTY, "SMALL_MUT_ARR_PTRS_FROZEN_DIRTY", "SMALL_MUT_ARR_PTRS_FROZEN_DIRTY")
-{ foreign "C" barf("SMALL_MUT_ARR_PTRS_FROZEN_DIRTY object (%p) entered!", R1) never returns; }
+{ ccall pbarf("SMALL_MUT_ARR_PTRS_FROZEN_DIRTY object (%p) entered!", R1 "ptr") never returns; }
/* ----------------------------------------------------------------------------
Mutable Variables
------------------------------------------------------------------------- */
INFO_TABLE(stg_MUT_VAR_CLEAN, 1, 0, MUT_VAR_CLEAN, "MUT_VAR_CLEAN", "MUT_VAR_CLEAN")
-{ foreign "C" barf("MUT_VAR_CLEAN object (%p) entered!", R1) never returns; }
+{ ccall pbarf("MUT_VAR_CLEAN object (%p) entered!", R1 "ptr") never returns; }
INFO_TABLE(stg_MUT_VAR_DIRTY, 1, 0, MUT_VAR_DIRTY, "MUT_VAR_DIRTY", "MUT_VAR_DIRTY")
-{ foreign "C" barf("MUT_VAR_DIRTY object (%p) entered!", R1) never returns; }
+{ ccall pbarf("MUT_VAR_DIRTY object (%p) entered!", R1 "ptr") never returns; }
/* ----------------------------------------------------------------------------
Dummy return closure
@@ -961,7 +961,7 @@ CLOSURE(stg_dummy_ret_closure,stg_dummy_ret);
------------------------------------------------------------------------- */
INFO_TABLE_CONSTR(stg_MVAR_TSO_QUEUE,2,0,0,PRIM,"MVAR_TSO_QUEUE","MVAR_TSO_QUEUE")
-{ foreign "C" barf("MVAR_TSO_QUEUE object (%p) entered!", R1) never returns; }
+{ ccall pbarf("MVAR_TSO_QUEUE object (%p) entered!", R1 "ptr") never returns; }
/* ----------------------------------------------------------------------------
COMPACT_NFDATA (a blob of data in NF with no outgoing pointers)
@@ -974,11 +974,11 @@ INFO_TABLE_CONSTR(stg_MVAR_TSO_QUEUE,2,0,0,PRIM,"MVAR_TSO_QUEUE","MVAR_TSO_QUEUE
INFO_TABLE( stg_COMPACT_NFDATA_CLEAN, 0, 9, COMPACT_NFDATA, "COMPACT_NFDATA", "COMPACT_NFDATA")
()
-{ foreign "C" barf("COMPACT_NFDATA_CLEAN object (%p) entered!", R1) never returns; }
+{ ccall pbarf("COMPACT_NFDATA_CLEAN object (%p) entered!", R1 "ptr") never returns; }
INFO_TABLE( stg_COMPACT_NFDATA_DIRTY, 0, 9, COMPACT_NFDATA, "COMPACT_NFDATA", "COMPACT_NFDATA")
()
-{ foreign "C" barf("COMPACT_NFDATA_DIRTY object (%p) entered!", R1) never returns; }
+{ ccall pbarf("COMPACT_NFDATA_DIRTY object (%p) entered!", R1 "ptr") never returns; }
/* ----------------------------------------------------------------------------
ClosureTable element null value
@@ -988,7 +988,7 @@ INFO_TABLE( stg_COMPACT_NFDATA_DIRTY, 0, 9, COMPACT_NFDATA, "COMPACT_NFDATA", "C
------------------------------------------------------------------------- */
INFO_TABLE_CONSTR(stg_CLOSURE_TABLE_NULL,0,0,0,CONSTR_NOCAF,"CLOSURE_TABLE_NULL","CLOSURE_TABLE_NULL")
-{ foreign "C" barf("CLOSURE_TABLE_NULL object (%p) entered!", R1) never returns; }
+{ ccall pbarf("CLOSURE_TABLE_NULL object (%p) entered!", R1 "ptr") never returns; }
CLOSURE(stg_CLOSURE_TABLE_NULL_closure,stg_CLOSURE_TABLE_NULL);
@@ -1003,10 +1003,10 @@ INFO_TABLE_CONSTR(stg_TIMEOUT_QUEUE,
stg_TIMEOUT_QUEUE_NUM_PTRS,
stg_TIMEOUT_QUEUE_NUM_NONPTRS,
0,MUT_PRIM,"TIMEOUT_QUEUE","TIMEOUT_QUEUE")
-{ foreign "C" barf("TIMEOUT_QUEUE object (%p) entered!", R1) never returns; }
+{ ccall pbarf("TIMEOUT_QUEUE object (%p) entered!", R1 "ptr") never returns; }
INFO_TABLE_CONSTR(stg_TIMEOUT_QUEUE_EMPTY,0,0,0,CONSTR_NOCAF,"TIMEOUT_QUEUE_EMPTY","TIMEOUT_QUEUE_EMPTY")
-{ foreign "C" barf("TIMEOUT_QUEUE_EMPTY object (%p) entered!", R1) never returns; }
+{ ccall pbarf("TIMEOUT_QUEUE_EMPTY object (%p) entered!", R1 "ptr") never returns; }
CLOSURE(stg_TIMEOUT_QUEUE_EMPTY_closure,stg_TIMEOUT_QUEUE_EMPTY);
@@ -1022,9 +1022,9 @@ INFO_TABLE_CONSTR(stg_ASYNCIOOP,
stg_ASYNCIOOP_NUM_PTRS,
stg_ASYNCIOOP_NUM_NONPTRS,
0,PRIM,"ASYNCIOOP","ASYNCIOOP")
-{ foreign "C" barf("ASYNCIOOP object (%p) entered!", R1) never returns; }
+{ ccall pbarf("ASYNCIOOP object (%p) entered!", R1 "ptr") never returns; }
INFO_TABLE_CONSTR(stg_ASYNCIO_LIVE0,0,0,0,CONSTR_NOCAF,"ASYNCIO_LIVE0","ASYNCIO_LIVE0")
-{ foreign "C" barf("ASYNCIO_LIVE0 object (%p) entered!", R1) never returns; }
+{ ccall pbarf("ASYNCIO_LIVE0 object (%p) entered!", R1 "ptr") never returns; }
CLOSURE(stg_ASYNCIO_LIVE0_closure,stg_ASYNCIO_LIVE0);
=====================================
rts/StgStartup.cmm
=====================================
@@ -178,5 +178,5 @@ INFO_TABLE_RET(stg_forceIO, RET_SMALL, P_ info_ptr)
/* Called when compiled with -falignment-sanitisation on alignment failure */
stg_badAlignment_entry
{
- foreign "C" barf("stg_badAlignment_entry", NULL);
+ ccall sbarf("stg_badAlignment_entry") never returns;
}
=====================================
rts/include/rts/Messages.h
=====================================
@@ -37,6 +37,18 @@ void barf(const char *s, ...)
void vbarf(const char *s, va_list ap)
STG_NORETURN;
+/* Non-variadic wrapper around barf(), used by the code generator. */
+void sbarf(const char *s)
+ STG_NORETURN;
+
+/* Non-variadic wrapper around barf() for a format string and one pointer. */
+void pbarf(const char *fmt, void *p)
+ STG_NORETURN;
+
+/* Non-variadic wrapper around barf() for a format string and one string. */
+void ssbarf(const char *fmt, const char *s)
+ STG_NORETURN;
+
// declared in Rts.h:
// extern void _assertFail(const char *filename, unsigned int linenum)
// STG_NORETURN;
=====================================
testsuite/tests/simplStg/should_compile/all.T
=====================================
@@ -19,8 +19,6 @@ test('T22840', [extra_files(
[ 'T22840A.hs'
, 'T22840B.hs'
]),
- # barf signature mismatch on wasm32 due to -dtag-inference-checks
- when(arch('wasm32'), skip),
when(not(have_dynamic()),skip)], multimod_compile, ['T22840', '-dynamic-too -dtag-inference-checks'])
test('inferTags003', [ only_ways(['optasm']),
grep_errmsg(r'(call stg\_ap\_0)', [1])
=====================================
utils/genapply/Main.hs
=====================================
@@ -79,7 +79,7 @@ in a conditional. For example, stg_stk_save_v32 looks like:
V32_[Sp+WDS(3)] = YMM1;
...
#else
- foreign "C" barf("stg_stk_save_v32: unsupported vector register", NULL) never returns;
+ ccall sbarf("stg_stk_save_v32: unsupported vector register") never returns;
#endif
}
@@ -344,7 +344,7 @@ vecsCpp fun regs code =
, text "#if" <+> cond ]
++ code
++ [ text "#else //" <+> cond
- , text "foreign \"C\" barf(\"" <> fun <> text ": unsupported vector register\", NULL) never returns;"
+ , text "ccall sbarf(\"" <> fun <> text ": unsupported vector register\") never returns;"
, text "#endif //" <+> cond
]
@@ -1049,7 +1049,7 @@ genApply targetInfo args =
text "default: {",
nest 4 (
- text "foreign \"C\" barf(\"" <> fun_ret_label <> text "\", NULL) never returns;"
+ text "ccall sbarf(\"" <> fun_ret_label <> text "\") never returns;"
),
text "}"
View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/1ca4b49a561447222072a44320fa9b0b...
--
View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/1ca4b49a561447222072a44320fa9b0b...
You're receiving this email because of your account on gitlab.haskell.org.