mirror of
https://github.com/nim-lang/Nim.git
synced 2026-04-06 07:38:24 +00:00
The `enforcenoraises` pragma prevents generation of exception checking code for atomic... functions when compiling with Microsoft Visual C++ as backend. Fixes #25445 Without this change, the following test program: ```nim import std/sysatomics var x: ptr uint64 = cast[ptr uint64](uint64(0)) var y: ptr uint64 = cast[ptr uint64](uint64(42)) let z = atomicExchangeN(addr x, y, ATOMIC_ACQ_REL) let a = atomicCompareExchangeN(addr x, addr y, y, true, ATOMIC_ACQ_REL, ATOMIC_ACQ_REL) var v = 42 atomicStoreN(addr v, 43, ATOMIC_ACQ_REL) let w = atomicLoadN(addr v, ATOMIC_ACQ_REL) ``` ... generates this C code when compiling with `--cc:vcc`: ```c N_LIB_PRIVATE N_NIMCALL(void, NimMainModule)(void) { { NU64* T1_; NIM_BOOL T2_; NI T3_; NIM_BOOL* nimErr_; nimfr_("testexcept", "/tmp/testexcept.nim"); nimErr_ = nimErrorFlag(); nimlf_(7, "/tmp/testexcept.nim");T1_ = ((NU64*) 0); T1_ = atomicExchangeN__testexcept_u4((&x__testexcept_u2), y__testexcept_u3, ((int) 4)); if (NIM_UNLIKELY((*nimErr_))) { goto BeforeRet_; } z__testexcept_u32 = T1_; nimln_(9);T2_ = ((NIM_BOOL) 0); T2_ = atomicCompareExchangeN__testexcept_u33((&x__testexcept_u2), (&y__testexcept_u3), y__testexcept_u3, NIM_TRUE, ((int) 4), ((int) 4)); if (NIM_UNLIKELY((*nimErr_))) { goto BeforeRet_; } a__testexcept_u45 = T2_; nimln_(12);atomicStoreN__testexcept_u47(((&v__testexcept_u46)), ((NI) 43)); if (NIM_UNLIKELY((*nimErr_))) { goto BeforeRet_; } nimln_(13);T3_ = ((NI) 0); T3_ = atomicLoadN__testexcept_u53(((&v__testexcept_u46))); if (NIM_UNLIKELY((*nimErr_))) { goto BeforeRet_; } w__testexcept_u59 = T3_; BeforeRet_: ; nimTestErrorFlag(); popFrame(); } } ``` Note the repeated checks for `*nimErr_`. With this PR applied, the checks vanish: ```c N_LIB_PRIVATE N_NIMCALL(void, NimMainModule)(void) { { nimfr_("testexcept", "/tmp/testexcept.nim"); nimlf_(7, "/tmp/testexcept.nim");z__testexcept_u32 = atomicExchangeN__testexcept_u4((&x__testexcept_u2), y__testexcept_u3, ((int) 4)); nimln_(9);a__testexcept_u45 = atomicCompareExchangeN__testexcept_u33((&x__testexcept_u2), (&y__testexcept_u3), y__testexcept_u3, NIM_TRUE, ((int) 4), ((int) 4)); nimln_(12);atomicStoreN__testexcept_u47(((&v__testexcept_u46)), ((NI) 43)); nimln_(13);w__testexcept_u59 = atomicLoadN__testexcept_u53(((&v__testexcept_u46))); nimTestErrorFlag(); popFrame(); } } ``` For reference, with gcc as backend the generated code looks as follows: ```c N_LIB_PRIVATE N_NIMCALL(void, NimMainModule)(void) { { nimfr_("testexcept", "/tmp/testexcept.nim"); nimlf_(7, "/tmp/testexcept.nim");z__testexcept_u9 = __atomic_exchange_n((&x__testexcept_u2), y__testexcept_u3, __ATOMIC_ACQ_REL); nimln_(9);a__testexcept_u18 = __atomic_compare_exchange_n((&x__testexcept_u2), (&y__testexcept_u3), y__testexcept_u3, NIM_TRUE, __ATOMIC_ACQ_REL, __ATOMIC_ACQ_REL); nimln_(12);__atomic_store_n(((&v__testexcept_u19)), ((NI) 43), __ATOMIC_ACQ_REL); nimln_(13);w__testexcept_u29 = __atomic_load_n(((&v__testexcept_u19)), __ATOMIC_ACQ_REL); nimTestErrorFlag(); popFrame(); } } ``` With this PR the program from #25445 yields the correct output `Error: unhandled exception: index 4 not in 0 .. 3 [IndexDefect]` instead of crashing with a SIGSEGV. PS: Unfortunately, I did not find out how to run the tests with MSVC. `./koch tests --cc:vcc` doesn't use MSVC.