summary refs log tree commit diff stats
diff options
context:
space:
mode:
authorAraq <rumpf_a@web.de>2016-12-30 00:59:10 +0100
committerAraq <rumpf_a@web.de>2016-12-30 00:59:10 +0100
commit4104ee121dc08b50b90bf9ce3b62740b60244673 (patch)
tree30f75f3aeb761f422892d7ed51aa91fcac351c37
parent700c024e1366b3478934237e27ead75009ac0c41 (diff)
downloadNim-4104ee121dc08b50b90bf9ce3b62740b60244673.tar.gz
fixes #5147
-rw-r--r--compiler/sighashes.nim32
-rw-r--r--tests/ccgbugs/tsighash_typename_regression.nim10
2 files changed, 35 insertions, 7 deletions
diff --git a/compiler/sighashes.nim b/compiler/sighashes.nim
index 145d3ff5a..fd2f444a6 100644
--- a/compiler/sighashes.nim
+++ b/compiler/sighashes.nim
@@ -82,6 +82,13 @@ else:
     result = 0
     for x in 0..3:
       result = (result shl 8) or u.MD5Digest[x].int
+type
+  ConsiderFlag* = enum
+    CoProc
+    CoType
+    CoOwnerSig
+
+proc hashType(c: var MD5Context, t: PType; flags: set[ConsiderFlag])
 
 proc hashSym(c: var MD5Context, s: PSym) =
   if sfAnon in s.flags or s.kind == skGenericParam:
@@ -93,6 +100,19 @@ proc hashSym(c: var MD5Context, s: PSym) =
       c &= "."
       it = it.owner
 
+proc hashTypeSym(c: var MD5Context, s: PSym) =
+  if sfAnon in s.flags or s.kind == skGenericParam:
+    c &= ":anon"
+  else:
+    var it = s
+    while it != nil:
+      if sfFromGeneric in it.flags and it.kind in routineKinds and
+          it.typ != nil:
+        hashType c, it.typ, {CoProc}
+      c &= it.name.s
+      c &= "."
+      it = it.owner
+
 proc hashTree(c: var MD5Context, n: PNode) =
   if n == nil:
     c &= "\255"
@@ -118,11 +138,6 @@ proc hashTree(c: var MD5Context, n: PNode) =
   else:
     for i in 0.. <n.len: hashTree(c, n.sons[i])
 
-type
-  ConsiderFlag* = enum
-    CoProc
-    CoType
-
 proc hashType(c: var MD5Context, t: PType; flags: set[ConsiderFlag]) =
   if t == nil:
     c &= "\254"
@@ -163,7 +178,10 @@ proc hashType(c: var MD5Context, t: PType; flags: set[ConsiderFlag]) =
       #  writeStackTrace()
       #  echo "yes ", t.sym.name.s
       #  #quit 1
-      c.hashSym(t.sym)
+      if CoOwnerSig in flags:
+        c.hashTypeSym(t.sym)
+      else:
+        c.hashSym(t.sym)
       if sfAnon in t.sym.flags:
         # generated object names can be identical, so we need to
         # disambiguate furthermore by hashing the field types and names:
@@ -246,7 +264,7 @@ when defined(debugSigHashes):
 proc hashType*(t: PType; flags: set[ConsiderFlag] = {CoType}): SigHash =
   var c: MD5Context
   md5Init c
-  hashType c, t, flags
+  hashType c, t, flags+{CoOwnerSig}
   md5Final c, result.Md5Digest
   when defined(debugSigHashes):
     db.exec(sql"INSERT OR IGNORE INTO sighashes(type, hash) VALUES (?, ?)",
diff --git a/tests/ccgbugs/tsighash_typename_regression.nim b/tests/ccgbugs/tsighash_typename_regression.nim
new file mode 100644
index 000000000..7122902d9
--- /dev/null
+++ b/tests/ccgbugs/tsighash_typename_regression.nim
@@ -0,0 +1,10 @@
+# bug #5147
+
+proc foo[T](t: T) =
+  type Wrapper = object
+    get: T
+  let w = Wrapper(get: t)
+  echo w.get
+
+foo(123)
+foo("baz")