summary refs log tree commit diff stats
diff options
context:
space:
mode:
authorAndreas Rumpf <rumpf_a@web.de>2018-09-15 12:55:23 +0200
committerGitHub <noreply@github.com>2018-09-15 12:55:23 +0200
commit4342b79a3c05fcfb1e6fc97152daa0075b0b9603 (patch)
tree6e1d377dbcdf67e4dbc6003a97f37c5094485e64
parent4c347871071541d4e01f8d2c3a0593e84454219c (diff)
parent6af6ca6351f29d180f86a8521cf2f46f0e6934a7 (diff)
downloadNim-4342b79a3c05fcfb1e6fc97152daa0075b0b9603.tar.gz
Merge pull request #8971 from LemonBoy/fix-8967
Fix codegen for set[T] parameters
-rw-r--r--compiler/ccgexprs.nim3
-rw-r--r--compiler/ccgtypes.nim15
-rw-r--r--tests/ccgbugs/t8967.nim10
3 files changed, 20 insertions, 8 deletions
diff --git a/compiler/ccgexprs.nim b/compiler/ccgexprs.nim
index 56ecf5ba3..a7a28a51c 100644
--- a/compiler/ccgexprs.nim
+++ b/compiler/ccgexprs.nim
@@ -1596,10 +1596,11 @@ proc genSwap(p: BProc, e: PNode, d: var TLoc) =
   genAssignment(p, a, b, {})
   genAssignment(p, b, tmp, {})
 
-proc rdSetElemLoc(conf: ConfigRef; a: TLoc, setType: PType): Rope =
+proc rdSetElemLoc(conf: ConfigRef; a: TLoc, typ: PType): Rope =
   # read a location of an set element; it may need a subtraction operation
   # before the set operation
   result = rdCharLoc(a)
+  let setType = typ.skipTypes(abstractPtrs)
   assert(setType.kind == tySet)
   if firstOrd(conf, setType) != 0:
     result = "($1- $2)" % [result, rope(firstOrd(conf, setType))]
diff --git a/compiler/ccgtypes.nim b/compiler/ccgtypes.nim
index dd79f4846..52a4a72f2 100644
--- a/compiler/ccgtypes.nim
+++ b/compiler/ccgtypes.nim
@@ -162,9 +162,9 @@ proc mapType(conf: ConfigRef; typ: PType): TCTypeKind =
     var base = skipTypes(typ.lastSon, typedescInst)
     case base.kind
     of tyOpenArray, tyArray, tyVarargs: result = ctPtrToArray
-    #of tySet:
-    #  if mapSetType(base) == ctArray: result = ctPtrToArray
-    #  else: result = ctPtr
+    of tySet:
+      if mapSetType(conf, base) == ctArray: result = ctPtrToArray
+      else: result = ctPtr
     # XXX for some reason this breaks the pegs module
     else: result = ctPtr
   of tyPointer: result = ctPtr
@@ -641,10 +641,11 @@ proc getTypeDescAux(m: BModule, origTyp: PType, check: var IntSet): Rope =
                     compileToCpp(m): "&" else: "*"
     var et = origTyp.skipTypes(abstractInst).lastSon
     var etB = et.skipTypes(abstractInst)
-    if etB.kind in {tyArray, tyOpenArray, tyVarargs}:
-      # this is correct! sets have no proper base type, so we treat
-      # ``var set[char]`` in `getParamTypeDesc`
-      et = elemType(etB)
+    if mapType(m.config, t) == ctPtrToArray:
+      if etB.kind == tySet:
+        et = getSysType(m.g.graph, unknownLineInfo(), tyUInt8)
+      else:
+        et = elemType(etB)
       etB = et.skipTypes(abstractInst)
       star[0] = '*'
     case etB.kind
diff --git a/tests/ccgbugs/t8967.nim b/tests/ccgbugs/t8967.nim
new file mode 100644
index 000000000..e342b7eae
--- /dev/null
+++ b/tests/ccgbugs/t8967.nim
@@ -0,0 +1,10 @@
+discard """
+  targets: "c cpp"
+"""
+
+import marshal
+
+let orig: set[char] = {'A'..'Z'}
+let m = $$orig
+let old = to[set[char]](m)
+doAssert orig - old == {}