* fixes  #10807
* use nkAddr instead of nkHiddenAddr
This commit is contained in:
cooldome
2019-03-12 12:45:05 +00:00
committed by Andreas Rumpf
parent ea3e18bc6c
commit 8ceba8a7f3
6 changed files with 34 additions and 9 deletions

View File

@@ -1001,3 +1001,11 @@ proc iiTablePut(t: var TIITable, key, val: int) =
swap(t.data, n)
iiTableRawInsert(t.data, key, val)
inc(t.counter)
proc isAddrNode*(n: PNode): bool =
case n.kind
of nkAddr, nkHiddenAddr: true
of nkCallKinds:
if n[0].kind == nkSym and n[0].sym.magic == mAddr: true
else: false
else: false

View File

@@ -2034,7 +2034,9 @@ proc semMagic(c: PContext, n: PNode, s: PSym, flags: TExprFlags): PNode =
case s.magic # magics that need special treatment
of mAddr:
checkSonsLen(n, 2, c.config)
result = semAddr(c, n.sons[1], s.name.s == "unsafeAddr")
result[0] = newSymNode(s, n[0].info)
result[1] = semAddrArg(c, n.sons[1], s.name.s == "unsafeAddr")
result.typ = makePtrType(c, result[1].typ)
of mTypeOf:
result = semTypeOf(c, n)
#of mArrGet: result = semArrGet(c, n, flags)
@@ -2579,7 +2581,8 @@ proc semExpr(c: PContext, n: PNode, flags: TExprFlags = {}): PNode =
of nkAddr:
result = n
checkSonsLen(n, 1, c.config)
result = semAddr(c, n.sons[0])
result[0] = semAddrArg(c, n.sons[0])
result.typ = makePtrType(c, result[0].typ)
of nkHiddenAddr, nkHiddenDeref:
checkSonsLen(n, 1, c.config)
n.sons[0] = semExpr(c, n.sons[0], flags)

View File

@@ -10,8 +10,7 @@
# This include file implements the semantic checking for magics.
# included from sem.nim
proc semAddr(c: PContext; n: PNode; isUnsafeAddr=false): PNode =
result = newNodeI(nkAddr, n.info)
proc semAddrArg(c: PContext; n: PNode; isUnsafeAddr = false): PNode =
let x = semExprWithType(c, n)
if x.kind == nkSym:
x.sym.flags.incl(sfAddrTaken)
@@ -22,8 +21,7 @@ proc semAddr(c: PContext; n: PNode; isUnsafeAddr=false): PNode =
localError(c.config, n.info, errExprHasNoAddress)
else:
localError(c.config, n.info, errExprHasNoAddress & "; maybe use 'unsafeAddr'")
result.add x
result.typ = makePtrType(c, x.typ)
result = x
proc semTypeOf(c: PContext; n: PNode): PNode =
var m = BiggestInt 1 # typeOfIter
@@ -335,7 +333,9 @@ proc magicsAfterOverloadResolution(c: PContext, n: PNode,
case n[0].sym.magic
of mAddr:
checkSonsLen(n, 2, c.config)
result = semAddr(c, n.sons[1], n[0].sym.name.s == "unsafeAddr")
result = n
result[1] = semAddrArg(c, n[1], n[0].sym.name.s == "unsafeAddr")
result.typ = makePtrType(c, result[1].typ)
of mTypeOf:
result = semTypeOf(c, n)
of mSizeOf:

View File

@@ -538,7 +538,7 @@ proc notNilCheck(tracked: PEffects, n: PNode, paramType: PType) =
let paramType = paramType.skipTypesOrNil(abstractInst)
if paramType != nil and tfNotNil in paramType.flags and
n.typ != nil and tfNotNil notin n.typ.flags:
if n.kind == nkAddr:
if isAddrNode(n):
# addr(x[]) can't be proven, but addr(x) can:
if not containsNode(n, {nkDerefExpr, nkHiddenDeref}): return
elif (n.kind == nkSym and n.sym.kind in routineKinds) or

View File

@@ -762,6 +762,10 @@ proc transformCall(c: PTransf, n: PNode): PTransNode =
inc(j)
add(result, a.PTransNode)
if len(result) == 2: result = result[1]
elif magic == mAddr:
result = newTransNode(nkAddr, n, 1)
result[0] = n[1].PTransNode
result = transformAddrDeref(c, result.PNode, nkDerefExpr, nkHiddenDeref)
elif magic in {mNBindSym, mTypeOf, mRunnableExamples}:
# for bindSym(myconst) we MUST NOT perform constant folding:
result = n.PTransNode

View File

@@ -91,14 +91,24 @@ proc fn2(x, y: float): float =
proc fn3(x, y: int): bool =
(((x and 3) div 4) or (x mod (y xor -1))) == 0 or y notin [1,2]
#------------------------------------
# bug #10807
proc fn_unsafeaddr(x: int): int =
cast[int](unsafeAddr(x))
static:
echo fn_unsafeaddr.repr_to_string
let fn1s = "proc fn1(x, y: int): int =\n result = 2 * (x + y)\n"
let fn2s = "proc fn2(x, y: float): float =\n result = (y + 2 * x) / (x - y)\n"
let fn3s = "proc fn3(x, y: int): bool =\n result = ((x and 3) div 4 or x mod (y xor -1)) == 0 or not contains([1, 2], y)\n"
let fnAddr = "proc fn_unsafeaddr(x: int): int =\n result = cast[int](unsafeAddr(x))\n"
doAssert fn1.repr_to_string == fn1s
doAssert fn2.repr_to_string == fn2s
doAssert fn3.repr_to_string == fn3s
doAssert fn_unsafeaddr.repr_to_string == fnAddr
#------------------------------------
# bug #8763