summary refs log tree commit diff stats
diff options
context:
space:
mode:
authorAraq <rumpf_a@web.de>2014-12-16 14:49:47 +0100
committerAraq <rumpf_a@web.de>2014-12-16 14:49:47 +0100
commit8be177627a15de6328d761c61ff52c25fcdb92c4 (patch)
treee85f83cdcf300f1373828cd354f81faee0d3ab4d
parent1293a8bca58130a4fd0b6b09d0ac5bf71c1f2b04 (diff)
downloadNim-8be177627a15de6328d761c61ff52c25fcdb92c4.tar.gz
fixes #1181, fixes #1715
-rw-r--r--compiler/ccgexprs.nim13
-rw-r--r--tests/converter/ttypeconverter1.nim7
2 files changed, 18 insertions, 2 deletions
diff --git a/compiler/ccgexprs.nim b/compiler/ccgexprs.nim
index 547d0d376..4a3be0027 100644
--- a/compiler/ccgexprs.nim
+++ b/compiler/ccgexprs.nim
@@ -658,7 +658,8 @@ proc unaryArith(p: BProc, e: PNode, d: var TLoc, op: TMagic) =
                     getSimpleTypeDesc(p.module, e.typ)]))
 
 proc genDeref(p: BProc, e: PNode, d: var TLoc; enforceDeref=false) =
-  if mapType(e.sons[0].typ) in {ctArray, ctPtrToArray} and not enforceDeref:
+  let mt = mapType(e.sons[0].typ)
+  if mt in {ctArray, ctPtrToArray} and not enforceDeref:
     # XXX the amount of hacks for C's arrays is incredible, maybe we should
     # simply wrap them in a struct? --> Losing auto vectorization then?
     #if e[0].kind != nkBracketExpr:
@@ -675,7 +676,15 @@ proc genDeref(p: BProc, e: PNode, d: var TLoc; enforceDeref=false) =
     of tyPtr:
       d.s = OnUnknown         # BUGFIX!
     else: internalError(e.info, "genDeref " & $a.t.kind)
-    putIntoDest(p, d, a.t.sons[0], ropef("(*$1)", [rdLoc(a)]))
+    if enforceDeref and mt == ctPtrToArray:
+      # we lie about the type for better C interop: 'ptr array[3,T]' is
+      # translated to 'ptr T', but for deref'ing this produces wrong code.
+      # See tmissingderef. So we get rid of the deref instead. The codegen
+      # ends up using 'memcpy' for the array assignment,
+      # so the '&' and '*' cancel out:
+      putIntoDest(p, d, a.t.sons[0], rdLoc(a))
+    else:
+      putIntoDest(p, d, a.t.sons[0], ropef("(*$1)", [rdLoc(a)]))
 
 proc genAddr(p: BProc, e: PNode, d: var TLoc) =
   # careful  'addr(myptrToArray)' needs to get the ampersand:
diff --git a/tests/converter/ttypeconverter1.nim b/tests/converter/ttypeconverter1.nim
index b9a5e88ae..fd3a0318a 100644
--- a/tests/converter/ttypeconverter1.nim
+++ b/tests/converter/ttypeconverter1.nim
@@ -1,3 +1,7 @@
+discard """
+  ouput: '''foo
+true'''
+"""
 
 converter p(i: int): bool = return i != 0
 
@@ -6,3 +10,6 @@ if 1:
 while 0: 
   echo "bar"
 
+var a: array[3, bool]
+a[0] = 3
+echo a[0]