mirror of
https://github.com/nim-lang/Nim.git
synced 2026-01-06 04:57:49 +00:00
* fixes #10807 * use nkAddr instead of nkHiddenAddr
This commit is contained in:
@@ -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
|
||||
@@ -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)
|
||||
|
||||
@@ -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:
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
Reference in New Issue
Block a user