From ea7f5c99e2e6fc1f7b28d92eef12ecebf6fd2746 Mon Sep 17 00:00:00 2001 From: flywind Date: Wed, 12 Jan 2022 23:07:29 +0800 Subject: [PATCH 1/8] deprecate unsafeAddr; extend addr addr is now available for all addressable locations, unsafeAddr is deprecated and become an alias for addr --- changelog.md | 3 +++ compiler/isolation_check.nim | 2 +- compiler/semmagic.nim | 9 ++------- doc/manual.rst | 15 +++++---------- doc/manual_experimental.rst | 2 +- lib/system.nim | 15 +++++++++++---- 6 files changed, 23 insertions(+), 23 deletions(-) diff --git a/changelog.md b/changelog.md index 1b97fd99a4f5..9d84b490e0a6 100644 --- a/changelog.md +++ b/changelog.md @@ -17,6 +17,9 @@ - `std/sharedstrings` module is removed. - Constants `colors.colPaleVioletRed` and `colors.colMediumPurple` changed to match the CSS color standard. +- `addr` is now available for all addressable locations, `unsafeAddr` is deprecated and +become an alias for `addr`. + ## Standard library additions and changes - `macros.parseExpr` and `macros.parseStmt` now accept an optional diff --git a/compiler/isolation_check.nim b/compiler/isolation_check.nim index a8c5a3651bca..68a2127946a6 100644 --- a/compiler/isolation_check.nim +++ b/compiler/isolation_check.nim @@ -71,7 +71,7 @@ proc isValueOnlyType(t: PType): bool = proc canAlias*(arg, ret: PType): bool = if isValueOnlyType(arg): - # can alias only with unsafeAddr(arg.x) and we don't care if it is not safe + # can alias only with addr(arg.x) and we don't care if it is not safe result = false else: var marker = initIntSet() diff --git a/compiler/semmagic.nim b/compiler/semmagic.nim index 874098294432..c7fc75620999 100644 --- a/compiler/semmagic.nim +++ b/compiler/semmagic.nim @@ -14,13 +14,8 @@ proc semAddrArg(c: PContext; n: PNode; isUnsafeAddr = false): PNode = let x = semExprWithType(c, n) if x.kind == nkSym: x.sym.flags.incl(sfAddrTaken) - if isAssignable(c, x, isUnsafeAddr) notin {arLValue, arLocalLValue}: - # Do not suggest the use of unsafeAddr if this expression already is a - # unsafeAddr - if isUnsafeAddr: - localError(c.config, n.info, errExprHasNoAddress) - else: - localError(c.config, n.info, errExprHasNoAddress & "; maybe use 'unsafeAddr'") + if isAssignable(c, x, true) notin {arLValue, arLocalLValue}: + localError(c.config, n.info, errExprHasNoAddress) result = x proc semTypeOf(c: PContext; n: PNode): PNode = diff --git a/doc/manual.rst b/doc/manual.rst index 8788e53a360a..2b7545b62a70 100644 --- a/doc/manual.rst +++ b/doc/manual.rst @@ -3502,8 +3502,9 @@ location is `T`, the `addr` operator result is of the type `ptr T`. An address is always an untraced reference. Taking the address of an object that resides on the stack is **unsafe**, as the pointer may live longer than the object on the stack and can thus reference a non-existing object. One can get -the address of variables, but one can't use it on variables declared through -`let` statements: +the address of variables. For easier interoperability with other compiled languages +such as C, retrieving the address of a `let` variable, a parameter, +or a `for` loop variable can be accomplished too: .. code-block:: nim @@ -3515,24 +3516,18 @@ the address of variables, but one can't use it on variables declared through # --> ref 0x7fff6b71b670 --> 0x10bb81050"Hello" echo cast[ptr string](t3)[] # --> Hello - # The following line doesn't compile: + # The following line also works echo repr(addr(t1)) - # Error: expression has no address - The unsafeAddr operator ----------------------- -For easier interoperability with other compiled languages such as C, retrieving -the address of a `let` variable, a parameter, or a `for` loop variable can -be accomplished by using the `unsafeAddr` operation: +The unsafeAddr operator is an alias for the addr operator and is deprecated: .. code-block:: nim - let myArray = [1, 2, 3] foreignProcThatTakesAnAddr(unsafeAddr myArray) - Procedures ========== diff --git a/doc/manual_experimental.rst b/doc/manual_experimental.rst index 4ed8439dffe6..c62236db27f9 100644 --- a/doc/manual_experimental.rst +++ b/doc/manual_experimental.rst @@ -592,7 +592,7 @@ has `source` as the owner. A path expression `e` is defined recursively: - Object field access `e.field` is a path expression. - `system.toOpenArray(e, ...)` is a path expression. - Pointer dereference `e[]` is a path expression. -- An address `addr e`, `unsafeAddr e` is a path expression. +- An address `addr e` is a path expression. - A type conversion `T(e)` is a path expression. - A cast expression `cast[T](e)` is a path expression. - `f(e, ...)` is a path expression if `f`'s return type is a view type. diff --git a/lib/system.nim b/lib/system.nim index c424cbc1b1c0..34d270a73e16 100644 --- a/lib/system.nim +++ b/lib/system.nim @@ -192,6 +192,13 @@ else: proc `addr`*[T](x: var T): ptr T {.magic: "Addr", noSideEffect.} = ## Builtin `addr` operator for taking the address of a memory location. + ## This works even for `let` variables or parameters + ## for better interop with C. + ## + ## .. note:: When you use it to write a wrapper for a C library, you should + ## always check that the original library does never write to data behind the + ## pointer that is returned from this procedure. + ## ## Cannot be overloaded. ## ## See also: @@ -205,13 +212,13 @@ proc `addr`*[T](x: var T): ptr T {.magic: "Addr", noSideEffect.} = ## echo p[] # b discard -proc unsafeAddr*[T](x: T): ptr T {.magic: "Addr", noSideEffect.} = +proc unsafeAddr*[T](x: T): ptr T {.magic: "Addr", noSideEffect, + deprecated: "'unsafeAddr' is a deprecated alias for 'addr'".} = ## Builtin `addr` operator for taking the address of a memory ## location. This works even for `let` variables or parameters - ## for better interop with C and so it is considered even more - ## unsafe than the ordinary `addr <#addr,T>`_. + ## for better interop with C. ## - ## **Note**: When you use it to write a wrapper for a C library, you should + ## .. note:: When you use it to write a wrapper for a C library, you should ## always check that the original library does never write to data behind the ## pointer that is returned from this procedure. ## From ee05ff2ea81ba1061439a31aa520b810699d2da7 Mon Sep 17 00:00:00 2001 From: flywind Date: Thu, 13 Jan 2022 08:45:43 +0800 Subject: [PATCH 2/8] follow @Vindaar's advice --- lib/system.nim | 25 ++++++++++++++----------- 1 file changed, 14 insertions(+), 11 deletions(-) diff --git a/lib/system.nim b/lib/system.nim index 34d270a73e16..4f9e30337879 100644 --- a/lib/system.nim +++ b/lib/system.nim @@ -192,12 +192,13 @@ else: proc `addr`*[T](x: var T): ptr T {.magic: "Addr", noSideEffect.} = ## Builtin `addr` operator for taking the address of a memory location. - ## This works even for `let` variables or parameters - ## for better interop with C. ## - ## .. note:: When you use it to write a wrapper for a C library, you should - ## always check that the original library does never write to data behind the - ## pointer that is returned from this procedure. + ## .. note:: This works for `let` variables or parameters + ## for better interop with C. When you use it to write a wrapper + ## for a C library and take the address of `let` variables or parameters, + ## you should always check that the original library + ## does never write to data behind the pointer that is returned from + ## this procedure. ## ## Cannot be overloaded. ## @@ -215,12 +216,14 @@ proc `addr`*[T](x: var T): ptr T {.magic: "Addr", noSideEffect.} = proc unsafeAddr*[T](x: T): ptr T {.magic: "Addr", noSideEffect, deprecated: "'unsafeAddr' is a deprecated alias for 'addr'".} = ## Builtin `addr` operator for taking the address of a memory - ## location. This works even for `let` variables or parameters - ## for better interop with C. - ## - ## .. note:: When you use it to write a wrapper for a C library, you should - ## always check that the original library does never write to data behind the - ## pointer that is returned from this procedure. + ## location. + ## + ## .. note:: This works for `let` variables or parameters + ## for better interop with C. When you use it to write a wrapper + ## for a C library and take the address of `let` variables or parameters, + ## you should always check that the original library + ## does never write to data behind the pointer that is returned from + ## this procedure. ## ## Cannot be overloaded. discard From a4ff401f50b5c4ac36043f2681db96645dd9bcce Mon Sep 17 00:00:00 2001 From: flywind Date: Thu, 13 Jan 2022 08:51:39 +0800 Subject: [PATCH 3/8] change the signature of addr --- lib/system.nim | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/system.nim b/lib/system.nim index 4f9e30337879..1fa76357405f 100644 --- a/lib/system.nim +++ b/lib/system.nim @@ -190,7 +190,7 @@ when defined(nimHasDeclaredMagic): else: proc declaredInScope*(x: untyped): bool {.magic: "DefinedInScope", noSideEffect, compileTime.} -proc `addr`*[T](x: var T): ptr T {.magic: "Addr", noSideEffect.} = +proc `addr`*[T](x: T): ptr T {.magic: "Addr", noSideEffect.} = ## Builtin `addr` operator for taking the address of a memory location. ## ## .. note:: This works for `let` variables or parameters From ab83c99c507048a8396e636bf22d55fdd84d7d1c Mon Sep 17 00:00:00 2001 From: flywind Date: Thu, 13 Jan 2022 08:55:35 +0800 Subject: [PATCH 4/8] unsafeAddr => addr (stdlib) --- lib/impure/db_sqlite.nim | 6 +++--- lib/impure/re.nim | 4 ++-- lib/pure/asyncdispatch.nim | 2 +- lib/pure/base64.nim | 2 +- lib/pure/hashes.nim | 2 +- lib/pure/nativesockets.nim | 2 +- lib/pure/net.nim | 6 +++--- lib/pure/streams.nim | 6 +++--- lib/pure/strutils.nim | 4 ++-- lib/std/private/digitsutils.nim | 4 ++-- lib/std/sha1.nim | 4 ++-- lib/system/ansi_c.nim | 4 ++-- lib/system/atomics.nim | 2 +- lib/system/channels_builtin.nim | 4 ++-- lib/system/io.nim | 4 ++-- lib/system/repr_v2.nim | 2 +- lib/system/sets.nim | 2 +- lib/system/strmantle.nim | 4 ++-- lib/system/strs_v2.nim | 14 +++++++------- lib/system/sysstr.nim | 6 +++--- 20 files changed, 42 insertions(+), 42 deletions(-) diff --git a/lib/impure/db_sqlite.nim b/lib/impure/db_sqlite.nim index b600576df1f0..8bc1f1410e21 100644 --- a/lib/impure/db_sqlite.nim +++ b/lib/impure/db_sqlite.nim @@ -121,7 +121,7 @@ ## var id = 1 ## ## Data needs to be converted to seq[byte] to be interpreted as binary by bindParams ## var dbuf = newSeq[byte](orig.len*sizeof(float64)) -## copyMem(unsafeAddr(dbuf[0]), unsafeAddr(orig[0]), dbuf.len) +## copyMem(addr(dbuf[0]), addr(orig[0]), dbuf.len) ## ## ## Use prepared statement to insert binary data into database ## var insertStmt = db.prepare("INSERT INTO test (id, data) VALUES (?, ?)") @@ -138,7 +138,7 @@ ## let seqSize = int(dataTest.len*sizeof(byte)/sizeof(float64)) ## ## Copy binary string data in dataTest into a seq ## var res: seq[float64] = newSeq[float64](seqSize) -## copyMem(unsafeAddr(res[0]), addr(dataTest[0]), dataTest.len) +## copyMem(addr(res[0]), addr(dataTest[0]), dataTest.len) ## ## ## Check datas obtained is identical ## doAssert res == orig @@ -827,7 +827,7 @@ proc bindParam*(ps: SqlPrepared, paramIdx: int,val: openArray[byte], copy = true ## binds a blob to the specified paramIndex. ## if copy is true then SQLite makes its own private copy of the data immediately let len = val.len - if bind_blob(ps.PStmt, paramIdx.int32, val[0].unsafeAddr, len.int32, if copy: SQLITE_TRANSIENT else: SQLITE_STATIC) != SQLITE_OK: + if bind_blob(ps.PStmt, paramIdx.int32, val[0].addr, len.int32, if copy: SQLITE_TRANSIENT else: SQLITE_STATIC) != SQLITE_OK: dbBindParamError(paramIdx, val) macro bindParams*(ps: SqlPrepared, params: varargs[untyped]): untyped {.since: (1, 3).} = diff --git a/lib/impure/re.nim b/lib/impure/re.nim index 4eacf0091cf6..548dfc94384d 100644 --- a/lib/impure/re.nim +++ b/lib/impure/re.nim @@ -122,7 +122,7 @@ proc bufSubstr(b: cstring, sPos, ePos: int): string {.inline.} = ## Don't assume cstring is '\0' terminated let sz = ePos - sPos result = newString(sz+1) - copyMem(addr(result[0]), unsafeAddr(b[sPos]), sz) + copyMem(addr(result[0]), addr(b[sPos]), sz) result.setLen(sz) proc matchOrFind(buf: cstring, pattern: Regex, matches: var openArray[string], @@ -427,7 +427,7 @@ iterator findAll*(buf: cstring, pattern: Regex, start = 0, bufSize: int): string let b = rawMatches[1] if a == b and a == i: break var str = newString(b-a) - copyMem(str[0].addr, unsafeAddr(buf[a]), b-a) + copyMem(str[0].addr, addr(buf[a]), b-a) yield str i = b diff --git a/lib/pure/asyncdispatch.nim b/lib/pure/asyncdispatch.nim index 5e2a8d98e745..7e2675b20d58 100644 --- a/lib/pure/asyncdispatch.nim +++ b/lib/pure/asyncdispatch.nim @@ -1920,7 +1920,7 @@ proc send*(socket: AsyncFD, data: string, ## data has been sent. var retFuture = newFuture[void]("send") if data.len > 0: - let sendFut = socket.send(unsafeAddr data[0], data.len, flags) + let sendFut = socket.send(addr data[0], data.len, flags) sendFut.callback = proc () = keepAlive(data) diff --git a/lib/pure/base64.nim b/lib/pure/base64.nim index 513ec5826959..1052073d471c 100644 --- a/lib/pure/base64.nim +++ b/lib/pure/base64.nim @@ -138,7 +138,7 @@ template encodeImpl() {.dirty.} = encodeInternal(s, lookupTableVM) else: block: - let lookupTable = if safe: unsafeAddr(cb64safe) else: unsafeAddr(cb64) + let lookupTable = if safe: addr(cb64safe) else: addr(cb64) encodeInternal(s, lookupTable) proc encode*[T: SomeInteger|char](s: openArray[T], safe = false): string = diff --git a/lib/pure/hashes.nim b/lib/pure/hashes.nim index d9f534670296..2df5970103ca 100644 --- a/lib/pure/hashes.nim +++ b/lib/pure/hashes.nim @@ -324,7 +324,7 @@ proc murmurHash(x: openArray[byte]): Hash = dec j k1 = (k1 shl 8) or (ord(x[i+j])).uint32 else: - k1 = cast[ptr uint32](unsafeAddr x[i])[] + k1 = cast[ptr uint32](addr x[i])[] inc i, stepSize k1 = imul(k1, c1) diff --git a/lib/pure/nativesockets.nim b/lib/pure/nativesockets.nim index eb0514a8ff1f..a5b7b8c9d020 100644 --- a/lib/pure/nativesockets.nim +++ b/lib/pure/nativesockets.nim @@ -663,7 +663,7 @@ when useNimNetLite: return "" proc sockAddrToStr(sa: var Sockaddr_in | var Sockaddr_in6): string = - result = sockAddrToStr(cast[ptr SockAddr](unsafeAddr(sa))) + result = sockAddrToStr(cast[ptr SockAddr](addr(sa))) proc getAddrString*(sockAddr: ptr SockAddr): string = result = sockAddrToStr(sockAddr) diff --git a/lib/pure/net.nim b/lib/pure/net.nim index c1d4c622862a..7303e3d756bc 100644 --- a/lib/pure/net.nim +++ b/lib/pure/net.nim @@ -484,14 +484,14 @@ proc toSockAddr*(address: IpAddress, port: Port, sa: var Sockaddr_storage, let s = cast[ptr Sockaddr_in](addr sa) s.sin_family = typeof(s.sin_family)(toInt(AF_INET)) s.sin_port = port - copyMem(addr s.sin_addr, unsafeAddr address.address_v4[0], + copyMem(addr s.sin_addr, addr address.address_v4[0], sizeof(s.sin_addr)) of IpAddressFamily.IPv6: sl = sizeof(Sockaddr_in6).SockLen let s = cast[ptr Sockaddr_in6](addr sa) s.sin6_family = typeof(s.sin6_family)(toInt(AF_INET6)) s.sin6_port = port - copyMem(addr s.sin6_addr, unsafeAddr address.address_v6[0], + copyMem(addr s.sin6_addr, addr address.address_v6[0], sizeof(s.sin6_addr)) proc fromSockAddrAux(sa: ptr Sockaddr_storage, sl: SockLen, @@ -516,7 +516,7 @@ proc fromSockAddr*(sa: Sockaddr_storage | SockAddr | Sockaddr_in | Sockaddr_in6, sl: SockLen, address: var IpAddress, port: var Port) {.inline.} = ## Converts `SockAddr` and `SockLen` to `IpAddress` and `Port`. Raises ## `ObjectConversionDefect` in case of invalid `sa` and `sl` arguments. - fromSockAddrAux(cast[ptr Sockaddr_storage](unsafeAddr sa), sl, address, port) + fromSockAddrAux(cast[ptr Sockaddr_storage](addr sa), sl, address, port) when defineSsl: CRYPTO_malloc_init() diff --git a/lib/pure/streams.nim b/lib/pure/streams.nim index 7dc81148f686..4020aa3746ac 100644 --- a/lib/pure/streams.nim +++ b/lib/pure/streams.nim @@ -333,7 +333,7 @@ proc write*[T](s: Stream, x: T) = ## ## .. code-block:: Nim ## - ## s.writeData(s, unsafeAddr(x), sizeof(x)) + ## s.writeData(s, addr(x), sizeof(x)) runnableExamples: var strm = newStringStream("") strm.write("abcde") @@ -341,7 +341,7 @@ proc write*[T](s: Stream, x: T) = doAssert strm.readAll() == "abcde" strm.close() - writeData(s, unsafeAddr(x), sizeof(x)) + writeData(s, addr(x), sizeof(x)) proc write*(s: Stream, x: string) = ## Writes the string `x` to the stream `s`. No length field or @@ -1196,7 +1196,7 @@ else: # after 1.3 or JS not defined jsOrVmBlock: buffer[slice.a.. 0: - let found = c_memchr(s[start].unsafeAddr, sub, cast[csize_t](L)) + let found = c_memchr(s[start].addr, sub, cast[csize_t](L)) if not found.isNil: return cast[ByteAddress](found) -% cast[ByteAddress](s.cstring) else: @@ -1928,7 +1928,7 @@ func find*(s, sub: string, start: Natural = 0, last = 0): int {.rtl, else: when hasCStringBuiltin: if last == 0 and s.len > start: - let found = c_strstr(s[start].unsafeAddr, sub) + let found = c_strstr(s[start].addr, sub) if not found.isNil: result = cast[ByteAddress](found) -% cast[ByteAddress](s.cstring) else: diff --git a/lib/std/private/digitsutils.nim b/lib/std/private/digitsutils.nim index 588bcaec07fb..ccd9ae04a004 100644 --- a/lib/std/private/digitsutils.nim +++ b/lib/std/private/digitsutils.nim @@ -31,7 +31,7 @@ const proc utoa2Digits*(buf: var openArray[char]; pos: int; digits: uint32) {.inline.} = buf[pos] = digits100[2 * digits] buf[pos+1] = digits100[2 * digits + 1] - #copyMem(buf, unsafeAddr(digits100[2 * digits]), 2 * sizeof((char))) + #copyMem(buf, addr(digits100[2 * digits]), 2 * sizeof((char))) proc trailingZeros2Digits*(digits: uint32): int32 {.inline.} = return trailingZeros100[digits] @@ -49,7 +49,7 @@ func addChars[T](result: var string, x: T, start: int, n: int) {.inline.} = when defined(js) or defined(nimscript): impl else: {.noSideEffect.}: - copyMem result[old].addr, x[start].unsafeAddr, n + copyMem result[old].addr, x[start].addr, n func addChars[T](result: var string, x: T) {.inline.} = addChars(result, x, 0, x.len) diff --git a/lib/std/sha1.nim b/lib/std/sha1.nim index 120a81702fa2..b47c9b795009 100644 --- a/lib/std/sha1.nim +++ b/lib/std/sha1.nim @@ -152,7 +152,7 @@ proc update*(ctx: var Sha1State, data: openArray[char]) = # Gather 64-bytes worth of data in order to perform a round with the leftover # data we had stored (but not processed yet) if len > 64 - i: - copyMem(addr ctx.buf[i], unsafeAddr data[j], 64 - i) + copyMem(addr ctx.buf[i], addr data[j], 64 - i) len -= 64 - i j += 64 - i transform(ctx) @@ -161,7 +161,7 @@ proc update*(ctx: var Sha1State, data: openArray[char]) = i = 0 # Process the bulk of the payload while len >= 64: - copyMem(addr ctx.buf[0], unsafeAddr data[j], 64) + copyMem(addr ctx.buf[0], addr data[j], 64) len -= 64 j += 64 transform(ctx) diff --git a/lib/system/ansi_c.nim b/lib/system/ansi_c.nim index 23fb9fdef0d7..8af48c36ed0d 100644 --- a/lib/system/ansi_c.nim +++ b/lib/system/ansi_c.nim @@ -111,11 +111,11 @@ elif defined(nimBuiltinSetjmp): proc c_builtin_longjmp(jmpb: ptr pointer, retval: cint) {. importc: "__builtin_longjmp", nodecl.} # The second parameter needs to be 1 and sometimes the C/C++ compiler checks it. - c_builtin_longjmp(unsafeAddr jmpb[0], 1) + c_builtin_longjmp(addr jmpb[0], 1) proc c_setjmp*(jmpb: C_JmpBuf): cint = proc c_builtin_setjmp(jmpb: ptr pointer): cint {. importc: "__builtin_setjmp", nodecl.} - c_builtin_setjmp(unsafeAddr jmpb[0]) + c_builtin_setjmp(addr jmpb[0]) elif defined(nimRawSetjmp) and not defined(nimStdSetjmp): when defined(windows): # No `_longjmp()` on Windows. diff --git a/lib/system/atomics.nim b/lib/system/atomics.nim index 8d29c287dede..1f25d0b24126 100644 --- a/lib/system/atomics.nim +++ b/lib/system/atomics.nim @@ -308,7 +308,7 @@ static int __tcc_cas(int *ptr, int oldVal, int newVal) tcc_cas(cast[ptr int](p), cast[int](oldValue), cast[int](newValue)) elif declared(atomicCompareExchangeN): proc cas*[T: bool|int|ptr](p: ptr T; oldValue, newValue: T): bool = - atomicCompareExchangeN(p, oldValue.unsafeAddr, newValue, false, ATOMIC_SEQ_CST, ATOMIC_SEQ_CST) + atomicCompareExchangeN(p, oldValue.addr, newValue, false, ATOMIC_SEQ_CST, ATOMIC_SEQ_CST) else: # this is valid for GCC and Intel C++ proc cas*[T: bool|int|ptr](p: ptr T; oldValue, newValue: T): bool diff --git a/lib/system/channels_builtin.nim b/lib/system/channels_builtin.nim index 30267e375227..8a920a06ff54 100644 --- a/lib/system/channels_builtin.nim +++ b/lib/system/channels_builtin.nim @@ -366,7 +366,7 @@ proc sendImpl(q: PRawChannel, typ: PNimType, msg: pointer, noBlock: bool): bool proc send*[TMsg](c: var Channel[TMsg], msg: sink TMsg) {.inline.} = ## Sends a message to a thread. `msg` is deeply copied. - discard sendImpl(cast[PRawChannel](addr c), cast[PNimType](getTypeInfo(msg)), unsafeAddr(msg), false) + discard sendImpl(cast[PRawChannel](addr c), cast[PNimType](getTypeInfo(msg)), addr(msg), false) when defined(gcDestructors): wasMoved(msg) @@ -377,7 +377,7 @@ proc trySend*[TMsg](c: var Channel[TMsg], msg: sink TMsg): bool {.inline.} = ## ## Returns `false` if the message was not sent because number of pending items ## in the channel exceeded `maxItems`. - result = sendImpl(cast[PRawChannel](addr c), cast[PNimType](getTypeInfo(msg)), unsafeAddr(msg), true) + result = sendImpl(cast[PRawChannel](addr c), cast[PNimType](getTypeInfo(msg)), addr(msg), true) when defined(gcDestructors): if result: wasMoved(msg) diff --git a/lib/system/io.nim b/lib/system/io.nim index 661d1a9ba1fd..3f64a851e742 100644 --- a/lib/system/io.nim +++ b/lib/system/io.nim @@ -251,7 +251,7 @@ when defined(windows): break inc i else: - let w = c_fprintf(f, "%s", unsafeAddr s[i]) + let w = c_fprintf(f, "%s", addr s[i]) if w <= 0: if doRaise: raiseEIO("cannot write string to file") break @@ -896,7 +896,7 @@ proc writeFile*(filename: string, content: openArray[byte]) {.since: (1, 1).} = var f: File = nil if open(f, filename, fmWrite): try: - f.writeBuffer(unsafeAddr content[0], content.len) + f.writeBuffer(addr content[0], content.len) finally: close(f) else: diff --git a/lib/system/repr_v2.nim b/lib/system/repr_v2.nim index 6ab5f3c3f744..25290b9c5bb5 100644 --- a/lib/system/repr_v2.nim +++ b/lib/system/repr_v2.nim @@ -90,7 +90,7 @@ proc repr*(p: pointer): string = proc repr*(p: proc): string = ## repr of a proc as its address - repr(cast[ptr pointer](unsafeAddr p)[]) + repr(cast[ptr pointer](addr p)[]) template repr*(x: distinct): string = repr(distinctBase(typeof(x))(x)) diff --git a/lib/system/sets.nim b/lib/system/sets.nim index 103c8d343ebe..94e1dd2edbda 100644 --- a/lib/system/sets.nim +++ b/lib/system/sets.nim @@ -18,7 +18,7 @@ proc cardSet(s: NimSet, len: int): int {.compilerproc, inline.} = result = 0 when defined(x86) or defined(amd64): while i < len - 8: - inc(result, countBits64((cast[ptr uint64](s[i].unsafeAddr))[])) + inc(result, countBits64((cast[ptr uint64](s[i].addr))[])) inc(i, 8) while i < len: diff --git a/lib/system/strmantle.nim b/lib/system/strmantle.nim index 9cf4f9e55f75..db8a9f6de30f 100644 --- a/lib/system/strmantle.nim +++ b/lib/system/strmantle.nim @@ -17,7 +17,7 @@ proc cmpStrings(a, b: string): int {.inline, compilerproc.} = let blen = b.len let minlen = min(alen, blen) if minlen > 0: - result = c_memcmp(unsafeAddr a[0], unsafeAddr b[0], cast[csize_t](minlen)) + result = c_memcmp(addr a[0], addr b[0], cast[csize_t](minlen)) if result == 0: result = alen - blen else: @@ -28,7 +28,7 @@ proc eqStrings(a, b: string): bool {.inline, compilerproc.} = let blen = b.len if alen == blen: if alen == 0: return true - return equalMem(unsafeAddr(a[0]), unsafeAddr(b[0]), alen) + return equalMem(addr(a[0]), addr(b[0]), alen) proc hashString(s: string): int {.compilerproc.} = # the compiler needs exactly the same hash function! diff --git a/lib/system/strs_v2.nim b/lib/system/strs_v2.nim index 6944cdc589df..45d3c630a6c4 100644 --- a/lib/system/strs_v2.nim +++ b/lib/system/strs_v2.nim @@ -51,7 +51,7 @@ proc prepareAdd(s: var NimStringV2; addlen: int) {.compilerRtl.} = s.p.cap = newLen if s.len > 0: # we are about to append, so there is no need to copy the \0 terminator: - copyMem(unsafeAddr s.p.data[0], unsafeAddr oldP.data[0], min(s.len, newLen)) + copyMem(addr s.p.data[0], addr oldP.data[0], min(s.len, newLen)) else: let oldCap = s.p.cap and not strlitFlag if newLen > oldCap: @@ -80,7 +80,7 @@ proc toNimStr(str: cstring, len: int): NimStringV2 {.compilerproc.} = p.cap = len if len > 0: # we are about to append, so there is no need to copy the \0 terminator: - copyMem(unsafeAddr p.data[0], str, len) + copyMem(addr p.data[0], str, len) result = NimStringV2(len: len, p: p) proc cstrToNimstr(str: cstring): NimStringV2 {.compilerRtl.} = @@ -89,12 +89,12 @@ proc cstrToNimstr(str: cstring): NimStringV2 {.compilerRtl.} = proc nimToCStringConv(s: NimStringV2): cstring {.compilerproc, nonReloadable, inline.} = if s.len == 0: result = cstring"" - else: result = cstring(unsafeAddr s.p.data) + else: result = cstring(addr s.p.data) proc appendString(dest: var NimStringV2; src: NimStringV2) {.compilerproc, inline.} = if src.len > 0: # also copy the \0 terminator: - copyMem(unsafeAddr dest.p.data[dest.len], unsafeAddr src.p.data[0], src.len+1) + copyMem(addr dest.p.data[dest.len], addr src.p.data[0], src.len+1) inc dest.len, src.len proc appendChar(dest: var NimStringV2; c: char) {.compilerproc, inline.} = @@ -153,7 +153,7 @@ proc nimAsgnStrV2(a: var NimStringV2, b: NimStringV2) {.compilerRtl.} = a.p = cast[ptr NimStrPayload](alloc0(contentSize(b.len))) a.p.cap = b.len a.len = b.len - copyMem(unsafeAddr a.p.data[0], unsafeAddr b.p.data[0], b.len+1) + copyMem(addr a.p.data[0], addr b.p.data[0], b.len+1) proc nimPrepareStrMutationImpl(s: var NimStringV2) = let oldP = s.p @@ -163,7 +163,7 @@ proc nimPrepareStrMutationImpl(s: var NimStringV2) = else: s.p = cast[ptr NimStrPayload](alloc0(contentSize(s.len))) s.p.cap = s.len - copyMem(unsafeAddr s.p.data[0], unsafeAddr oldP.data[0], s.len+1) + copyMem(addr s.p.data[0], addr oldP.data[0], s.len+1) proc nimPrepareStrMutationV2(s: var NimStringV2) {.compilerRtl, inline.} = if s.p != nil and (s.p.cap and strlitFlag) == strlitFlag: @@ -173,5 +173,5 @@ proc prepareMutation*(s: var string) {.inline.} = # string literals are "copy on write", so you need to call # `prepareMutation` before modifying the strings via `addr`. {.cast(noSideEffect).}: - let s = unsafeAddr s + let s = addr s nimPrepareStrMutationV2(cast[ptr NimStringV2](s)[]) diff --git a/lib/system/sysstr.nim b/lib/system/sysstr.nim index 49fff41e9ee7..19458368f233 100644 --- a/lib/system/sysstr.nim +++ b/lib/system/sysstr.nim @@ -163,7 +163,7 @@ proc addChar(s: NimString, c: char): NimString = when defined(nimIncrSeqV3): result = rawNewStringNoInit(r) result.len = s.len - copyMem(addr result.data[0], unsafeAddr(s.data[0]), s.len+1) + copyMem(addr result.data[0], addr(s.data[0]), s.len+1) else: result = cast[NimString](growObj(result, sizeof(TGenericSeq) + r + 1)) @@ -213,7 +213,7 @@ proc resizeString(dest: NimString, addlen: int): NimString {.compilerRtl.} = when defined(nimIncrSeqV3): result = rawNewStringNoInit(sp) result.len = dest.len - copyMem(addr result.data[0], unsafeAddr(dest.data[0]), dest.len+1) + copyMem(addr result.data[0], addr(dest.data[0]), dest.len+1) else: result = cast[NimString](growObj(dest, sizeof(TGenericSeq) + sp + 1)) result.reserved = sp @@ -242,7 +242,7 @@ proc setLengthStr(s: NimString, newLen: int): NimString {.compilerRtl.} = when defined(nimIncrSeqV3): result = rawNewStringNoInit(sp) result.len = s.len - copyMem(addr result.data[0], unsafeAddr(s.data[0]), s.len+1) + copyMem(addr result.data[0], addr(s.data[0]), s.len+1) zeroMem(addr result.data[s.len], newLen - s.len) result.reserved = sp else: From b5283405f86147be9c3a69e4ddf061f1ec3c66ce Mon Sep 17 00:00:00 2001 From: flywind Date: Thu, 13 Jan 2022 08:56:19 +0800 Subject: [PATCH 5/8] Update changelog.md --- changelog.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/changelog.md b/changelog.md index 9d84b490e0a6..5163706be34f 100644 --- a/changelog.md +++ b/changelog.md @@ -18,7 +18,7 @@ - Constants `colors.colPaleVioletRed` and `colors.colMediumPurple` changed to match the CSS color standard. - `addr` is now available for all addressable locations, `unsafeAddr` is deprecated and -become an alias for `addr`. +becomes an alias for `addr`. ## Standard library additions and changes From 042a409b39de129919cba75b7d4f9174365f96c3 Mon Sep 17 00:00:00 2001 From: flywind Date: Thu, 13 Jan 2022 09:02:32 +0800 Subject: [PATCH 6/8] unsafeAddr => addr (tests) --- tests/arc/tcustomtrace.nim | 2 +- tests/arc/thard_alignment.nim | 2 +- tests/async/tioselectors.nim | 2 +- tests/ccgbugs/tnoalias.nim | 2 +- tests/compiles/t8630.nim | 2 +- tests/concepts/tconcepts_issues.nim | 4 ++-- tests/destructor/t12037.nim | 6 +++--- tests/destructor/tarray_indexing.nim | 2 +- tests/destructor/tcustomseqs.nim | 2 +- tests/destructor/tcustomstrings.nim | 2 +- tests/destructor/tuse_result_prevents_sinks.nim | 2 +- tests/errmsgs/t10594.nim | 2 +- tests/errmsgs/tnon_concrete_cast.nim | 2 +- tests/js/tfieldchecks.nim | 2 +- tests/lent/tbasic_lent_check.nim | 10 +++++----- tests/misc/taddr.nim | 2 +- tests/overload/t8829.nim | 4 ++-- tests/overload/tstatic_with_converter.nim | 2 +- tests/stdlib/tdecls.nim | 14 +++++++------- tests/stdlib/tmemory.nim | 2 +- tests/stdlib/tsqlitebindatas.nim | 4 ++-- tests/strictnotnil/tnilcheck.nim | 2 +- tests/system/tostring.nim | 2 +- tests/types/tlent_var.nim | 2 +- 24 files changed, 39 insertions(+), 39 deletions(-) diff --git a/tests/arc/tcustomtrace.nim b/tests/arc/tcustomtrace.nim index 3977194d9421..5e0ecfb24841 100644 --- a/tests/arc/tcustomtrace.nim +++ b/tests/arc/tcustomtrace.nim @@ -130,7 +130,7 @@ proc createSeq*[T](elems: varargs[T]): myseq[T] = result.data = cast[type(result.data)](alloc0(result.cap * sizeof(T))) inc allocCount when supportsCopyMem(T): - copyMem(result.data, unsafeAddr(elems[0]), result.cap * sizeof(T)) + copyMem(result.data, addr(elems[0]), result.cap * sizeof(T)) else: for i in 0.. 0 doAssert cmpMem(b.addr, a.addr, sizeof(SomeHash)) < 0 - doAssert cmpMem(a.addr, c.unsafeAddr, sizeof(SomeHash)) == 0 + doAssert cmpMem(a.addr, c.addr, sizeof(SomeHash)) == 0 diff --git a/tests/stdlib/tsqlitebindatas.nim b/tests/stdlib/tsqlitebindatas.nim index 754c80ae1d3b..b2c3247fad07 100644 --- a/tests/stdlib/tsqlitebindatas.nim +++ b/tests/stdlib/tsqlitebindatas.nim @@ -27,7 +27,7 @@ block tsqlitebindatas: ## db_sqlite binary data db.exec(createTableStr) var dbuf = newSeq[byte](orig.len*sizeof(float64)) - copyMem(unsafeAddr(dbuf[0]), unsafeAddr(orig[0]), dbuf.len) + copyMem(addr(dbuf[0]), addr(orig[0]), dbuf.len) var insertStmt = db.prepare("INSERT INTO test (id, name, data) VALUES (?, ?, ?)") insertStmt.bindParams(1, origName, dbuf) @@ -42,7 +42,7 @@ block tsqlitebindatas: ## db_sqlite binary data var dataTest = db.getValue(sql"SELECT data FROM test WHERE id = ?", 1) let seqSize = int(dataTest.len*sizeof(byte)/sizeof(float64)) var res: seq[float64] = newSeq[float64](seqSize) - copyMem(unsafeAddr(res[0]), addr(dataTest[0]), dataTest.len) + copyMem(addr(res[0]), addr(dataTest[0]), dataTest.len) doAssert res.len == orig.len doAssert res == orig diff --git a/tests/strictnotnil/tnilcheck.nim b/tests/strictnotnil/tnilcheck.nim index 5b9292522c8a..c2d009b709a7 100644 --- a/tests/strictnotnil/tnilcheck.nim +++ b/tests/strictnotnil/tnilcheck.nim @@ -194,7 +194,7 @@ proc testAliasChanging(a: Nilable) = # # proc testPtrAlias(a: Nilable) = # # # pointer to a: hm. # # # alias to a? -# # var ptrA = a.unsafeAddr # {0, 1} +# # var ptrA = a.addr # {0, 1} # # if not a.isNil: # {0, 1} # # ptrA[] = nil # {0, 1} 0: MaybeNil 1: MaybeNil # # echo a.a #[ tt.Warning diff --git a/tests/system/tostring.nim b/tests/system/tostring.nim index bdbaa2ce6269..cae20865ebfc 100644 --- a/tests/system/tostring.nim +++ b/tests/system/tostring.nim @@ -47,7 +47,7 @@ import strutils let arr = ['H','e','l','l','o',' ','W','o','r','l','d','!','\0'] doAssert $arr == "['H', 'e', 'l', 'l', 'o', ' ', 'W', 'o', 'r', 'l', 'd', '!', '\\x00']" -doAssert $cstring(unsafeAddr arr) == "Hello World!" +doAssert $cstring(addr arr) == "Hello World!" proc takes(c: cstring) = doAssert c == cstring"" diff --git a/tests/types/tlent_var.nim b/tests/types/tlent_var.nim index 491f6fde8764..73b5bef9b4a2 100644 --- a/tests/types/tlent_var.nim +++ b/tests/types/tlent_var.nim @@ -15,7 +15,7 @@ proc test_var(x: var MyObj): var int = var x = MyObj(a: 5) doAssert: test_var(x).addr == x.a.addr -doAssert: test_lent(x).unsafeAddr == x.a.addr +doAssert: test_lent(x).addr == x.a.addr proc varProc(x: var int) = x = 100 From 47456f246bdfc269431f8fb7c677fa8980fec0eb Mon Sep 17 00:00:00 2001 From: flywind Date: Thu, 13 Jan 2022 09:04:47 +0800 Subject: [PATCH 7/8] Revert "unsafeAddr => addr (stdlib)" This reverts commit ab83c99c507048a8396e636bf22d55fdd84d7d1c. --- lib/impure/db_sqlite.nim | 6 +++--- lib/impure/re.nim | 4 ++-- lib/pure/asyncdispatch.nim | 2 +- lib/pure/base64.nim | 2 +- lib/pure/hashes.nim | 2 +- lib/pure/nativesockets.nim | 2 +- lib/pure/net.nim | 6 +++--- lib/pure/streams.nim | 6 +++--- lib/pure/strutils.nim | 4 ++-- lib/std/private/digitsutils.nim | 4 ++-- lib/std/sha1.nim | 4 ++-- lib/system/ansi_c.nim | 4 ++-- lib/system/atomics.nim | 2 +- lib/system/channels_builtin.nim | 4 ++-- lib/system/io.nim | 4 ++-- lib/system/repr_v2.nim | 2 +- lib/system/sets.nim | 2 +- lib/system/strmantle.nim | 4 ++-- lib/system/strs_v2.nim | 14 +++++++------- lib/system/sysstr.nim | 6 +++--- 20 files changed, 42 insertions(+), 42 deletions(-) diff --git a/lib/impure/db_sqlite.nim b/lib/impure/db_sqlite.nim index 8bc1f1410e21..b600576df1f0 100644 --- a/lib/impure/db_sqlite.nim +++ b/lib/impure/db_sqlite.nim @@ -121,7 +121,7 @@ ## var id = 1 ## ## Data needs to be converted to seq[byte] to be interpreted as binary by bindParams ## var dbuf = newSeq[byte](orig.len*sizeof(float64)) -## copyMem(addr(dbuf[0]), addr(orig[0]), dbuf.len) +## copyMem(unsafeAddr(dbuf[0]), unsafeAddr(orig[0]), dbuf.len) ## ## ## Use prepared statement to insert binary data into database ## var insertStmt = db.prepare("INSERT INTO test (id, data) VALUES (?, ?)") @@ -138,7 +138,7 @@ ## let seqSize = int(dataTest.len*sizeof(byte)/sizeof(float64)) ## ## Copy binary string data in dataTest into a seq ## var res: seq[float64] = newSeq[float64](seqSize) -## copyMem(addr(res[0]), addr(dataTest[0]), dataTest.len) +## copyMem(unsafeAddr(res[0]), addr(dataTest[0]), dataTest.len) ## ## ## Check datas obtained is identical ## doAssert res == orig @@ -827,7 +827,7 @@ proc bindParam*(ps: SqlPrepared, paramIdx: int,val: openArray[byte], copy = true ## binds a blob to the specified paramIndex. ## if copy is true then SQLite makes its own private copy of the data immediately let len = val.len - if bind_blob(ps.PStmt, paramIdx.int32, val[0].addr, len.int32, if copy: SQLITE_TRANSIENT else: SQLITE_STATIC) != SQLITE_OK: + if bind_blob(ps.PStmt, paramIdx.int32, val[0].unsafeAddr, len.int32, if copy: SQLITE_TRANSIENT else: SQLITE_STATIC) != SQLITE_OK: dbBindParamError(paramIdx, val) macro bindParams*(ps: SqlPrepared, params: varargs[untyped]): untyped {.since: (1, 3).} = diff --git a/lib/impure/re.nim b/lib/impure/re.nim index 548dfc94384d..4eacf0091cf6 100644 --- a/lib/impure/re.nim +++ b/lib/impure/re.nim @@ -122,7 +122,7 @@ proc bufSubstr(b: cstring, sPos, ePos: int): string {.inline.} = ## Don't assume cstring is '\0' terminated let sz = ePos - sPos result = newString(sz+1) - copyMem(addr(result[0]), addr(b[sPos]), sz) + copyMem(addr(result[0]), unsafeAddr(b[sPos]), sz) result.setLen(sz) proc matchOrFind(buf: cstring, pattern: Regex, matches: var openArray[string], @@ -427,7 +427,7 @@ iterator findAll*(buf: cstring, pattern: Regex, start = 0, bufSize: int): string let b = rawMatches[1] if a == b and a == i: break var str = newString(b-a) - copyMem(str[0].addr, addr(buf[a]), b-a) + copyMem(str[0].addr, unsafeAddr(buf[a]), b-a) yield str i = b diff --git a/lib/pure/asyncdispatch.nim b/lib/pure/asyncdispatch.nim index 7e2675b20d58..5e2a8d98e745 100644 --- a/lib/pure/asyncdispatch.nim +++ b/lib/pure/asyncdispatch.nim @@ -1920,7 +1920,7 @@ proc send*(socket: AsyncFD, data: string, ## data has been sent. var retFuture = newFuture[void]("send") if data.len > 0: - let sendFut = socket.send(addr data[0], data.len, flags) + let sendFut = socket.send(unsafeAddr data[0], data.len, flags) sendFut.callback = proc () = keepAlive(data) diff --git a/lib/pure/base64.nim b/lib/pure/base64.nim index 1052073d471c..513ec5826959 100644 --- a/lib/pure/base64.nim +++ b/lib/pure/base64.nim @@ -138,7 +138,7 @@ template encodeImpl() {.dirty.} = encodeInternal(s, lookupTableVM) else: block: - let lookupTable = if safe: addr(cb64safe) else: addr(cb64) + let lookupTable = if safe: unsafeAddr(cb64safe) else: unsafeAddr(cb64) encodeInternal(s, lookupTable) proc encode*[T: SomeInteger|char](s: openArray[T], safe = false): string = diff --git a/lib/pure/hashes.nim b/lib/pure/hashes.nim index 2df5970103ca..d9f534670296 100644 --- a/lib/pure/hashes.nim +++ b/lib/pure/hashes.nim @@ -324,7 +324,7 @@ proc murmurHash(x: openArray[byte]): Hash = dec j k1 = (k1 shl 8) or (ord(x[i+j])).uint32 else: - k1 = cast[ptr uint32](addr x[i])[] + k1 = cast[ptr uint32](unsafeAddr x[i])[] inc i, stepSize k1 = imul(k1, c1) diff --git a/lib/pure/nativesockets.nim b/lib/pure/nativesockets.nim index a5b7b8c9d020..eb0514a8ff1f 100644 --- a/lib/pure/nativesockets.nim +++ b/lib/pure/nativesockets.nim @@ -663,7 +663,7 @@ when useNimNetLite: return "" proc sockAddrToStr(sa: var Sockaddr_in | var Sockaddr_in6): string = - result = sockAddrToStr(cast[ptr SockAddr](addr(sa))) + result = sockAddrToStr(cast[ptr SockAddr](unsafeAddr(sa))) proc getAddrString*(sockAddr: ptr SockAddr): string = result = sockAddrToStr(sockAddr) diff --git a/lib/pure/net.nim b/lib/pure/net.nim index 7303e3d756bc..c1d4c622862a 100644 --- a/lib/pure/net.nim +++ b/lib/pure/net.nim @@ -484,14 +484,14 @@ proc toSockAddr*(address: IpAddress, port: Port, sa: var Sockaddr_storage, let s = cast[ptr Sockaddr_in](addr sa) s.sin_family = typeof(s.sin_family)(toInt(AF_INET)) s.sin_port = port - copyMem(addr s.sin_addr, addr address.address_v4[0], + copyMem(addr s.sin_addr, unsafeAddr address.address_v4[0], sizeof(s.sin_addr)) of IpAddressFamily.IPv6: sl = sizeof(Sockaddr_in6).SockLen let s = cast[ptr Sockaddr_in6](addr sa) s.sin6_family = typeof(s.sin6_family)(toInt(AF_INET6)) s.sin6_port = port - copyMem(addr s.sin6_addr, addr address.address_v6[0], + copyMem(addr s.sin6_addr, unsafeAddr address.address_v6[0], sizeof(s.sin6_addr)) proc fromSockAddrAux(sa: ptr Sockaddr_storage, sl: SockLen, @@ -516,7 +516,7 @@ proc fromSockAddr*(sa: Sockaddr_storage | SockAddr | Sockaddr_in | Sockaddr_in6, sl: SockLen, address: var IpAddress, port: var Port) {.inline.} = ## Converts `SockAddr` and `SockLen` to `IpAddress` and `Port`. Raises ## `ObjectConversionDefect` in case of invalid `sa` and `sl` arguments. - fromSockAddrAux(cast[ptr Sockaddr_storage](addr sa), sl, address, port) + fromSockAddrAux(cast[ptr Sockaddr_storage](unsafeAddr sa), sl, address, port) when defineSsl: CRYPTO_malloc_init() diff --git a/lib/pure/streams.nim b/lib/pure/streams.nim index 4020aa3746ac..7dc81148f686 100644 --- a/lib/pure/streams.nim +++ b/lib/pure/streams.nim @@ -333,7 +333,7 @@ proc write*[T](s: Stream, x: T) = ## ## .. code-block:: Nim ## - ## s.writeData(s, addr(x), sizeof(x)) + ## s.writeData(s, unsafeAddr(x), sizeof(x)) runnableExamples: var strm = newStringStream("") strm.write("abcde") @@ -341,7 +341,7 @@ proc write*[T](s: Stream, x: T) = doAssert strm.readAll() == "abcde" strm.close() - writeData(s, addr(x), sizeof(x)) + writeData(s, unsafeAddr(x), sizeof(x)) proc write*(s: Stream, x: string) = ## Writes the string `x` to the stream `s`. No length field or @@ -1196,7 +1196,7 @@ else: # after 1.3 or JS not defined jsOrVmBlock: buffer[slice.a.. 0: - let found = c_memchr(s[start].addr, sub, cast[csize_t](L)) + let found = c_memchr(s[start].unsafeAddr, sub, cast[csize_t](L)) if not found.isNil: return cast[ByteAddress](found) -% cast[ByteAddress](s.cstring) else: @@ -1928,7 +1928,7 @@ func find*(s, sub: string, start: Natural = 0, last = 0): int {.rtl, else: when hasCStringBuiltin: if last == 0 and s.len > start: - let found = c_strstr(s[start].addr, sub) + let found = c_strstr(s[start].unsafeAddr, sub) if not found.isNil: result = cast[ByteAddress](found) -% cast[ByteAddress](s.cstring) else: diff --git a/lib/std/private/digitsutils.nim b/lib/std/private/digitsutils.nim index ccd9ae04a004..588bcaec07fb 100644 --- a/lib/std/private/digitsutils.nim +++ b/lib/std/private/digitsutils.nim @@ -31,7 +31,7 @@ const proc utoa2Digits*(buf: var openArray[char]; pos: int; digits: uint32) {.inline.} = buf[pos] = digits100[2 * digits] buf[pos+1] = digits100[2 * digits + 1] - #copyMem(buf, addr(digits100[2 * digits]), 2 * sizeof((char))) + #copyMem(buf, unsafeAddr(digits100[2 * digits]), 2 * sizeof((char))) proc trailingZeros2Digits*(digits: uint32): int32 {.inline.} = return trailingZeros100[digits] @@ -49,7 +49,7 @@ func addChars[T](result: var string, x: T, start: int, n: int) {.inline.} = when defined(js) or defined(nimscript): impl else: {.noSideEffect.}: - copyMem result[old].addr, x[start].addr, n + copyMem result[old].addr, x[start].unsafeAddr, n func addChars[T](result: var string, x: T) {.inline.} = addChars(result, x, 0, x.len) diff --git a/lib/std/sha1.nim b/lib/std/sha1.nim index b47c9b795009..120a81702fa2 100644 --- a/lib/std/sha1.nim +++ b/lib/std/sha1.nim @@ -152,7 +152,7 @@ proc update*(ctx: var Sha1State, data: openArray[char]) = # Gather 64-bytes worth of data in order to perform a round with the leftover # data we had stored (but not processed yet) if len > 64 - i: - copyMem(addr ctx.buf[i], addr data[j], 64 - i) + copyMem(addr ctx.buf[i], unsafeAddr data[j], 64 - i) len -= 64 - i j += 64 - i transform(ctx) @@ -161,7 +161,7 @@ proc update*(ctx: var Sha1State, data: openArray[char]) = i = 0 # Process the bulk of the payload while len >= 64: - copyMem(addr ctx.buf[0], addr data[j], 64) + copyMem(addr ctx.buf[0], unsafeAddr data[j], 64) len -= 64 j += 64 transform(ctx) diff --git a/lib/system/ansi_c.nim b/lib/system/ansi_c.nim index 8af48c36ed0d..23fb9fdef0d7 100644 --- a/lib/system/ansi_c.nim +++ b/lib/system/ansi_c.nim @@ -111,11 +111,11 @@ elif defined(nimBuiltinSetjmp): proc c_builtin_longjmp(jmpb: ptr pointer, retval: cint) {. importc: "__builtin_longjmp", nodecl.} # The second parameter needs to be 1 and sometimes the C/C++ compiler checks it. - c_builtin_longjmp(addr jmpb[0], 1) + c_builtin_longjmp(unsafeAddr jmpb[0], 1) proc c_setjmp*(jmpb: C_JmpBuf): cint = proc c_builtin_setjmp(jmpb: ptr pointer): cint {. importc: "__builtin_setjmp", nodecl.} - c_builtin_setjmp(addr jmpb[0]) + c_builtin_setjmp(unsafeAddr jmpb[0]) elif defined(nimRawSetjmp) and not defined(nimStdSetjmp): when defined(windows): # No `_longjmp()` on Windows. diff --git a/lib/system/atomics.nim b/lib/system/atomics.nim index 1f25d0b24126..8d29c287dede 100644 --- a/lib/system/atomics.nim +++ b/lib/system/atomics.nim @@ -308,7 +308,7 @@ static int __tcc_cas(int *ptr, int oldVal, int newVal) tcc_cas(cast[ptr int](p), cast[int](oldValue), cast[int](newValue)) elif declared(atomicCompareExchangeN): proc cas*[T: bool|int|ptr](p: ptr T; oldValue, newValue: T): bool = - atomicCompareExchangeN(p, oldValue.addr, newValue, false, ATOMIC_SEQ_CST, ATOMIC_SEQ_CST) + atomicCompareExchangeN(p, oldValue.unsafeAddr, newValue, false, ATOMIC_SEQ_CST, ATOMIC_SEQ_CST) else: # this is valid for GCC and Intel C++ proc cas*[T: bool|int|ptr](p: ptr T; oldValue, newValue: T): bool diff --git a/lib/system/channels_builtin.nim b/lib/system/channels_builtin.nim index 8a920a06ff54..30267e375227 100644 --- a/lib/system/channels_builtin.nim +++ b/lib/system/channels_builtin.nim @@ -366,7 +366,7 @@ proc sendImpl(q: PRawChannel, typ: PNimType, msg: pointer, noBlock: bool): bool proc send*[TMsg](c: var Channel[TMsg], msg: sink TMsg) {.inline.} = ## Sends a message to a thread. `msg` is deeply copied. - discard sendImpl(cast[PRawChannel](addr c), cast[PNimType](getTypeInfo(msg)), addr(msg), false) + discard sendImpl(cast[PRawChannel](addr c), cast[PNimType](getTypeInfo(msg)), unsafeAddr(msg), false) when defined(gcDestructors): wasMoved(msg) @@ -377,7 +377,7 @@ proc trySend*[TMsg](c: var Channel[TMsg], msg: sink TMsg): bool {.inline.} = ## ## Returns `false` if the message was not sent because number of pending items ## in the channel exceeded `maxItems`. - result = sendImpl(cast[PRawChannel](addr c), cast[PNimType](getTypeInfo(msg)), addr(msg), true) + result = sendImpl(cast[PRawChannel](addr c), cast[PNimType](getTypeInfo(msg)), unsafeAddr(msg), true) when defined(gcDestructors): if result: wasMoved(msg) diff --git a/lib/system/io.nim b/lib/system/io.nim index 3f64a851e742..661d1a9ba1fd 100644 --- a/lib/system/io.nim +++ b/lib/system/io.nim @@ -251,7 +251,7 @@ when defined(windows): break inc i else: - let w = c_fprintf(f, "%s", addr s[i]) + let w = c_fprintf(f, "%s", unsafeAddr s[i]) if w <= 0: if doRaise: raiseEIO("cannot write string to file") break @@ -896,7 +896,7 @@ proc writeFile*(filename: string, content: openArray[byte]) {.since: (1, 1).} = var f: File = nil if open(f, filename, fmWrite): try: - f.writeBuffer(addr content[0], content.len) + f.writeBuffer(unsafeAddr content[0], content.len) finally: close(f) else: diff --git a/lib/system/repr_v2.nim b/lib/system/repr_v2.nim index 25290b9c5bb5..6ab5f3c3f744 100644 --- a/lib/system/repr_v2.nim +++ b/lib/system/repr_v2.nim @@ -90,7 +90,7 @@ proc repr*(p: pointer): string = proc repr*(p: proc): string = ## repr of a proc as its address - repr(cast[ptr pointer](addr p)[]) + repr(cast[ptr pointer](unsafeAddr p)[]) template repr*(x: distinct): string = repr(distinctBase(typeof(x))(x)) diff --git a/lib/system/sets.nim b/lib/system/sets.nim index 94e1dd2edbda..103c8d343ebe 100644 --- a/lib/system/sets.nim +++ b/lib/system/sets.nim @@ -18,7 +18,7 @@ proc cardSet(s: NimSet, len: int): int {.compilerproc, inline.} = result = 0 when defined(x86) or defined(amd64): while i < len - 8: - inc(result, countBits64((cast[ptr uint64](s[i].addr))[])) + inc(result, countBits64((cast[ptr uint64](s[i].unsafeAddr))[])) inc(i, 8) while i < len: diff --git a/lib/system/strmantle.nim b/lib/system/strmantle.nim index db8a9f6de30f..9cf4f9e55f75 100644 --- a/lib/system/strmantle.nim +++ b/lib/system/strmantle.nim @@ -17,7 +17,7 @@ proc cmpStrings(a, b: string): int {.inline, compilerproc.} = let blen = b.len let minlen = min(alen, blen) if minlen > 0: - result = c_memcmp(addr a[0], addr b[0], cast[csize_t](minlen)) + result = c_memcmp(unsafeAddr a[0], unsafeAddr b[0], cast[csize_t](minlen)) if result == 0: result = alen - blen else: @@ -28,7 +28,7 @@ proc eqStrings(a, b: string): bool {.inline, compilerproc.} = let blen = b.len if alen == blen: if alen == 0: return true - return equalMem(addr(a[0]), addr(b[0]), alen) + return equalMem(unsafeAddr(a[0]), unsafeAddr(b[0]), alen) proc hashString(s: string): int {.compilerproc.} = # the compiler needs exactly the same hash function! diff --git a/lib/system/strs_v2.nim b/lib/system/strs_v2.nim index 45d3c630a6c4..6944cdc589df 100644 --- a/lib/system/strs_v2.nim +++ b/lib/system/strs_v2.nim @@ -51,7 +51,7 @@ proc prepareAdd(s: var NimStringV2; addlen: int) {.compilerRtl.} = s.p.cap = newLen if s.len > 0: # we are about to append, so there is no need to copy the \0 terminator: - copyMem(addr s.p.data[0], addr oldP.data[0], min(s.len, newLen)) + copyMem(unsafeAddr s.p.data[0], unsafeAddr oldP.data[0], min(s.len, newLen)) else: let oldCap = s.p.cap and not strlitFlag if newLen > oldCap: @@ -80,7 +80,7 @@ proc toNimStr(str: cstring, len: int): NimStringV2 {.compilerproc.} = p.cap = len if len > 0: # we are about to append, so there is no need to copy the \0 terminator: - copyMem(addr p.data[0], str, len) + copyMem(unsafeAddr p.data[0], str, len) result = NimStringV2(len: len, p: p) proc cstrToNimstr(str: cstring): NimStringV2 {.compilerRtl.} = @@ -89,12 +89,12 @@ proc cstrToNimstr(str: cstring): NimStringV2 {.compilerRtl.} = proc nimToCStringConv(s: NimStringV2): cstring {.compilerproc, nonReloadable, inline.} = if s.len == 0: result = cstring"" - else: result = cstring(addr s.p.data) + else: result = cstring(unsafeAddr s.p.data) proc appendString(dest: var NimStringV2; src: NimStringV2) {.compilerproc, inline.} = if src.len > 0: # also copy the \0 terminator: - copyMem(addr dest.p.data[dest.len], addr src.p.data[0], src.len+1) + copyMem(unsafeAddr dest.p.data[dest.len], unsafeAddr src.p.data[0], src.len+1) inc dest.len, src.len proc appendChar(dest: var NimStringV2; c: char) {.compilerproc, inline.} = @@ -153,7 +153,7 @@ proc nimAsgnStrV2(a: var NimStringV2, b: NimStringV2) {.compilerRtl.} = a.p = cast[ptr NimStrPayload](alloc0(contentSize(b.len))) a.p.cap = b.len a.len = b.len - copyMem(addr a.p.data[0], addr b.p.data[0], b.len+1) + copyMem(unsafeAddr a.p.data[0], unsafeAddr b.p.data[0], b.len+1) proc nimPrepareStrMutationImpl(s: var NimStringV2) = let oldP = s.p @@ -163,7 +163,7 @@ proc nimPrepareStrMutationImpl(s: var NimStringV2) = else: s.p = cast[ptr NimStrPayload](alloc0(contentSize(s.len))) s.p.cap = s.len - copyMem(addr s.p.data[0], addr oldP.data[0], s.len+1) + copyMem(unsafeAddr s.p.data[0], unsafeAddr oldP.data[0], s.len+1) proc nimPrepareStrMutationV2(s: var NimStringV2) {.compilerRtl, inline.} = if s.p != nil and (s.p.cap and strlitFlag) == strlitFlag: @@ -173,5 +173,5 @@ proc prepareMutation*(s: var string) {.inline.} = # string literals are "copy on write", so you need to call # `prepareMutation` before modifying the strings via `addr`. {.cast(noSideEffect).}: - let s = addr s + let s = unsafeAddr s nimPrepareStrMutationV2(cast[ptr NimStringV2](s)[]) diff --git a/lib/system/sysstr.nim b/lib/system/sysstr.nim index 19458368f233..49fff41e9ee7 100644 --- a/lib/system/sysstr.nim +++ b/lib/system/sysstr.nim @@ -163,7 +163,7 @@ proc addChar(s: NimString, c: char): NimString = when defined(nimIncrSeqV3): result = rawNewStringNoInit(r) result.len = s.len - copyMem(addr result.data[0], addr(s.data[0]), s.len+1) + copyMem(addr result.data[0], unsafeAddr(s.data[0]), s.len+1) else: result = cast[NimString](growObj(result, sizeof(TGenericSeq) + r + 1)) @@ -213,7 +213,7 @@ proc resizeString(dest: NimString, addlen: int): NimString {.compilerRtl.} = when defined(nimIncrSeqV3): result = rawNewStringNoInit(sp) result.len = dest.len - copyMem(addr result.data[0], addr(dest.data[0]), dest.len+1) + copyMem(addr result.data[0], unsafeAddr(dest.data[0]), dest.len+1) else: result = cast[NimString](growObj(dest, sizeof(TGenericSeq) + sp + 1)) result.reserved = sp @@ -242,7 +242,7 @@ proc setLengthStr(s: NimString, newLen: int): NimString {.compilerRtl.} = when defined(nimIncrSeqV3): result = rawNewStringNoInit(sp) result.len = s.len - copyMem(addr result.data[0], addr(s.data[0]), s.len+1) + copyMem(addr result.data[0], unsafeAddr(s.data[0]), s.len+1) zeroMem(addr result.data[s.len], newLen - s.len) result.reserved = sp else: From 51881c7928259da71d7db5e9ac8cf0492e7812f8 Mon Sep 17 00:00:00 2001 From: flywind Date: Fri, 14 Jan 2022 09:29:12 +0800 Subject: [PATCH 8/8] doc changes; thanks to @konsumlamm Co-authored-by: konsumlamm <44230978+konsumlamm@users.noreply.github.com> --- doc/manual.rst | 2 +- lib/system.nim | 20 ++++++++++---------- 2 files changed, 11 insertions(+), 11 deletions(-) diff --git a/doc/manual.rst b/doc/manual.rst index 2b7545b62a70..6cbc2c0b8b0d 100644 --- a/doc/manual.rst +++ b/doc/manual.rst @@ -3522,7 +3522,7 @@ or a `for` loop variable can be accomplished too: The unsafeAddr operator ----------------------- -The unsafeAddr operator is an alias for the addr operator and is deprecated: +The `unsafeAddr` operator is a deprecated alias for the `addr` operator: .. code-block:: nim let myArray = [1, 2, 3] diff --git a/lib/system.nim b/lib/system.nim index 1fa76357405f..3b3e28344cbb 100644 --- a/lib/system.nim +++ b/lib/system.nim @@ -194,11 +194,11 @@ proc `addr`*[T](x: T): ptr T {.magic: "Addr", noSideEffect.} = ## Builtin `addr` operator for taking the address of a memory location. ## ## .. note:: This works for `let` variables or parameters - ## for better interop with C. When you use it to write a wrapper - ## for a C library and take the address of `let` variables or parameters, - ## you should always check that the original library - ## does never write to data behind the pointer that is returned from - ## this procedure. + ## for better interop with C. When you use it to write a wrapper + ## for a C library and take the address of `let` variables or parameters, + ## you should always check that the original library + ## does never write to data behind the pointer that is returned from + ## this procedure. ## ## Cannot be overloaded. ## @@ -219,11 +219,11 @@ proc unsafeAddr*[T](x: T): ptr T {.magic: "Addr", noSideEffect, ## location. ## ## .. note:: This works for `let` variables or parameters - ## for better interop with C. When you use it to write a wrapper - ## for a C library and take the address of `let` variables or parameters, - ## you should always check that the original library - ## does never write to data behind the pointer that is returned from - ## this procedure. + ## for better interop with C. When you use it to write a wrapper + ## for a C library and take the address of `let` variables or parameters, + ## you should always check that the original library + ## does never write to data behind the pointer that is returned from + ## this procedure. ## ## Cannot be overloaded. discard