diff options
-rw-r--r-- | compiler/ccgexprs.nim | 4 | ||||
-rw-r--r-- | compiler/ccgstmts.nim | 6 | ||||
-rw-r--r-- | compiler/ccgtypes.nim | 38 | ||||
-rw-r--r-- | compiler/cgen.nim | 2 | ||||
-rw-r--r-- | compiler/injectdestructors.nim | 2 | ||||
-rw-r--r-- | compiler/jsgen.nim | 4 | ||||
-rw-r--r-- | compiler/liftdestructors.nim | 4 | ||||
-rw-r--r-- | compiler/pathutils.nim | 51 | ||||
-rw-r--r-- | compiler/sighashes.nim | 86 | ||||
-rw-r--r-- | compiler/vm.nim | 2 | ||||
-rw-r--r-- | tests/ccgbugs/m1/defs.nim | 4 | ||||
-rw-r--r-- | tests/ccgbugs/m2/defs.nim | 4 | ||||
-rw-r--r-- | tests/ccgbugs/t20139.nim | 10 |
13 files changed, 143 insertions, 74 deletions
diff --git a/compiler/ccgexprs.nim b/compiler/ccgexprs.nim index f428324b7..a64a42219 100644 --- a/compiler/ccgexprs.nim +++ b/compiler/ccgexprs.nim @@ -1704,7 +1704,7 @@ proc genNewFinalize(p: BProc, e: PNode) = proc genOfHelper(p: BProc; dest: PType; a: Rope; info: TLineInfo; result: var Rope) = if optTinyRtti in p.config.globalOptions: - let token = $genDisplayElem(MD5Digest(hashType(dest))) + let token = $genDisplayElem(MD5Digest(hashType(dest, p.config))) appcg(p.module, result, "#isObjDisplayCheck($#.m_type, $#, $#)", [a, getObjDepth(dest), token]) else: # unfortunately 'genTypeInfoV1' sets tfObjHasKids as a side effect, so we @@ -2779,7 +2779,7 @@ proc upConv(p: BProc, n: PNode, d: var TLoc) = rdMType(p, a, nilCheck, r) if optTinyRtti in p.config.globalOptions: let checkFor = $getObjDepth(dest) - let token = $genDisplayElem(MD5Digest(hashType(dest))) + let token = $genDisplayElem(MD5Digest(hashType(dest, p.config))) if nilCheck != "": linefmt(p, cpsStmts, "if ($1 && !#isObjDisplayCheck($2, $3, $4)){ #raiseObjectConversionError(); ", [nilCheck, r, checkFor, token]) diff --git a/compiler/ccgstmts.nim b/compiler/ccgstmts.nim index db839b21b..7ade85b42 100644 --- a/compiler/ccgstmts.nim +++ b/compiler/ccgstmts.nim @@ -1081,7 +1081,7 @@ proc genTryCpp(p: BProc, t: PNode, d: var TLoc) = let memberName = if p.module.compileToCpp: "m_type" else: "Sup.m_type" if optTinyRtti in p.config.globalOptions: let checkFor = $getObjDepth(typeNode.typ) - appcg(p.module, orExpr, "#isObjDisplayCheck(#nimBorrowCurrentException()->$1, $2, $3)", [memberName, checkFor, $genDisplayElem(MD5Digest(hashType(typeNode.typ)))]) + appcg(p.module, orExpr, "#isObjDisplayCheck(#nimBorrowCurrentException()->$1, $2, $3)", [memberName, checkFor, $genDisplayElem(MD5Digest(hashType(typeNode.typ, p.config)))]) else: let checkFor = genTypeInfoV1(p.module, typeNode.typ, typeNode.info) appcg(p.module, orExpr, "#isObj(#nimBorrowCurrentException()->$1, $2)", [memberName, checkFor]) @@ -1300,7 +1300,7 @@ proc genTryGoto(p: BProc; t: PNode; d: var TLoc) = let memberName = if p.module.compileToCpp: "m_type" else: "Sup.m_type" if optTinyRtti in p.config.globalOptions: let checkFor = $getObjDepth(t[i][j].typ) - appcg(p.module, orExpr, "#isObjDisplayCheck(#nimBorrowCurrentException()->$1, $2, $3)", [memberName, checkFor, $genDisplayElem(MD5Digest(hashType(t[i][j].typ)))]) + appcg(p.module, orExpr, "#isObjDisplayCheck(#nimBorrowCurrentException()->$1, $2, $3)", [memberName, checkFor, $genDisplayElem(MD5Digest(hashType(t[i][j].typ, p.config)))]) else: let checkFor = genTypeInfoV1(p.module, t[i][j].typ, t[i][j].info) appcg(p.module, orExpr, "#isObj(#nimBorrowCurrentException()->$1, $2)", [memberName, checkFor]) @@ -1445,7 +1445,7 @@ proc genTrySetjmp(p: BProc, t: PNode, d: var TLoc) = let memberName = if p.module.compileToCpp: "m_type" else: "Sup.m_type" if optTinyRtti in p.config.globalOptions: let checkFor = $getObjDepth(t[i][j].typ) - appcg(p.module, orExpr, "#isObjDisplayCheck(#nimBorrowCurrentException()->$1, $2, $3)", [memberName, checkFor, $genDisplayElem(MD5Digest(hashType(t[i][j].typ)))]) + appcg(p.module, orExpr, "#isObjDisplayCheck(#nimBorrowCurrentException()->$1, $2, $3)", [memberName, checkFor, $genDisplayElem(MD5Digest(hashType(t[i][j].typ, p.config)))]) else: let checkFor = genTypeInfoV1(p.module, t[i][j].typ, t[i][j].info) appcg(p.module, orExpr, "#isObj(#nimBorrowCurrentException()->$1, $2)", [memberName, checkFor]) diff --git a/compiler/ccgtypes.nim b/compiler/ccgtypes.nim index e7677f2f2..98c1fc55f 100644 --- a/compiler/ccgtypes.nim +++ b/compiler/ccgtypes.nim @@ -43,14 +43,14 @@ proc fillBackendName(m: BModule; s: PSym) = result.add rope s.itemId.item if m.hcrOn: result.add "_" - result.add(idOrSig(s, m.module.name.s.mangle, m.sigConflicts)) + result.add(idOrSig(s, m.module.name.s.mangle, m.sigConflicts, m.config)) s.loc.r = result writeMangledName(m.ndi, s, m.config) proc fillParamName(m: BModule; s: PSym) = if s.loc.r == "": var res = s.name.s.mangle - res.add idOrSig(s, res, m.sigConflicts) + res.add idOrSig(s, res, m.sigConflicts, m.config) # Take into account if HCR is on because of the following scenario: # if a module gets imported and it has some more importc symbols in it, # some param names might receive the "_0" suffix to distinguish from what @@ -302,7 +302,7 @@ proc getSimpleTypeDesc(m: BModule, typ: PType): Rope = else: result = "" if result != "" and typ.isImportedType(): - let sig = hashType typ + let sig = hashType(typ, m.config) if cacheGetType(m.typeCache, sig) == "": m.typeCache[sig] = result @@ -362,10 +362,10 @@ proc getTypeDescWeak(m: BModule; t: PType; check: var IntSet; kind: TSymKind): R if isImportedCppType(etB) and t.kind == tyGenericInst: result = getTypeDescAux(m, t, check, kind) else: - result = getTypeForward(m, t, hashType(t)) + result = getTypeForward(m, t, hashType(t, m.config)) pushType(m, t) of tySequence: - let sig = hashType(t) + let sig = hashType(t, m.config) if optSeqDestructors in m.config.globalOptions: if skipTypes(etB[0], typedescInst).kind == tyEmpty: internalError(m.config, "cannot map the empty seq type to a C type") @@ -398,7 +398,7 @@ proc getSeqPayloadType(m: BModule; t: PType): Rope = #result = getTypeForward(m, t, hashType(t)) & "_Content" proc seqV2ContentType(m: BModule; t: PType; check: var IntSet) = - let sig = hashType(t) + let sig = hashType(t, m.config) let result = cacheGetType(m.typeCache, sig) if result == "": discard getTypeDescAux(m, t, check, skVar) @@ -664,7 +664,7 @@ proc resolveStarsInCppType(typ: PType, idx, stars: int): PType = else: result.elemType proc getOpenArrayDesc(m: BModule, t: PType, check: var IntSet; kind: TSymKind): Rope = - let sig = hashType(t) + let sig = hashType(t, m.config) if kind == skParam: result = getTypeDescWeak(m, t[0], check, kind) & "*" else: @@ -688,7 +688,7 @@ proc getTypeDescAux(m: BModule, origTyp: PType, check: var IntSet; kind: TSymKin # C type generation into an analysis and a code generation phase somehow. if t.sym != nil: useHeader(m, t.sym) if t != origTyp and origTyp.sym != nil: useHeader(m, origTyp.sym) - let sig = hashType(origTyp) + let sig = hashType(origTyp, m.config) defer: # defer is the simplest in this case if isImportedType(t) and not m.typeABICache.containsOrIncl(sig): @@ -717,7 +717,7 @@ proc getTypeDescAux(m: BModule, origTyp: PType, check: var IntSet; kind: TSymKin result = getTypeDescAux(m, et, check, kind) & star else: # no restriction! We have a forward declaration for structs - let name = getTypeForward(m, et, hashType et) + let name = getTypeForward(m, et, hashType(et, m.config)) result = name & star m.typeCache[sig] = result of tySequence: @@ -726,7 +726,7 @@ proc getTypeDescAux(m: BModule, origTyp: PType, check: var IntSet; kind: TSymKin m.typeCache[sig] = result else: # no restriction! We have a forward declaration for structs - let name = getTypeForward(m, et, hashType et) + let name = getTypeForward(m, et, hashType(et, m.config)) result = name & seqStar(m) & star m.typeCache[sig] = result pushType(m, et) @@ -893,7 +893,7 @@ proc getTypeDescAux(m: BModule, origTyp: PType, check: var IntSet; kind: TSymKin # Don't use the imported name as it may be scoped: 'Foo::SomeKind' result = rope("tySet_") t.lastSon.typeName(result) - result.add $t.lastSon.hashType + result.add $t.lastSon.hashType(m.config) m.typeCache[sig] = result if not isImportedType(t): let s = int(getSize(m.config, t)) @@ -1066,7 +1066,7 @@ proc discriminatorTableName(m: BModule, objtype: PType, d: PSym): Rope = objtype = objtype[0].skipTypes(abstractPtrs) if objtype.sym == nil: internalError(m.config, d.info, "anonymous obj with discriminator") - result = "NimDT_$1_$2" % [rope($hashType(objtype)), rope(d.name.s.mangle)] + result = "NimDT_$1_$2" % [rope($hashType(objtype, m.config)), rope(d.name.s.mangle)] proc rope(arg: Int128): Rope = rope($arg) @@ -1285,7 +1285,7 @@ proc genTypeInfo2Name(m: BModule; t: PType): Rope = result.add m.name.s & "." result.add it.sym.name.s else: - result = $hashType(it) + result = $hashType(it, m.config) result = makeCString(result) proc isTrivialProc(g: ModuleGraph; s: PSym): bool {.inline.} = getBody(g, s).len == 0 @@ -1329,14 +1329,14 @@ proc genDisplayElem(d: MD5Digest): uint32 = result += uint32(d[i]) result = result shl 8 -proc genDisplay(t: PType, depth: int): Rope = +proc genDisplay(m: BModule, t: PType, depth: int): Rope = result = Rope"{" var x = t var seqs = newSeq[string](depth+1) var i = 0 while x != nil: x = skipTypes(x, skipPtrs) - seqs[i] = $genDisplayElem(MD5Digest(hashType(x))) + seqs[i] = $genDisplayElem(MD5Digest(hashType(x, m.config))) x = x[0] inc i @@ -1376,7 +1376,7 @@ proc genTypeInfoV2OldImpl(m: BModule; t, origType: PType, name: Rope; info: TLin [name, getTypeDesc(m, t), rope(objDepth), rope(flags)]) if objDepth >= 0: - let objDisplay = genDisplay(t, objDepth) + let objDisplay = genDisplay(m, t, objDepth) let objDisplayStore = getTempName(m) m.s[cfsVars].addf("static $1 $2[$3] = $4;$n", [getTypeDesc(m, getSysType(m.g.graph, unknownLineInfo, tyUInt32), skVar), objDisplayStore, rope(objDepth+1), objDisplay]) addf(typeEntry, "$1.display = $2;$n", [name, rope(objDisplayStore)]) @@ -1408,7 +1408,7 @@ proc genTypeInfoV2Impl(m: BModule; t, origType: PType, name: Rope; info: TLineIn [getTypeDesc(m, t), rope(objDepth)]) if objDepth >= 0: - let objDisplay = genDisplay(t, objDepth) + let objDisplay = genDisplay(m, t, objDepth) let objDisplayStore = getTempName(m) m.s[cfsVars].addf("static NIM_CONST $1 $2[$3] = $4;$n", [getTypeDesc(m, getSysType(m.g.graph, unknownLineInfo, tyUInt32), skVar), objDisplayStore, rope(objDepth+1), objDisplay]) addf(typeEntry, ", .display = $1", [rope(objDisplayStore)]) @@ -1435,7 +1435,7 @@ proc genTypeInfoV2(m: BModule, t: PType; info: TLineInfo): Rope = let prefixTI = if m.hcrOn: "(" else: "(&" - let sig = hashType(origType) + let sig = hashType(origType, m.config) result = m.typeInfoMarkerV2.getOrDefault(sig) if result != "": return prefixTI.rope & result & ")".rope @@ -1509,7 +1509,7 @@ proc genTypeInfoV1(m: BModule, t: PType; info: TLineInfo): Rope = let prefixTI = if m.hcrOn: "(" else: "(&" - let sig = hashType(origType) + let sig = hashType(origType, m.config) result = m.typeInfoMarker.getOrDefault(sig) if result != "": return prefixTI.rope & result & ")".rope diff --git a/compiler/cgen.nim b/compiler/cgen.nim index c346a0b78..ab6e6559f 100644 --- a/compiler/cgen.nim +++ b/compiler/cgen.nim @@ -1630,7 +1630,7 @@ proc registerModuleToMain(g: BModuleList; m: BModule) = hcrModuleMeta.addf("\t\"\"};$n", []) hcrModuleMeta.addf("$nN_LIB_EXPORT N_NIMCALL(void**, HcrGetImportedModules)() { return (void**)hcr_module_list; }$n", []) hcrModuleMeta.addf("$nN_LIB_EXPORT N_NIMCALL(char*, HcrGetSigHash)() { return \"$1\"; }$n$n", - [($sigHash(m.module)).rope]) + [($sigHash(m.module, m.config)).rope]) if sfMainModule in m.module.flags: g.mainModProcs.add(hcrModuleMeta) g.mainModProcs.addf("static void* hcr_handle;$N", []) diff --git a/compiler/injectdestructors.nim b/compiler/injectdestructors.nim index 13141b765..d58f28289 100644 --- a/compiler/injectdestructors.nim +++ b/compiler/injectdestructors.nim @@ -217,7 +217,7 @@ proc genOp(c: var Con; t: PType; kind: TTypeAttachedOp; dest, ri: PNode): PNode var op = getAttachedOp(c.graph, t, kind) if op == nil or op.ast.isGenericRoutine: # give up and find the canonical type instead: - let h = sighashes.hashType(t, {CoType, CoConsiderOwned, CoDistinct}) + let h = sighashes.hashType(t, c.graph.config, {CoType, CoConsiderOwned, CoDistinct}) let canon = c.graph.canonTypes.getOrDefault(h) if canon != nil: op = getAttachedOp(c.graph, canon, kind) diff --git a/compiler/jsgen.nim b/compiler/jsgen.nim index 572d19b13..6619963b0 100644 --- a/compiler/jsgen.nim +++ b/compiler/jsgen.nim @@ -262,7 +262,7 @@ proc mangleName(m: BModule, s: PSym): Rope = if m.config.hcrOn: # When hot reloading is enabled, we must ensure that the names # of functions and types will be preserved across rebuilds: - result.add(idOrSig(s, m.module.name.s, m.sigConflicts)) + result.add(idOrSig(s, m.module.name.s, m.sigConflicts, m.config)) else: result.add("_") result.add(rope(s.id)) @@ -2813,7 +2813,7 @@ proc genModule(p: PProc, n: PNode) = if p.config.hcrOn and n.kind == nkStmtList: let moduleSym = p.module.module var moduleLoadedVar = rope(moduleSym.name.s) & "_loaded" & - idOrSig(moduleSym, moduleSym.name.s, p.module.sigConflicts) + idOrSig(moduleSym, moduleSym.name.s, p.module.sigConflicts, p.config) lineF(p, "var $1;$n", [moduleLoadedVar]) var inGuardedBlock = false diff --git a/compiler/liftdestructors.nim b/compiler/liftdestructors.nim index c7464d39e..d7b1f2daa 100644 --- a/compiler/liftdestructors.nim +++ b/compiler/liftdestructors.nim @@ -553,7 +553,7 @@ proc useSeqOrStrOp(c: var TLiftCtx; t: PType; body, x, y: PNode) = # operation here: var t = t if t.assignment == nil or t.destructor == nil: - let h = sighashes.hashType(t, {CoType, CoConsiderOwned, CoDistinct}) + let h = sighashes.hashType(t,c.g.config, {CoType, CoConsiderOwned, CoDistinct}) let canon = c.g.canonTypes.getOrDefault(h) if canon != nil: t = canon @@ -1113,7 +1113,7 @@ proc createTypeBoundOps(g: ModuleGraph; c: PContext; orig: PType; info: TLineInf let skipped = orig.skipTypes({tyGenericInst, tyAlias, tySink}) if isEmptyContainer(skipped) or skipped.kind == tyStatic: return - let h = sighashes.hashType(skipped, {CoType, CoConsiderOwned, CoDistinct}) + let h = sighashes.hashType(skipped, g.config, {CoType, CoConsiderOwned, CoDistinct}) var canon = g.canonTypes.getOrDefault(h) if canon == nil: g.canonTypes[h] = skipped diff --git a/compiler/pathutils.nim b/compiler/pathutils.nim index 1ef0143d5..d9779deab 100644 --- a/compiler/pathutils.nim +++ b/compiler/pathutils.nim @@ -10,7 +10,7 @@ ## Path handling utilities for Nim. Strictly typed code in order ## to avoid the never ending time sink in getting path handling right. -import os, pathnorm +import os, pathnorm, strutils when defined(nimPreviewSlimSystem): import std/[syncio, assertions] @@ -102,3 +102,52 @@ when true: proc addFileExt*(x: RelativeFile; ext: string): RelativeFile {.borrow.} proc writeFile*(x: AbsoluteFile; content: string) {.borrow.} + +proc skipHomeDir(x: string): int = + when defined(windows): + if x.continuesWith("Users/", len("C:/")): + result = 3 + else: + result = 0 + else: + if x.startsWith("/home/") or x.startsWith("/Users/"): + result = 3 + elif x.startsWith("/mnt/") and x.continuesWith("/Users/", len("/mnt/c")): + result = 5 + else: + result = 0 + +proc relevantPart(s: string; afterSlashX: int): string = + result = newStringOfCap(s.len - 8) + var slashes = afterSlashX + for i in 0..<s.len: + if slashes == 0: + result.add s[i] + elif s[i] == '/': + dec slashes + +template canonSlashes(x: string): string = + when defined(windows): + x.replace('\\', '/') + else: + x + +proc customPathImpl(x: string): string = + # Idea: Encode a "protocol" via "//protocol/path" which is not ambiguous + # as path canonicalization would have removed the double slashes. + # /mnt/X/Users/Y + # X:\\Users\Y + # /home/Y + # --> + # //user/ + if not isAbsolute(x): + result = customPathImpl(canonSlashes(getCurrentDir() / x)) + else: + let slashes = skipHomeDir(x) + if slashes > 0: + result = "//user/" & relevantPart(x, slashes) + else: + result = x + +proc customPath*(x: string): string = + customPathImpl canonSlashes x diff --git a/compiler/sighashes.nim b/compiler/sighashes.nim index 3508a146a..7e2a0b660 100644 --- a/compiler/sighashes.nim +++ b/compiler/sighashes.nim @@ -9,10 +9,12 @@ ## Computes hash values for routine (proc, method etc) signatures. -import ast, tables, ropes, md5, modulegraphs +import ast, tables, ropes, md5, modulegraphs, options, msgs, packages, pathutils from hashes import Hash import types +import std/os + when defined(nimPreviewSlimSystem): import std/assertions @@ -42,8 +44,7 @@ type CoDistinct CoHashTypeInsideNode -proc hashType(c: var MD5Context, t: PType; flags: set[ConsiderFlag]) - +proc hashType(c: var MD5Context, t: PType; flags: set[ConsiderFlag]; conf: ConfigRef) proc hashSym(c: var MD5Context, s: PSym) = if sfAnon in s.flags or s.kind == skGenericParam: c &= ":anon" @@ -54,20 +55,21 @@ proc hashSym(c: var MD5Context, s: PSym) = c &= "." it = it.owner -proc hashTypeSym(c: var MD5Context, s: PSym) = +proc hashTypeSym(c: var MD5Context, s: PSym; conf: ConfigRef) = if sfAnon in s.flags or s.kind == skGenericParam: c &= ":anon" else: var it = s + c &= customPath(conf.toFullPath(s.info)) while it != nil: if sfFromGeneric in it.flags and it.kind in routineKinds and it.typ != nil: - hashType c, it.typ, {CoProc} + hashType c, it.typ, {CoProc}, conf c &= it.name.s c &= "." it = it.owner -proc hashTree(c: var MD5Context, n: PNode; flags: set[ConsiderFlag]) = +proc hashTree(c: var MD5Context, n: PNode; flags: set[ConsiderFlag]; conf: ConfigRef) = if n == nil: c &= "\255" return @@ -82,7 +84,7 @@ proc hashTree(c: var MD5Context, n: PNode; flags: set[ConsiderFlag]) = of nkSym: hashSym(c, n.sym) if CoHashTypeInsideNode in flags and n.sym.typ != nil: - hashType(c, n.sym.typ, flags) + hashType(c, n.sym.typ, flags, conf) of nkCharLit..nkUInt64Lit: let v = n.intVal lowlevel v @@ -92,9 +94,9 @@ proc hashTree(c: var MD5Context, n: PNode; flags: set[ConsiderFlag]) = of nkStrLit..nkTripleStrLit: c &= n.strVal else: - for i in 0..<n.len: hashTree(c, n[i], flags) + for i in 0..<n.len: hashTree(c, n[i], flags, conf) -proc hashType(c: var MD5Context, t: PType; flags: set[ConsiderFlag]) = +proc hashType(c: var MD5Context, t: PType; flags: set[ConsiderFlag]; conf: ConfigRef) = if t == nil: c &= "\254" return @@ -102,14 +104,14 @@ proc hashType(c: var MD5Context, t: PType; flags: set[ConsiderFlag]) = case t.kind of tyGenericInvocation: for i in 0..<t.len: - c.hashType t[i], flags + c.hashType t[i], flags, conf of tyDistinct: if CoDistinct in flags: if t.sym != nil: c.hashSym(t.sym) if t.sym == nil or tfFromGeneric in t.flags: - c.hashType t.lastSon, flags + c.hashType t.lastSon, flags, conf elif CoType in flags or t.sym == nil: - c.hashType t.lastSon, flags + c.hashType t.lastSon, flags, conf else: c.hashSym(t.sym) of tyGenericInst: @@ -119,15 +121,15 @@ proc hashType(c: var MD5Context, t: PType; flags: set[ConsiderFlag]) = # value for each instantiation, so we hash the generic parameters here: let normalizedType = t.skipGenericAlias for i in 0..<normalizedType.len - 1: - c.hashType t[i], flags + c.hashType t[i], flags, conf else: - c.hashType t.lastSon, flags + c.hashType t.lastSon, flags, conf of tyAlias, tySink, tyUserTypeClasses, tyInferred: - c.hashType t.lastSon, flags + c.hashType t.lastSon, flags, conf of tyOwned: if CoConsiderOwned in flags: c &= char(t.kind) - c.hashType t.lastSon, flags + c.hashType t.lastSon, flags, conf of tyBool, tyChar, tyInt..tyUInt64: # no canonicalization for integral types, so that e.g. ``pid_t`` is # produced instead of ``NI``: @@ -141,7 +143,7 @@ proc hashType(c: var MD5Context, t: PType; flags: set[ConsiderFlag]) = t.typeInst = nil assert inst.kind == tyGenericInst for i in 0..<inst.len - 1: - c.hashType inst[i], flags + c.hashType inst[i], flags, conf t.typeInst = inst return c &= char(t.kind) @@ -153,7 +155,7 @@ proc hashType(c: var MD5Context, t: PType; flags: set[ConsiderFlag]) = # The user has set a specific name for this type c &= t.sym.loc.r elif CoOwnerSig in flags: - c.hashTypeSym(t.sym) + c.hashTypeSym(t.sym, conf) else: c.hashSym(t.sym) @@ -172,7 +174,7 @@ proc hashType(c: var MD5Context, t: PType; flags: set[ConsiderFlag]) = # xxx instead, use a hash table to indicate we've already visited a type, which # would also be more efficient. symWithFlags.flags.excl {sfAnon, sfGenSym} - hashTree(c, t.n, flags + {CoHashTypeInsideNode}) + hashTree(c, t.n, flags + {CoHashTypeInsideNode}, conf) symWithFlags.flags = oldFlags else: # The object has no fields: we _must_ add something here in order to @@ -182,15 +184,15 @@ proc hashType(c: var MD5Context, t: PType; flags: set[ConsiderFlag]) = else: c &= t.id if t.len > 0 and t[0] != nil: - hashType c, t[0], flags + hashType c, t[0], flags, conf of tyRef, tyPtr, tyGenericBody, tyVar: c &= char(t.kind) if t.sons.len > 0: - c.hashType t.lastSon, flags + c.hashType t.lastSon, flags, conf if tfVarIsPtr in t.flags: c &= ".varisptr" of tyFromExpr: c &= char(t.kind) - c.hashTree(t.n, {}) + c.hashTree(t.n, {}, conf) of tyTuple: c &= char(t.kind) if t.n != nil and CoType notin flags: @@ -199,19 +201,19 @@ proc hashType(c: var MD5Context, t: PType; flags: set[ConsiderFlag]) = assert(t.n[i].kind == nkSym) c &= t.n[i].sym.name.s c &= ':' - c.hashType(t[i], flags+{CoIgnoreRange}) + c.hashType(t[i], flags+{CoIgnoreRange}, conf) c &= ',' else: - for i in 0..<t.len: c.hashType t[i], flags+{CoIgnoreRange} + for i in 0..<t.len: c.hashType t[i], flags+{CoIgnoreRange}, conf of tyRange: if CoIgnoreRange notin flags: c &= char(t.kind) - c.hashTree(t.n, {}) - c.hashType(t[0], flags) + c.hashTree(t.n, {}, conf) + c.hashType(t[0], flags, conf) of tyStatic: c &= char(t.kind) - c.hashTree(t.n, {}) - c.hashType(t[0], flags) + c.hashTree(t.n, {}, conf) + c.hashType(t[0], flags, conf) of tyProc: c &= char(t.kind) c &= (if tfIterator in t.flags: "iterator " else: "proc ") @@ -221,11 +223,11 @@ proc hashType(c: var MD5Context, t: PType; flags: set[ConsiderFlag]) = let param = params[i].sym c &= param.name.s c &= ':' - c.hashType(param.typ, flags) + c.hashType(param.typ, flags, conf) c &= ',' - c.hashType(t[0], flags) + c.hashType(t[0], flags, conf) else: - for i in 0..<t.len: c.hashType(t[i], flags) + for i in 0..<t.len: c.hashType(t[i], flags, conf) c &= char(t.callConv) # purity of functions doesn't have to affect the mangling (which is in fact # problematic for HCR - someone could have cached a pointer to another @@ -237,10 +239,10 @@ proc hashType(c: var MD5Context, t: PType; flags: set[ConsiderFlag]) = if tfVarargs in t.flags: c &= ".varargs" of tyArray: c &= char(t.kind) - for i in 0..<t.len: c.hashType(t[i], flags-{CoIgnoreRange}) + for i in 0..<t.len: c.hashType(t[i], flags-{CoIgnoreRange}, conf) else: c &= char(t.kind) - for i in 0..<t.len: c.hashType(t[i], flags) + for i in 0..<t.len: c.hashType(t[i], flags, conf) if tfNotNil in t.flags and CoType notin flags: c &= "not nil" when defined(debugSigHashes): @@ -257,19 +259,19 @@ when defined(debugSigHashes): # select hash, type from sighashes where hash in # (select hash from sighashes group by hash having count(*) > 1) order by hash; -proc hashType*(t: PType; flags: set[ConsiderFlag] = {CoType}): SigHash = +proc hashType*(t: PType; conf: ConfigRef; flags: set[ConsiderFlag] = {CoType}): SigHash = var c: MD5Context md5Init c - hashType c, t, flags+{CoOwnerSig} + hashType c, t, flags+{CoOwnerSig}, conf md5Final c, result.MD5Digest when defined(debugSigHashes): db.exec(sql"INSERT OR IGNORE INTO sighashes(type, hash) VALUES (?, ?)", typeToString(t), $result) -proc hashProc*(s: PSym): SigHash = +proc hashProc*(s: PSym; conf: ConfigRef): SigHash = var c: MD5Context md5Init c - hashType c, s.typ, {CoProc} + hashType c, s.typ, {CoProc}, conf var m = s while m.kind != skModule: m = m.owner @@ -315,9 +317,9 @@ proc hashOwner*(s: PSym): SigHash = md5Final c, result.MD5Digest -proc sigHash*(s: PSym): SigHash = +proc sigHash*(s: PSym; conf: ConfigRef): SigHash = if s.kind in routineKinds and s.typ != nil: - result = hashProc(s) + result = hashProc(s, conf) else: result = hashNonProc(s) @@ -378,7 +380,7 @@ proc symBodyDigest*(graph: ModuleGraph, sym: PSym): SigHash = var c: MD5Context md5Init(c) - c.hashType(sym.typ, {CoProc}) + c.hashType(sym.typ, {CoProc}, graph.config) c &= char(sym.kind) c.md5Final(result.MD5Digest) graph.symBodyHashes[sym.id] = result # protect from recursion in the body @@ -391,12 +393,12 @@ proc symBodyDigest*(graph: ModuleGraph, sym: PSym): SigHash = graph.symBodyHashes[sym.id] = result proc idOrSig*(s: PSym, currentModule: string, - sigCollisions: var CountTable[SigHash]): Rope = + sigCollisions: var CountTable[SigHash]; conf: ConfigRef): Rope = if s.kind in routineKinds and s.typ != nil: # signatures for exported routines are reliable enough to # produce a unique name and this means produced C++ is more stable regarding # Nim changes: - let sig = hashProc(s) + let sig = hashProc(s, conf) result = rope($sig) #let m = if s.typ.callConv != ccInline: findPendingModule(m, s) else: m let counter = sigCollisions.getOrDefault(sig) diff --git a/compiler/vm.nim b/compiler/vm.nim index 38b856277..18d840613 100644 --- a/compiler/vm.nim +++ b/compiler/vm.nim @@ -1855,7 +1855,7 @@ proc rawExecute(c: PCtx, start: int, tos: PStackFrame): TFullReg = if regs[rb].node.kind != nkSym: stackTrace(c, tos, pc, "node is not a symbol") else: - regs[ra].node.strVal = $sigHash(regs[rb].node.sym) + regs[ra].node.strVal = $sigHash(regs[rb].node.sym, c.config) of opcSlurp: decodeB(rkNode) createStr regs[ra] diff --git a/tests/ccgbugs/m1/defs.nim b/tests/ccgbugs/m1/defs.nim new file mode 100644 index 000000000..ed78d8b72 --- /dev/null +++ b/tests/ccgbugs/m1/defs.nim @@ -0,0 +1,4 @@ +type MyObj* = object + field1*: int + s*: string + ch*: char diff --git a/tests/ccgbugs/m2/defs.nim b/tests/ccgbugs/m2/defs.nim new file mode 100644 index 000000000..798d1fea8 --- /dev/null +++ b/tests/ccgbugs/m2/defs.nim @@ -0,0 +1,4 @@ +type MyObj* = object + s*: string + field1*: int + ch*: char diff --git a/tests/ccgbugs/t20139.nim b/tests/ccgbugs/t20139.nim new file mode 100644 index 000000000..4592b994d --- /dev/null +++ b/tests/ccgbugs/t20139.nim @@ -0,0 +1,10 @@ +discard """ + joinable: false +""" + +# bug #20139 +import m1/defs as md1 +import m2/defs as md2 + +doAssert $(md1.MyObj(field1: 1)) == """(field1: 1, s: "", ch: '\x00')""" +doAssert $(md2.MyObj(field1: 1)) == """(s: "", field1: 1, ch: '\x00')""" |