From ec713a1d39dcc6bf6df6a18214777be0d2888c7a Mon Sep 17 00:00:00 2001 From: zerbina <100542850+zerbina@users.noreply.github.com> Date: Sun, 4 Aug 2024 03:31:18 +0200 Subject: [PATCH] fix a compiler crash with `.varargs` proc types (#1396) ## Summary Fix the compiler crashing when a non-closure `proc` type with C-style varargs is used somewhere. Only the C backend was affected. Fixes https://github.com/nim-works/nimskull/issues/1394. ## Details * `mirtypes.callConv` didn't consider the `x` field storing a boolean value in the most-significant bit, resulting in range defect * the integer value is now properly masked before converting it to a `TCallingConvention` enum value --- compiler/mir/mirtypes.nim | 7 +++++-- tests/ccgbugs/tvarargs_proc_type.nim | 10 ++++++++++ 2 files changed, 15 insertions(+), 2 deletions(-) create mode 100644 tests/ccgbugs/tvarargs_proc_type.nim diff --git a/compiler/mir/mirtypes.nim b/compiler/mir/mirtypes.nim index bccc5ce4547..f8791ffd585 100644 --- a/compiler/mir/mirtypes.nim +++ b/compiler/mir/mirtypes.nim @@ -183,6 +183,8 @@ const MangleFlag = 0x4000'u16 NoAliasFlag = 0x8000'u16 + VarargsFlag = 0x8000_0000'u32 + func `==`*(a, b: FieldId): bool {.borrow, inline.} func `==`(a, b: IntVal): bool {.borrow, inline.} @@ -359,10 +361,11 @@ func numParams*(desc: TypeHeader): int = int(desc.b - desc.a) - 1 func callConv*(desc: TypeHeader, env: TypeEnv): TCallingConvention = - TCallingConvention env.params[desc.a].x + # mask away the varargs flag + TCallingConvention(env.params[desc.a].x and not(VarargsFlag)) func hasVarargs*(desc: TypeHeader, env: TypeEnv): bool = - (env.params[desc.a].x and 0x8000_0000'u32) != 0 + (env.params[desc.a].x and VarargsFlag) != 0 func retType*(desc: TypeHeader, env: TypeEnv): TypeId = assert desc.kind in {tkProc, tkClosure} diff --git a/tests/ccgbugs/tvarargs_proc_type.nim b/tests/ccgbugs/tvarargs_proc_type.nim new file mode 100644 index 00000000000..7fc815cfa51 --- /dev/null +++ b/tests/ccgbugs/tvarargs_proc_type.nim @@ -0,0 +1,10 @@ +discard """ + description: ''' + Regression test for a bug with querying the calling convention of a MIR + type. Derived from https://github.com/nim-works/nimskull/issues/1394. + ''' +""" + +# calling convention doesn't matter, as long as the proc type is not a closure +# type +var p: proc(x: int) {.nimcall, varargs.}