From 0c1d595fae32b41085177ee8bd95b7845c7db68c Mon Sep 17 00:00:00 2001 From: Hiroki Noda Date: Tue, 21 Mar 2023 02:41:25 +0900 Subject: [PATCH 01/15] NuttX: use accept4 (#21544) NuttX supports accept4 since https://github.com/apache/nuttx/commit/48c9d1033659603663f6e35587cf27045a130e0d --- lib/posix/posix.nim | 2 +- lib/posix/posix_other.nim | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/lib/posix/posix.nim b/lib/posix/posix.nim index 12fc8fd571..fbe945df33 100644 --- a/lib/posix/posix.nim +++ b/lib/posix/posix.nim @@ -958,7 +958,7 @@ proc `==`*(x, y: SocketHandle): bool {.borrow.} proc accept*(a1: SocketHandle, a2: ptr SockAddr, a3: ptr SockLen): SocketHandle {. importc, header: "", sideEffect.} -when defined(linux) or defined(bsd): +when defined(linux) or defined(bsd) or defined(nuttx): proc accept4*(a1: SocketHandle, a2: ptr SockAddr, a3: ptr SockLen, flags: cint): SocketHandle {.importc, header: "".} diff --git a/lib/posix/posix_other.nim b/lib/posix/posix_other.nim index 1b6734b518..d5e3c782e5 100644 --- a/lib/posix/posix_other.nim +++ b/lib/posix/posix_other.nim @@ -646,7 +646,7 @@ elif defined(nuttx): else: var SO_REUSEPORT* {.importc, header: "".}: cint -when defined(linux) or defined(bsd): +when defined(linux) or defined(bsd) or defined(nuttx): var SOCK_CLOEXEC* {.importc, header: "".}: cint when defined(macosx): From ae06c6623d3bca0f3eb080b4e6f18d2055ca9351 Mon Sep 17 00:00:00 2001 From: Hiroki Noda Date: Tue, 21 Mar 2023 02:43:10 +0900 Subject: [PATCH 02/15] NuttX: use posix_spawn for osproc (#21539) NuttX has standard posix_spawn interface, and can be used with it. * https://nuttx.apache.org/docs/12.0.0/reference/user/01_task_control.html#c.posix_spawn --- lib/posix/posix_other.nim | 10 +++++----- lib/pure/osproc.nim | 10 ++++++---- 2 files changed, 11 insertions(+), 9 deletions(-) diff --git a/lib/posix/posix_other.nim b/lib/posix/posix_other.nim index d5e3c782e5..ea8731405d 100644 --- a/lib/posix/posix_other.nim +++ b/lib/posix/posix_other.nim @@ -10,7 +10,7 @@ when defined(nimHasStyleChecks): {.push styleChecks: off.} -when defined(freertos) or defined(zephyr) or defined(nuttx): +when defined(freertos) or defined(zephyr): const hasSpawnH = false # should exist for every Posix system nowadays hasAioH = false @@ -675,14 +675,14 @@ when defined(haiku): when hasSpawnH: when defined(linux): - # better be safe than sorry; Linux has this flag, macosx doesn't, don't - # know about the other OSes + # better be safe than sorry; Linux has this flag, macosx and NuttX don't, + # don't know about the other OSes - # Non-GNU systems like TCC and musl-libc don't define __USE_GNU, so we + # Non-GNU systems like TCC and musl-libc don't define __USE_GNU, so we # can't get the magic number from spawn.h const POSIX_SPAWN_USEVFORK* = cint(0x40) else: - # macosx lacks this, so we define the constant to be 0 to not affect + # macosx and NuttX lack this, so we define the constant to be 0 to not affect # OR'ing of flags: const POSIX_SPAWN_USEVFORK* = cint(0) diff --git a/lib/pure/osproc.nim b/lib/pure/osproc.nim index 915337f122..e30f1da737 100644 --- a/lib/pure/osproc.nim +++ b/lib/pure/osproc.nim @@ -1053,13 +1053,15 @@ elif not defined(useNimRtl): var mask: Sigset chck sigemptyset(mask) chck posix_spawnattr_setsigmask(attr, mask) - if poDaemon in data.options: - chck posix_spawnattr_setpgroup(attr, 0'i32) + when not defined(nuttx): + if poDaemon in data.options: + chck posix_spawnattr_setpgroup(attr, 0'i32) var flags = POSIX_SPAWN_USEVFORK or POSIX_SPAWN_SETSIGMASK - if poDaemon in data.options: - flags = flags or POSIX_SPAWN_SETPGROUP + when not defined(nuttx): + if poDaemon in data.options: + flags = flags or POSIX_SPAWN_SETPGROUP chck posix_spawnattr_setflags(attr, flags) if not (poParentStreams in data.options): From 741fed716edb163c95475db79b5a1ec95de11fa6 Mon Sep 17 00:00:00 2001 From: Jake Leahy Date: Tue, 21 Mar 2023 04:48:13 +1100 Subject: [PATCH 03/15] Use `analyseIfAddressTaken` logic for checking if address is taken in converter (#21533) * Add a test case There are way more test cases (See all branches of analyseIfAddressTaken but this covers at least a second branch * Port analyseIfAddressTaken from semexprs to sigmatch This was done since we cannot import sem or semexprs (circular import) but we need the rest of the logic. In needs to be done here since the converter isn't semmed afterwards and so we can't just leave the process til later use the version from semexprs * Less hacky solution which has the checking be done in analyseIfAddressTakenInCall This was done instead of the recommendation on removing it since sfAddrTaken is used in places other than the backend * Remove weird whitespace * Still check nkHiddenAddr if we are checking a converter --- compiler/semexprs.nim | 24 +++++++++++++++--------- compiler/sigmatch.nim | 3 +-- tests/converter/t21531.nim | 10 ++++++++++ 3 files changed, 26 insertions(+), 11 deletions(-) create mode 100644 tests/converter/t21531.nim diff --git a/compiler/semexprs.nim b/compiler/semexprs.nim index cfa34fcdc2..f74a72692b 100644 --- a/compiler/semexprs.nim +++ b/compiler/semexprs.nim @@ -787,7 +787,7 @@ proc analyseIfAddressTaken(c: PContext, n: PNode, isOutParam: bool): PNode = else: result = newHiddenAddrTaken(c, n, isOutParam) -proc analyseIfAddressTakenInCall(c: PContext, n: PNode) = +proc analyseIfAddressTakenInCall(c: PContext, n: PNode, isConverter = false) = checkMinSonsLen(n, 1, c.config) const FakeVarParams = {mNew, mNewFinalize, mInc, ast.mDec, mIncl, mExcl, @@ -795,10 +795,15 @@ proc analyseIfAddressTakenInCall(c: PContext, n: PNode) = mAppendSeqElem, mNewSeq, mReset, mShallowCopy, mDeepCopy, mMove, mWasMoved} + template checkIfConverterCalled(c: PContext, n: PNode) = + ## Checks if there is a converter call which wouldn't be checked otherwise + # Call can sometimes be wrapped in a deref + let node = if n.kind == nkHiddenDeref: n[0] else: n + if node.kind == nkHiddenCallConv: + analyseIfAddressTakenInCall(c, node, true) # get the real type of the callee # it may be a proc var with a generic alias type, so we skip over them var t = n[0].typ.skipTypes({tyGenericInst, tyAlias, tySink}) - if n[0].kind == nkSym and n[0].sym.magic in FakeVarParams: # BUGFIX: check for L-Value still needs to be done for the arguments! # note sometimes this is eval'ed twice so we check for nkHiddenAddr here: @@ -813,6 +818,8 @@ proc analyseIfAddressTakenInCall(c: PContext, n: PNode) = discard "allow access within a cast(unsafeAssign) section" else: localError(c.config, it.info, errVarForOutParamNeededX % $it) + # Make sure to still check arguments for converters + c.checkIfConverterCalled(n[i]) # bug #5113: disallow newSeq(result) where result is a 'var T': if n[0].sym.magic in {mNew, mNewFinalize, mNewSeq}: var arg = n[1] #.skipAddr @@ -824,15 +831,14 @@ proc analyseIfAddressTakenInCall(c: PContext, n: PNode) = return for i in 1.. Date: Mon, 20 Mar 2023 18:49:18 +0100 Subject: [PATCH 04/15] Add check for nimMaxJeap on occupied memory + allocation size (#21521) * fix nimMAxHeap checks * move check to alloc pages * remove debug trace * Fix bad indentation How the hell did that pass through CI ? --- lib/system/alloc.nim | 31 ++++++++++++++++++++----------- 1 file changed, 20 insertions(+), 11 deletions(-) diff --git a/lib/system/alloc.nim b/lib/system/alloc.nim index cee70f6774..ac1741ceb5 100644 --- a/lib/system/alloc.nim +++ b/lib/system/alloc.nim @@ -268,6 +268,20 @@ proc getMaxMem(a: var MemRegion): int = # maximum of these both values here: result = max(a.currMem, a.maxMem) +const nimMaxHeap {.intdefine.} = 0 + +proc allocPages(a: var MemRegion, size: int): pointer = + when nimMaxHeap != 0: + if a.occ + size > nimMaxHeap * 1024 * 1024: + raiseOutOfMem() + osAllocPages(size) + +proc tryAllocPages(a: var MemRegion, size: int): pointer = + when nimMaxHeap != 0: + if a.occ + size > nimMaxHeap * 1024 * 1024: + raiseOutOfMem() + osTryAllocPages(size) + proc llAlloc(a: var MemRegion, size: int): pointer = # *low-level* alloc for the memory managers data structures. Deallocation # is done at the end of the allocator's life time. @@ -277,7 +291,7 @@ proc llAlloc(a: var MemRegion, size: int): pointer = # is one page: sysAssert roundup(size+sizeof(LLChunk), PageSize) == PageSize, "roundup 6" var old = a.llmem # can be nil and is correct with nil - a.llmem = cast[PLLChunk](osAllocPages(PageSize)) + a.llmem = cast[PLLChunk](allocPages(a, PageSize)) when defined(nimAvlcorruption): trackLocation(a.llmem, PageSize) incCurrMem(a, PageSize) @@ -453,15 +467,10 @@ when false: it, it.next, it.prev, it.size) it = it.next -const nimMaxHeap {.intdefine.} = 0 - proc requestOsChunks(a: var MemRegion, size: int): PBigChunk = when not defined(emscripten): if not a.blockChunkSizeIncrease: let usedMem = a.occ #a.currMem # - a.freeMem - when nimMaxHeap != 0: - if usedMem > nimMaxHeap * 1024 * 1024: - raiseOutOfMem() if usedMem < 64 * 1024: a.nextChunkSize = PageSize*4 else: @@ -470,11 +479,11 @@ proc requestOsChunks(a: var MemRegion, size: int): PBigChunk = var size = size if size > a.nextChunkSize: - result = cast[PBigChunk](osAllocPages(size)) + result = cast[PBigChunk](allocPages(a, size)) else: - result = cast[PBigChunk](osTryAllocPages(a.nextChunkSize)) + result = cast[PBigChunk](tryAllocPages(a, a.nextChunkSize)) if result == nil: - result = cast[PBigChunk](osAllocPages(size)) + result = cast[PBigChunk](allocPages(a, size)) a.blockChunkSizeIncrease = true else: size = a.nextChunkSize @@ -654,7 +663,7 @@ proc getBigChunk(a: var MemRegion, size: int): PBigChunk = releaseSys a.lock proc getHugeChunk(a: var MemRegion; size: int): PBigChunk = - result = cast[PBigChunk](osAllocPages(size)) + result = cast[PBigChunk](allocPages(a, size)) when RegionHasLock: if not a.lockActive: a.lockActive = true @@ -811,9 +820,9 @@ proc rawAlloc(a: var MemRegion, requestedSize: int): pointer = sysAssert(roundup(65, 8) == 72, "rawAlloc: roundup broken") var size = roundup(requestedSize, MemAlign) sysAssert(size >= sizeof(FreeCell), "rawAlloc: requested size too small") - sysAssert(size >= requestedSize, "insufficient allocated size!") #c_fprintf(stdout, "alloc; size: %ld; %ld\n", requestedSize, size) + if size <= SmallChunkSize-smallChunkOverhead(): # allocate a small block: for small chunks, we use only its next pointer let s = size div MemAlign From fb00b482eb1ed685c93034360467ee76238e6548 Mon Sep 17 00:00:00 2001 From: Ivan Yonchovski Date: Mon, 20 Mar 2023 19:49:59 +0200 Subject: [PATCH 05/15] Avoid calling build_all* when nim binary is present (#21522) - `nimble` will build `nim` using `bin/nim` and if it is already present we can reuse it. --- nim.nimble | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/nim.nimble b/nim.nimble index 380ffbce8f..b0253f66d5 100644 --- a/nim.nimble +++ b/nim.nimble @@ -10,6 +10,8 @@ skipDirs = @["build" , "changelogs" , "ci" , "csources_v2" , "drnim" , "nimdoc", before install: when defined(windows): - exec "build_all.bat" + if not "bin\nim.exe".fileExists: + exec "build_all.bat" else: - exec "./build_all.sh" + if not "bin/nim".fileExists: + exec "./build_all.sh" From 285ea3c48e7b01fe6beecf794e9e8cc904c27889 Mon Sep 17 00:00:00 2001 From: Mark Leyva Date: Mon, 20 Mar 2023 10:50:58 -0700 Subject: [PATCH 06/15] Fix: #21541. Add support for xnVerbatimText (#21542) to text and text= procs. Remove unnecessary LF for xnVerbatimText in $ proc. --- lib/pure/xmltree.nim | 8 ++++---- tests/stdlib/txmltree.nim | 15 +++++++++++++++ 2 files changed, 19 insertions(+), 4 deletions(-) diff --git a/lib/pure/xmltree.nim b/lib/pure/xmltree.nim index 82513bc984..186da4df81 100644 --- a/lib/pure/xmltree.nim +++ b/lib/pure/xmltree.nim @@ -190,7 +190,7 @@ proc text*(n: XmlNode): lent string {.inline.} = assert $c == "" assert c.text == "my comment" - n.expect {xnText, xnComment, xnCData, xnEntity} + n.expect {xnText, xnVerbatimText, xnComment, xnCData, xnEntity} result = n.fText proc `text=`*(n: XmlNode, text: sink string) {.inline.} = @@ -208,7 +208,7 @@ proc `text=`*(n: XmlNode, text: sink string) {.inline.} = e.text = "a new entity text" assert $e == "&a new entity text;" - n.expect {xnText, xnComment, xnCData, xnEntity} + n.expect {xnText, xnVerbatimText, xnComment, xnCData, xnEntity} n.fText = text proc tag*(n: XmlNode): lent string {.inline.} = @@ -735,7 +735,7 @@ proc addImpl(result: var string, n: XmlNode, indent = 0, indWidth = 2, addNewLines = true, lastNodeIsText = false) = proc noWhitespace(n: XmlNode): bool = for i in 0 ..< n.len: - if n[i].kind in {xnText, xnEntity}: return true + if n[i].kind in {xnText, xnVerbatimText, xnEntity}: return true proc addEscapedAttr(result: var string, s: string) = # `addEscaped` alternative with less escaped characters. @@ -784,7 +784,7 @@ proc addImpl(result: var string, n: XmlNode, indent = 0, indWidth = 2, var lastNodeIsText = false for i in 0 ..< n.len: result.addImpl(n[i], indentNext, indWidth, addNewLines, lastNodeIsText) - lastNodeIsText = n[i].kind == xnText + lastNodeIsText = (n[i].kind == xnText) or (n[i].kind == xnVerbatimText) if not n.noWhitespace(): result.addIndent(indent, addNewLines) diff --git a/tests/stdlib/txmltree.nim b/tests/stdlib/txmltree.nim index 4362f5ec32..c878715445 100644 --- a/tests/stdlib/txmltree.nim +++ b/tests/stdlib/txmltree.nim @@ -99,3 +99,18 @@ block: # bug #21290 doAssert s == """ Hola """ + +block: #21541 + let root = <>root() + root.add <>child(newText("hello")) + root.add <>more(newVerbatimText("hola")) + let s = $root + doAssert s == """ + hello + hola +""" + + let temp = newVerbatimText("Hello!") + doAssert temp.text == "Hello!" + temp.text = "Hola!" + doAssert temp.text == "Hola!" From da7833c68bd8a3fea4b380e2a0e84753812450fe Mon Sep 17 00:00:00 2001 From: "Eric N. Vander Weele" Date: Mon, 20 Mar 2023 13:51:31 -0400 Subject: [PATCH 07/15] fixes #21538; expand len template parameter once in newSeqWith (#21543) `len` could contain side effects and may result in different values when substituted twice in the template expansion. Instead, capture the result of substituting `len` once. closes: #21538 --- lib/pure/collections/sequtils.nim | 6 +++--- tests/stdlib/tsequtils.nim | 5 +++++ 2 files changed, 8 insertions(+), 3 deletions(-) diff --git a/lib/pure/collections/sequtils.nim b/lib/pure/collections/sequtils.nim index 1773e827b1..bcdd0879d6 100644 --- a/lib/pure/collections/sequtils.nim +++ b/lib/pure/collections/sequtils.nim @@ -1077,9 +1077,9 @@ template newSeqWith*(len: int, init: untyped): untyped = import std/random var seqRand = newSeqWith(20, rand(1.0)) assert seqRand[0] != seqRand[1] - - var result = newSeq[typeof(init)](len) - for i in 0 ..< len: + let newLen = len + var result = newSeq[typeof(init)](newLen) + for i in 0 ..< newLen: result[i] = init move(result) # refs bug #7295 diff --git a/tests/stdlib/tsequtils.nim b/tests/stdlib/tsequtils.nim index 176c00214b..2b9ef5d6ea 100644 --- a/tests/stdlib/tsequtils.nim +++ b/tests/stdlib/tsequtils.nim @@ -388,6 +388,11 @@ block: # newSeqWith tests seq2D[0][1] = true doAssert seq2D == @[@[true, true], @[true, false], @[false, false], @[false, false]] +block: # bug #21538 + var x: seq[int] = @[2, 4] + var y = newSeqWith(x.pop(), true) + doAssert y == @[true, true, true, true] + block: # mapLiterals tests let x = mapLiterals([0.1, 1.2, 2.3, 3.4], int) doAssert x is array[4, int] From 9df8ca0d8104c5f474dd5184b69446bbb1515242 Mon Sep 17 00:00:00 2001 From: Federico Ceratto Date: Mon, 20 Mar 2023 17:51:58 +0000 Subject: [PATCH 08/15] Add URI parsing warning (#21547) Related to CVE-2021-41259 https://github.com/nim-lang/security/security/advisories/GHSA-3gg2-rw3q-qwgc https://github.com/nim-lang/Nim/pull/19128#issuecomment-1181944367 --- lib/pure/httpclient.nim | 2 ++ lib/pure/uri.nim | 2 ++ 2 files changed, 4 insertions(+) diff --git a/lib/pure/httpclient.nim b/lib/pure/httpclient.nim index d2cf64149f..fd0ef38564 100644 --- a/lib/pure/httpclient.nim +++ b/lib/pure/httpclient.nim @@ -10,6 +10,8 @@ ## This module implements a simple HTTP client that can be used to retrieve ## webpages and other data. ## +## .. warning:: Validate untrusted inputs: URI parsers and getters are not detecting malicious URIs. +## ## Retrieving a website ## ==================== ## diff --git a/lib/pure/uri.nim b/lib/pure/uri.nim index ebc8b90efb..725d5bbd95 100644 --- a/lib/pure/uri.nim +++ b/lib/pure/uri.nim @@ -14,6 +14,8 @@ ## as a locator, a name, or both. The term "Uniform Resource Locator" ## (URL) refers to the subset of URIs. ## +## .. warning:: URI parsers in this module do not perform security validation. +## ## # Basic usage From 274d61865f53e4146518a1f54465785595052ffe Mon Sep 17 00:00:00 2001 From: ringabout <43030857+ringabout@users.noreply.github.com> Date: Tue, 21 Mar 2023 05:42:57 +0800 Subject: [PATCH 09/15] closes #21536; fixes manual (#21552) fixes manual --- doc/manual.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/doc/manual.md b/doc/manual.md index 31c620ca73..98f9d2ec3e 100644 --- a/doc/manual.md +++ b/doc/manual.md @@ -5455,7 +5455,7 @@ more complex type classes: ```nim # create a type class that will match all tuple and object types - type RecordType = tuple or object + type RecordType = (tuple or object) proc printFields[T: RecordType](rec: T) = for key, value in fieldPairs(rec): @@ -5504,7 +5504,7 @@ A type class can be used directly as the parameter's type. ```nim # create a type class that will match all tuple and object types - type RecordType = tuple or object + type RecordType = (tuple or object) proc printFields(rec: RecordType) = for key, value in fieldPairs(rec): From c155e20796a6c1d2d290f76cbc55c3fe872ff86b Mon Sep 17 00:00:00 2001 From: Peter Munch-Ellingsen Date: Mon, 20 Mar 2023 22:43:42 +0100 Subject: [PATCH 10/15] Fix infinite recursion introduced in 7031ea6 [backport 1.6] (#21555) Fix infinite recursion introduced in 7031ea6 --- nimsuggest/nimsuggest.nim | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/nimsuggest/nimsuggest.nim b/nimsuggest/nimsuggest.nim index ce9681975a..685dbedb8d 100644 --- a/nimsuggest/nimsuggest.nim +++ b/nimsuggest/nimsuggest.nim @@ -234,7 +234,7 @@ proc executeNoHooks(cmd: IdeCmd, file, dirtyfile: AbsoluteFile, line, col: int, localError(conf, conf.m.trackPos, "found no symbol at this position " & (conf $ conf.m.trackPos)) proc executeNoHooks(cmd: IdeCmd, file, dirtyfile: AbsoluteFile, line, col: int, graph: ModuleGraph) = - executeNoHooks(cmd, file, dirtyfile, line, col, graph) + executeNoHooks(cmd, file, dirtyfile, line, col, "", graph) proc execute(cmd: IdeCmd, file, dirtyfile: AbsoluteFile, line, col: int; tag: string, graph: ModuleGraph) = From f7e3af0c2d68035a649cf9449cc4e02a7ea59e84 Mon Sep 17 00:00:00 2001 From: Andreas Rumpf Date: Mon, 20 Mar 2023 22:53:13 +0100 Subject: [PATCH 11/15] =?UTF-8?q?mitigates=20#21272;=20but=20it's=20not=20?= =?UTF-8?q?the=20final=20fix=20because=20the=20first=20round=20=E2=80=A6?= =?UTF-8?q?=20(#21462)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit mitigates #21272; but it's not the final fix because the first round of overload resolution should already match --- compiler/semcall.nim | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/compiler/semcall.nim b/compiler/semcall.nim index 54f03026f8..987fd4a13b 100644 --- a/compiler/semcall.nim +++ b/compiler/semcall.nim @@ -338,7 +338,7 @@ proc notFoundError*(c: PContext, n: PNode, errors: CandidateErrors) = if n[0].kind in nkIdentKinds: let ident = considerQuotedIdent(c, n[0], n).s localError(c.config, n.info, errUndeclaredRoutine % ident) - else: + else: localError(c.config, n.info, "expression '$1' cannot be called" % n[0].renderTree) return @@ -630,7 +630,7 @@ proc semOverloadedCall(c: PContext, n, nOrig: PNode, if efExplain notin flags: # repeat the overload resolution, # this time enabling all the diagnostic output (this should fail again) - discard semOverloadedCall(c, n, nOrig, filter, flags + {efExplain}) + result = semOverloadedCall(c, n, nOrig, filter, flags + {efExplain}) elif efNoUndeclared notin flags: notFoundError(c, n, errors) From c814c4d993675551ecf388b6a583c471a1b8bc5e Mon Sep 17 00:00:00 2001 From: ringabout <43030857+ringabout@users.noreply.github.com> Date: Tue, 21 Mar 2023 22:22:07 +0800 Subject: [PATCH 12/15] fixes #3770; templates with untyped parameters resolve private fields wrongly in generics (#21554) * fixes #3770; templates with untyped parameters resolve private fields wrongly * add a test case for #3770 * rename to `nfSkipFieldChecking` --- compiler/ast.nim | 4 ++-- compiler/sem.nim | 8 ++++---- compiler/semgnrc.nim | 22 ++++++++++++++++++++++ compiler/semobjconstr.nim | 4 ++-- compiler/semtypes.nim | 4 ++-- compiler/vmgen.nim | 2 +- tests/generics/m3770.nim | 6 ++++++ tests/generics/t3770.nim | 9 +++++++++ 8 files changed, 48 insertions(+), 11 deletions(-) create mode 100644 tests/generics/m3770.nim create mode 100644 tests/generics/t3770.nim diff --git a/compiler/ast.nim b/compiler/ast.nim index f93c8d9101..b5306c423c 100644 --- a/compiler/ast.nim +++ b/compiler/ast.nim @@ -510,7 +510,7 @@ type nfLastRead # this node is a last read nfFirstWrite # this node is a first write nfHasComment # node has a comment - nfUseDefaultField # node has a default value (object constructor) + nfSkipFieldChecking # node skips field visable checking TNodeFlags* = set[TNodeFlag] TTypeFlag* = enum # keep below 32 for efficiency reasons (now: 46) @@ -1081,7 +1081,7 @@ const nfIsRef, nfIsPtr, nfPreventCg, nfLL, nfFromTemplate, nfDefaultRefsParam, nfExecuteOnReload, nfLastRead, - nfFirstWrite, nfUseDefaultField} + nfFirstWrite, nfSkipFieldChecking} namePos* = 0 patternPos* = 1 # empty except for term rewriting macros genericParamsPos* = 2 diff --git a/compiler/sem.nim b/compiler/sem.nim index 48a7d56c8a..1c15f905e3 100644 --- a/compiler/sem.nim +++ b/compiler/sem.nim @@ -572,7 +572,7 @@ proc defaultFieldsForTuple(c: PContext, recNode: PNode, hasDefault: var bool): s let asgnExpr = defaultNodeField(c, recNode, recNode.typ) if asgnExpr != nil: hasDefault = true - asgnExpr.flags.incl nfUseDefaultField + asgnExpr.flags.incl nfSkipFieldChecking result.add newTree(nkExprColonExpr, recNode, asgnExpr) return @@ -582,7 +582,7 @@ proc defaultFieldsForTuple(c: PContext, recNode: PNode, hasDefault: var bool): s newSymNode(getSysMagic(c.graph, recNode.info, "zeroDefault", mZeroDefault)), newNodeIT(nkType, recNode.info, asgnType) ) - asgnExpr.flags.incl nfUseDefaultField + asgnExpr.flags.incl nfSkipFieldChecking asgnExpr.typ = recType result.add newTree(nkExprColonExpr, recNode, asgnExpr) else: @@ -604,7 +604,7 @@ proc defaultFieldsForTheUninitialized(c: PContext, recNode: PNode): seq[PNode] = defaultValue = newIntNode(nkIntLit#[c.graph]#, 0) defaultValue.typ = discriminator.typ selectedBranch = recNode.pickCaseBranchIndex defaultValue - defaultValue.flags.incl nfUseDefaultField + defaultValue.flags.incl nfSkipFieldChecking result.add newTree(nkExprColonExpr, discriminator, defaultValue) result.add defaultFieldsForTheUninitialized(c, recNode[selectedBranch][^1]) of nkSym: @@ -616,7 +616,7 @@ proc defaultFieldsForTheUninitialized(c: PContext, recNode: PNode): seq[PNode] = let asgnExpr = defaultNodeField(c, recNode, recType) if asgnExpr != nil: asgnExpr.typ = recType - asgnExpr.flags.incl nfUseDefaultField + asgnExpr.flags.incl nfSkipFieldChecking result.add newTree(nkExprColonExpr, recNode, asgnExpr) else: doAssert false diff --git a/compiler/semgnrc.nim b/compiler/semgnrc.nim index 0827e68456..fa37af850a 100644 --- a/compiler/semgnrc.nim +++ b/compiler/semgnrc.nim @@ -78,14 +78,18 @@ proc semGenericStmtSymbol(c: PContext, n: PNode, s: PSym, if macroToExpandSym(s): onUse(n.info, s) result = semTemplateExpr(c, n, s, {efNoSemCheck}) + c.friendModules.add(s.owner.getModule) result = semGenericStmt(c, result, {}, ctx) + discard c.friendModules.pop() else: result = symChoice(c, n, s, scOpen) of skMacro: if macroToExpandSym(s): onUse(n.info, s) result = semMacroExpr(c, n, n, s, {efNoSemCheck}) + c.friendModules.add(s.owner.getModule) result = semGenericStmt(c, result, {}, ctx) + discard c.friendModules.pop() else: result = symChoice(c, n, s, scOpen) of skGenericParam: @@ -245,7 +249,9 @@ proc semGenericStmt(c: PContext, n: PNode, if macroToExpand(s) and sc.safeLen <= 1: onUse(fn.info, s) result = semMacroExpr(c, n, n, s, {efNoSemCheck}) + c.friendModules.add(s.owner.getModule) result = semGenericStmt(c, result, flags, ctx) + discard c.friendModules.pop() else: n[0] = sc result = n @@ -254,7 +260,9 @@ proc semGenericStmt(c: PContext, n: PNode, if macroToExpand(s) and sc.safeLen <= 1: onUse(fn.info, s) result = semTemplateExpr(c, n, s, {efNoSemCheck}) + c.friendModules.add(s.owner.getModule) result = semGenericStmt(c, result, flags, ctx) + discard c.friendModules.pop() else: n[0] = sc result = n @@ -493,6 +501,20 @@ proc semGenericStmt(c: PContext, n: PNode, of nkExprColonExpr, nkExprEqExpr: checkMinSonsLen(n, 2, c.config) result[1] = semGenericStmt(c, n[1], flags, ctx) + of nkObjConstr: + for i in 0.. Date: Tue, 21 Mar 2023 15:24:57 +0100 Subject: [PATCH 13/15] atlas tool: 'update' command (#21557) --- tools/atlas/atlas.md | 6 ++++++ tools/atlas/atlas.nim | 33 ++++++++++++++++++++++++++++++--- 2 files changed, 36 insertions(+), 3 deletions(-) diff --git a/tools/atlas/atlas.md b/tools/atlas/atlas.md index ee770cd626..61ca28ff00 100644 --- a/tools/atlas/atlas.md +++ b/tools/atlas/atlas.md @@ -79,3 +79,9 @@ in its description (or name or list of tags). ### Install Use the .nimble file to setup the project's dependencies. + +### Update [filter] + +Update every package in the workspace that has a remote URL that +matches `filter` if a filter is given. The package is only updated +if there are no uncommitted changes. diff --git a/tools/atlas/atlas.nim b/tools/atlas/atlas.nim index 274e94517e..dfa60856ef 100644 --- a/tools/atlas/atlas.nim +++ b/tools/atlas/atlas.nim @@ -9,9 +9,11 @@ ## Simple tool to automate frequent workflows: Can "clone" ## a Nimble dependency and its dependencies recursively. -import std/[parseopt, strutils, os, osproc, unicode, tables, sets, json, jsonutils] +import std/[parseopt, strutils, os, osproc, tables, sets, json, jsonutils] import parse_requires, osutils, packagesjson +from unicode import nil + const Version = "0.2" Usage = "atlas - Nim Package Cloner Version " & Version & """ @@ -25,6 +27,8 @@ Command: search keyw keywB... search for package that contains the given keywords extract file.nimble extract the requirements and custom commands from the given Nimble file + update [filter] update every package in the workspace that has a remote + URL that matches `filter` if a filter is given Options: --keepCommits do not perform any `git checkouts` @@ -146,7 +150,7 @@ proc toDepRelation(s: string): DepRelation = of ">": strictlyGreater else: normal -proc isCleanGit(c: var AtlasContext; dir: string): string = +proc isCleanGit(c: var AtlasContext): string = result = "" let (outp, status) = exec(c, GitDiff, []) if outp.len != 0: @@ -264,7 +268,7 @@ proc checkoutCommit(c: var AtlasContext; w: Dependency) = if w.commit.len == 0 or cmpIgnoreCase(w.commit, "head") == 0: gitPull(c, w.name) else: - let err = isCleanGit(c, dir) + let err = isCleanGit(c) if err != "": warn c, w.name, err else: @@ -448,6 +452,27 @@ proc installDependencies(c: var AtlasContext; nimbleFile: string) = let paths = cloneLoop(c, work) patchNimCfg(c, paths, if c.cfgHere: getCurrentDir() else: findSrcDir(c)) +proc updateWorkspace(c: var AtlasContext; filter: string) = + for kind, file in walkDir(c.workspace): + if kind == pcDir and dirExists(file / ".git"): + c.withDir file: + let pkg = PackageName(file) + let (remote, _) = osproc.execCmdEx("git remote -v") + if filter.len == 0 or filter in remote: + let diff = isCleanGit(c) + if diff != "": + warn(c, pkg, "has uncommitted changes; skipped") + else: + let (branch, _) = osproc.execCmdEx("git rev-parse --abbrev-ref HEAD") + if branch.strip.len > 0: + let (output, exitCode) = osproc.execCmdEx("git pull origin " & branch.strip) + if exitCode != 0: + error c, pkg, output + else: + message(c, "[Hint] ", pkg, "successfully updated") + else: + error c, pkg, "could not fetch current branch name" + proc main = var action = "" var args: seq[string] = @[] @@ -525,6 +550,8 @@ proc main = of "search", "list": updatePackages(c) search getPackages(c.workspace), args + of "update": + updateWorkspace(c, if args.len == 0: "" else: args[0]) of "extract": singleArg() if fileExists(args[0]): From e8a70ff1794e941a6930c3d240af16a708b59339 Mon Sep 17 00:00:00 2001 From: tersec Date: Wed, 22 Mar 2023 22:05:20 +0100 Subject: [PATCH 14/15] don't access void* out of alignment in refc GC to avoid UB (#21560) --- lib/system/gc_common.nim | 1 - 1 file changed, 1 deletion(-) diff --git a/lib/system/gc_common.nim b/lib/system/gc_common.nim index 54c51e7838..eb08845603 100644 --- a/lib/system/gc_common.nim +++ b/lib/system/gc_common.nim @@ -391,7 +391,6 @@ else: let regEnd = sp +% sizeof(registers) while sp <% regEnd: gcMark(gch, cast[PPointer](sp)[]) - gcMark(gch, cast[PPointer](sp +% sizeof(pointer) div 2)[]) sp = sp +% sizeof(pointer) # Make sure sp is word-aligned sp = sp and not (sizeof(pointer) - 1) From 55636a2913d0b0dec6b24568cb6baef43a9220c1 Mon Sep 17 00:00:00 2001 From: ringabout <43030857+ringabout@users.noreply.github.com> Date: Thu, 23 Mar 2023 23:10:14 +0800 Subject: [PATCH 15/15] fixes #14255; Crash in compiler when using `system.any` by accident. (#21562) fixes #14255; Crash in compiler when using system.any by accident. --- compiler/semexprs.nim | 2 +- tests/arc/t20588.nim | 5 ++++- 2 files changed, 5 insertions(+), 2 deletions(-) diff --git a/compiler/semexprs.nim b/compiler/semexprs.nim index f74a72692b..d3c96ce3c4 100644 --- a/compiler/semexprs.nim +++ b/compiler/semexprs.nim @@ -302,7 +302,7 @@ proc semConv(c: PContext, n: PNode; expectedType: PType = nil): PNode = result = newNodeI(nkConv, n.info) var targetType = semTypeNode(c, n[0], nil) - case targetType.kind + case targetType.skipTypes({tyDistinct}).kind of tyTypeDesc: internalAssert c.config, targetType.len > 0 if targetType.base.kind == tyNone: diff --git a/tests/arc/t20588.nim b/tests/arc/t20588.nim index d747c656d3..008bd1dcd3 100644 --- a/tests/arc/t20588.nim +++ b/tests/arc/t20588.nim @@ -5,6 +5,7 @@ discard """ t20588.nim(20, 12) Error: illegal type conversion to 'auto' t20588.nim(21, 14) Error: illegal type conversion to 'typed' t20588.nim(22, 16) Error: illegal type conversion to 'untyped' +t20588.nim(24, 7) Error: illegal type conversion to 'any' ''' """ @@ -16,7 +17,9 @@ t20588.nim(22, 16) Error: illegal type conversion to 'untyped' - discard 0.0.auto discard typed("abc") discard untyped(4) +var a = newSeq[bool](1000) +if any(a): + echo "ok?" \ No newline at end of file