diff --git a/compiler/ast/astalgo.nim b/compiler/ast/astalgo.nim index 4d50c463972..25e6bd67286 100644 --- a/compiler/ast/astalgo.nim +++ b/compiler/ast/astalgo.nim @@ -599,13 +599,8 @@ proc iiTablePut(t: var TIITable, key, val: int) = 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 +func isAddrNode*(n: PNode): bool = + n.kind in {nkAddr, nkHiddenAddr} proc listSymbolNames*(symbols: openArray[PSym]): string = for sym in symbols: diff --git a/compiler/sem/semexprs.nim b/compiler/sem/semexprs.nim index 6544725ea80..d203ee09998 100644 --- a/compiler/sem/semexprs.nim +++ b/compiler/sem/semexprs.nim @@ -2814,9 +2814,7 @@ proc semMagic(c: PContext, n: PNode, s: PSym, flags: TExprFlags): PNode = of mAddr: markUsed(c, n.info, s) checkSonsLen(n, 2, c.config) - result[0] = newSymNode(s, n[0].info) - result[1] = semAddrArg(c, n[1]) - result.typ = makePtrType(c, result[1].typ) + result = semAddrCall(c, n) of mTypeOf: markUsed(c, n.info, s) result = semTypeOf(c, n) diff --git a/compiler/sem/semmagic.nim b/compiler/sem/semmagic.nim index 7c30b089356..9e2a2d0ff40 100644 --- a/compiler/sem/semmagic.nim +++ b/compiler/sem/semmagic.nim @@ -24,6 +24,15 @@ proc semAddrArg(c: PContext; n: PNode): PNode = else: result = newError(c.config, n, PAstDiag(kind: adSemExprHasNoAddress)) +proc semAddrCall(c: PContext, n: PNode): PNode = + ## Analyzes a well-formed call of the ``system.addr`` procedure (`n`), + ## returning either an error or an ``nkAddr`` expression. + result = newTreeI(nkAddr, n.info, semAddrArg(c, n[1])) + if result[0].kind == nkError: + result = c.config.wrapError(result) + else: + result.typ = makePtrType(c, result[0].typ) + proc semTypeOf(c: PContext; n: PNode): PNode = addInNimDebugUtils(c.config, "semTypeOf", n, result) var m = BiggestInt 1 # typeOfIter @@ -421,11 +430,9 @@ proc magicsAfterOverloadResolution(c: PContext, n: PNode, case n[0].sym.magic of mAddr: - # XXX: wasn't this magic already processed in ``semMagic``? + # 'addr' was overloaded, hence ``semMagic`` not handling the magic already checkSonsLen(n, 2, c.config) - result = n - result[1] = semAddrArg(c, n[1]) - result.typ = makePtrType(c, result[1].typ) + result = semAddrCall(c, n) of mTypeOf: result = semTypeOf(c, n) of mSizeOf: diff --git a/compiler/sem/sempass2.nim b/compiler/sem/sempass2.nim index 291f43d34e4..3ddca3050c8 100644 --- a/compiler/sem/sempass2.nim +++ b/compiler/sem/sempass2.nim @@ -1143,8 +1143,6 @@ proc allowCStringConv(n: PNode): bool = of nkStrLiterals: result = true of nkSym: result = n.sym.kind in {skConst, skParam} of nkAddr: result = isCharArrayPtr(n.typ, true) - of nkCallKinds: - result = isCharArrayPtr(n.typ, n[0].kind == nkSym and n[0].sym.magic == mAddr) else: result = isCharArrayPtr(n.typ, false) proc reportErrors(c: ConfigRef, n: PNode) = diff --git a/compiler/sem/transf.nim b/compiler/sem/transf.nim index 5feab15987f..a94d9c0d79c 100644 --- a/compiler/sem/transf.nim +++ b/compiler/sem/transf.nim @@ -1110,9 +1110,6 @@ proc transformCall(c: PTransf, n: PNode): PNode = inc(j) result.add(a) if result.len == 2: result = result[1] - elif magic == mAddr: - result = newTreeIT(nkAddr, n.info, n.typ): n[1] - result = transformAddr(c, result) elif magic == mTypeOf: result = n elif magic == mRunnableExamples: diff --git a/tests/effects/teffects11.nim b/tests/effects/teffects11.nim new file mode 100644 index 00000000000..66a9b1c574f --- /dev/null +++ b/tests/effects/teffects11.nim @@ -0,0 +1,11 @@ +discard """ + description: ''' + Taking the address of a location storing a procedural value does not + incur the procedure's effects. + ''' + action: compile +""" + +proc p() {.raises: [].} = + var a: proc() {.raises: ValueError.} + discard addr(a) diff --git a/tests/lang_callable/macros/tmacrostmt.nim b/tests/lang_callable/macros/tmacrostmt.nim index 9c90845336e..2a4466d8ffa 100644 --- a/tests/lang_callable/macros/tmacrostmt.nim +++ b/tests/lang_callable/macros/tmacrostmt.nim @@ -114,8 +114,6 @@ proc fn6() = #------------------------------------ # bug #10807 -proc fn_unsafeaddr(x: int): int = - cast[int](unsafeAddr(x)) static: let fn1s = "proc fn1(x, y: int): int =\n result = 2 * (x + y)\n" @@ -124,7 +122,6 @@ static: let fn4s = "proc fn4(x: int): int =\n if x mod 2 == 0:\n return x + 2\n else:\n return 0\n" let fn5s = "proc fn5(a, b: float): float =\n result = -a * a / (b * b)\n" let fn6s = "proc fn6() =\n var a = @[1.0, 2.0]\n let z = a{0, 1}\n a{2} = 5.0\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 @@ -132,7 +129,6 @@ static: doAssert fn4.repr_to_string == fn4s doAssert fn5.repr_to_string == fn5s doAssert fn6.repr_to_string == fn6s - doAssert fn_unsafeaddr.repr_to_string == fnAddr #------------------------------------ # bug #8763