[Git][ghc/ghc][master] compiler/rts: fix ABI mismatch in barf() invocations
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 <codex@openai.com> - - - - - 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.
participants (1)
-
Marge Bot (@marge-bot)