mirror of
https://github.com/nim-lang/Nim.git
synced 2026-07-11 03:39:31 +00:00
fixes #25931; type N {.importc: "const void *".} = pointer creates order-dependent compilation failure (#25936)
fixes #25931 This fix addresses bug #25931 — a signature hash collision with importc-aliased pointer/cstring types. The problem: In compiler/sighashes.nim, the hashType procedure canonicalizes types for signature hashing. Integral types (tyInt..tyUInt64, etc.) were excluded from canonicalization so that types like pid_t (an importc alias) keep their backend spelling. But pointer and cstring types with importc annotations were not excluded — meaning a type like: type N {.importc: "const void *".} = pointer ...would be collapsed to just pointer in the signature hash, causing collisions when N and pointer are both used in procedure types within the same compilation unit. The fix (compiler/sighashes.nim:193): Adds tyPointer and tyCstring to the list of types that skip canonicalization, right alongside the integral types. The comment is updated to clarify this applies to "builtin scalar-ish / pointer-like types". The test (tests/ccgbugs/tsighash_typename_regression.nim:33-42): Adds a regression test exercising the exact scenario — an importc pointer alias used in both an object field type and a proc parameter type.
This commit is contained in:
@@ -190,9 +190,10 @@ proc hashType(c: var MD5Context, t: PType; flags: set[ConsiderFlag]; conf: Confi
|
||||
if CoConsiderOwned in flags:
|
||||
c &= char(t.kind)
|
||||
c.hashType t.skipModifier, flags, conf
|
||||
of tyBool, tyChar, tyInt..tyUInt64:
|
||||
# no canonicalization for integral types, so that e.g. ``pid_t`` is
|
||||
# produced instead of ``NI``:
|
||||
of tyBool, tyChar, tyPointer, tyCstring, tyInt..tyUInt64:
|
||||
# no canonicalization for builtin scalar-ish / pointer-like types, so
|
||||
# that e.g. ``pid_t`` or an imported ``pointer`` alias keep their
|
||||
# backend spelling instead of collapsing into the generic Nim builtin:
|
||||
c &= char(t.kind)
|
||||
if t.sym != nil and {sfImportc, sfExportc} * t.sym.flags != {}:
|
||||
c.hashSym(t.sym)
|
||||
@@ -533,4 +534,3 @@ proc idOrSig*(s: PSym, currentModule: string,
|
||||
if counter != 0:
|
||||
result.add "_" & rope(counter+1)
|
||||
sigCollisions.inc(sig)
|
||||
|
||||
|
||||
@@ -30,3 +30,13 @@ block:
|
||||
|
||||
var x = M(x: 1)
|
||||
doAssert(x.x == 1)
|
||||
|
||||
block: # bug #25931
|
||||
type
|
||||
N {.importc: "const void *".} = pointer
|
||||
S = object
|
||||
f: proc (_: N) {.cdecl.}
|
||||
#var _: proc (_: pointer) {.cdecl.}
|
||||
proc d(_: proc (_: pointer) {.cdecl.}) = discard
|
||||
discard S()
|
||||
d(proc (_: pointer) {.cdecl.} = discard)
|
||||
|
||||
Reference in New Issue
Block a user