Skip to content

Commit 39317bf

Browse files
authored
sem: replace addr calls with nkAddr (#1465)
## Summary In typed AST, address-of operations are now *always* represented by `nkAddr` trees. This simplifies some compiler logic, makes processing for typed macros easier, and fixes an effect tracking bug with `addr`. ## Details This is effectively a revert of nim-lang/Nim#10814. Not turning calls to `mAddr` into `nkAddr` was done to prevent the unsafe address semantics from being lost, but those no longer exist. Lowering the call into an `nkAddr` tree has the benefit that it simplifies AST analysis and processing, as address-of operation can now always be detected by `PNode.kind == nkAddr`. Old code for detecting `mAddr` magic calls is removed. The effect tracking in `sempass2` had no special case for `mAddr` calls, thus treating them as normal calls, which led to `addr(x)` being treated as an indirect invocation of `x`, when `x` is of procedural type. With the `mAddr` call now being lowered earlier, this is no longer the case.
1 parent c61e95b commit 39317bf

File tree

7 files changed

+25
-23
lines changed

7 files changed

+25
-23
lines changed

compiler/ast/astalgo.nim

Lines changed: 2 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -599,13 +599,8 @@ proc iiTablePut(t: var TIITable, key, val: int) =
599599
iiTableRawInsert(t.data, key, val)
600600
inc(t.counter)
601601

602-
proc isAddrNode*(n: PNode): bool =
603-
case n.kind
604-
of nkAddr, nkHiddenAddr: true
605-
of nkCallKinds:
606-
if n[0].kind == nkSym and n[0].sym.magic == mAddr: true
607-
else: false
608-
else: false
602+
func isAddrNode*(n: PNode): bool =
603+
n.kind in {nkAddr, nkHiddenAddr}
609604

610605
proc listSymbolNames*(symbols: openArray[PSym]): string =
611606
for sym in symbols:

compiler/sem/semexprs.nim

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2814,9 +2814,7 @@ proc semMagic(c: PContext, n: PNode, s: PSym, flags: TExprFlags): PNode =
28142814
of mAddr:
28152815
markUsed(c, n.info, s)
28162816
checkSonsLen(n, 2, c.config)
2817-
result[0] = newSymNode(s, n[0].info)
2818-
result[1] = semAddrArg(c, n[1])
2819-
result.typ = makePtrType(c, result[1].typ)
2817+
result = semAddrCall(c, n)
28202818
of mTypeOf:
28212819
markUsed(c, n.info, s)
28222820
result = semTypeOf(c, n)

compiler/sem/semmagic.nim

Lines changed: 11 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,15 @@ proc semAddrArg(c: PContext; n: PNode): PNode =
2424
else:
2525
result = newError(c.config, n, PAstDiag(kind: adSemExprHasNoAddress))
2626

27+
proc semAddrCall(c: PContext, n: PNode): PNode =
28+
## Analyzes a well-formed call of the ``system.addr`` procedure (`n`),
29+
## returning either an error or an ``nkAddr`` expression.
30+
result = newTreeI(nkAddr, n.info, semAddrArg(c, n[1]))
31+
if result[0].kind == nkError:
32+
result = c.config.wrapError(result)
33+
else:
34+
result.typ = makePtrType(c, result[0].typ)
35+
2736
proc semTypeOf(c: PContext; n: PNode): PNode =
2837
addInNimDebugUtils(c.config, "semTypeOf", n, result)
2938
var m = BiggestInt 1 # typeOfIter
@@ -421,11 +430,9 @@ proc magicsAfterOverloadResolution(c: PContext, n: PNode,
421430

422431
case n[0].sym.magic
423432
of mAddr:
424-
# XXX: wasn't this magic already processed in ``semMagic``?
433+
# 'addr' was overloaded, hence ``semMagic`` not handling the magic already
425434
checkSonsLen(n, 2, c.config)
426-
result = n
427-
result[1] = semAddrArg(c, n[1])
428-
result.typ = makePtrType(c, result[1].typ)
435+
result = semAddrCall(c, n)
429436
of mTypeOf:
430437
result = semTypeOf(c, n)
431438
of mSizeOf:

compiler/sem/sempass2.nim

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1143,8 +1143,6 @@ proc allowCStringConv(n: PNode): bool =
11431143
of nkStrLiterals: result = true
11441144
of nkSym: result = n.sym.kind in {skConst, skParam}
11451145
of nkAddr: result = isCharArrayPtr(n.typ, true)
1146-
of nkCallKinds:
1147-
result = isCharArrayPtr(n.typ, n[0].kind == nkSym and n[0].sym.magic == mAddr)
11481146
else: result = isCharArrayPtr(n.typ, false)
11491147

11501148
proc reportErrors(c: ConfigRef, n: PNode) =

compiler/sem/transf.nim

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1110,9 +1110,6 @@ proc transformCall(c: PTransf, n: PNode): PNode =
11101110
inc(j)
11111111
result.add(a)
11121112
if result.len == 2: result = result[1]
1113-
elif magic == mAddr:
1114-
result = newTreeIT(nkAddr, n.info, n.typ): n[1]
1115-
result = transformAddr(c, result)
11161113
elif magic == mTypeOf:
11171114
result = n
11181115
elif magic == mRunnableExamples:

tests/effects/teffects11.nim

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
discard """
2+
description: '''
3+
Taking the address of a location storing a procedural value does not
4+
incur the procedure's effects.
5+
'''
6+
action: compile
7+
"""
8+
9+
proc p() {.raises: [].} =
10+
var a: proc() {.raises: ValueError.}
11+
discard addr(a)

tests/lang_callable/macros/tmacrostmt.nim

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -114,8 +114,6 @@ proc fn6() =
114114

115115
#------------------------------------
116116
# bug #10807
117-
proc fn_unsafeaddr(x: int): int =
118-
cast[int](unsafeAddr(x))
119117

120118
static:
121119
let fn1s = "proc fn1(x, y: int): int =\n result = 2 * (x + y)\n"
@@ -124,15 +122,13 @@ static:
124122
let fn4s = "proc fn4(x: int): int =\n if x mod 2 == 0:\n return x + 2\n else:\n return 0\n"
125123
let fn5s = "proc fn5(a, b: float): float =\n result = -a * a / (b * b)\n"
126124
let fn6s = "proc fn6() =\n var a = @[1.0, 2.0]\n let z = a{0, 1}\n a{2} = 5.0\n"
127-
let fnAddr = "proc fn_unsafeaddr(x: int): int =\n result = cast[int](unsafeAddr(x))\n"
128125

129126
doAssert fn1.repr_to_string == fn1s
130127
doAssert fn2.repr_to_string == fn2s
131128
doAssert fn3.repr_to_string == fn3s
132129
doAssert fn4.repr_to_string == fn4s
133130
doAssert fn5.repr_to_string == fn5s
134131
doAssert fn6.repr_to_string == fn6s
135-
doAssert fn_unsafeaddr.repr_to_string == fnAddr
136132

137133
#------------------------------------
138134
# bug #8763

0 commit comments

Comments
 (0)