Compare commits

..

3 Commits

Author SHA1 Message Date
ringabout
c38fab3576 test 2026-03-05 16:11:11 +08:00
ringabout
8e2547a5e2 fixes #25566; {.align.} pragma where each 16-byte-aligned (#25570)
fixes #25566
2026-03-04 09:14:13 +01:00
Ryan McConnell
46cddbccd6 fixes #25572 ICE evaluating closure iter with object conversion (#25575) 2026-03-04 05:45:16 +01:00
9 changed files with 35 additions and 14 deletions

View File

@@ -727,7 +727,7 @@ proc lowerStmtListExprs(ctx: var Ctx, n: PNode, needsSplit: var bool): PNode =
n[0] = ex
result.add(n)
of nkCast, nkHiddenStdConv, nkHiddenSubConv, nkConv, nkObjDownConv,
of nkCast, nkHiddenStdConv, nkHiddenSubConv, nkConv, nkObjDownConv, nkObjUpConv,
nkDerefExpr, nkHiddenDeref:
var ns = false
for i in ord(n.kind == nkCast)..<n.len:

View File

@@ -457,10 +457,10 @@ proc isCapturedVar(n: PNode): bool =
else: result = false
proc passCopyToSink(n: PNode; c: var Con; s: var Scope): PNode =
result = newNodeIT(nkStmtListExpr, n.info, n.typ)
let nTyp = n.typ.skipTypes(tyUserTypeClasses)
let tmp = c.getTemp(s, nTyp, n.info)
if hasDestructorOrAsgn(c, nTyp):
result = newNodeIT(nkStmtListExpr, n.info, n.typ)
let tmp = c.getTemp(s, nTyp, n.info)
let typ = nTyp.skipTypes({tyGenericInst, tyAlias, tySink})
let op = getAttachedOp(c.graph, typ, attachedDup)
if op != nil and tfHasOwned notin typ.flags:
@@ -494,15 +494,15 @@ proc passCopyToSink(n: PNode; c: var Con; s: var Scope): PNode =
if c.inEnsureMove > 0:
localError(c.graph.config, n.info, errFailedMove,
("cannot move '$1', passing '$1' to a sink parameter introduces an implicit copy") % $n)
# Since we know somebody will take over the produced copy, there is
# no need to destroy it.
result.add tmp
else:
if c.graph.config.selectedGC in {gcArc, gcOrc, gcYrc, gcAtomicArc}:
assert(not containsManagedMemory(nTyp))
if nTyp.skipTypes(abstractInst).kind in {tyOpenArray, tyVarargs}:
localError(c.graph.config, n.info, "cannot create an implicit openArray copy to be passed to a sink parameter")
result.add newTree(nkAsgn, tmp, p(n, c, s, normal))
# Since we know somebody will take over the produced copy, there is
# no need to destroy it.
result.add tmp
result = p(n, c, s, normal)
proc isDangerousSeq(t: PType): bool {.inline.} =
let t = t.skipTypes(abstractInst)

View File

@@ -7906,7 +7906,7 @@ alignment requirement of the type are ignored.
main()
```
This pragma has no effect on the JS backend.
This pragma has no effect on the JavaScript backend and may significantly increase memory usage with the `--mm:refc` option.
Noalias pragma

View File

@@ -856,7 +856,7 @@ proc bigChunkAlignOffset(alignment: int): int {.inline.} =
if alignment == 0:
result = 0
else:
result = align(sizeof(BigChunk) + sizeof(Cell), alignment) - sizeof(BigChunk) - sizeof(Cell)
result = align(sizeof(BigChunk) + sizeof(FreeCell), alignment) - sizeof(BigChunk) - sizeof(FreeCell)
proc rawAlloc(a: var MemRegion, requestedSize: int, alignment: int = 0): pointer =
when defined(nimTypeNames):

View File

@@ -59,9 +59,9 @@ else:
when trackAllocationSource:
filename: cstring
line: int
elif useCellIds:
when useCellIds:
id: int
elif defined(cpu32):
when (not trackAllocationSource) and (not useCellIds) and sizeof(int) == 4: # 32-bit only
headerAlignPad: array[8, byte] # so addr(data) ≡ 8 (mod 16)
PCell = ptr Cell

View File

@@ -460,7 +460,7 @@ proc rawNewObj(typ: PNimType, size: int, gch: var GcHeap): pointer =
collectCT(gch)
# Use alignment from typ.base if available, otherwise use MemAlign
let alignment = if typ.kind == tyRef and typ.base != nil and
typ.base.align >= MemAlign: typ.base.align else: 0
typ.base.align > 16: typ.base.align else: 0
var res = cast[PCell](rawAlloc(gch.region, size + sizeof(Cell), alignment))
#gcAssert typ.kind in {tyString, tySequence} or size >= typ.base.size, "size too small"
# Check that the user data (after the Cell header) is properly aligned
@@ -517,7 +517,7 @@ proc newObjRC1(typ: PNimType, size: int): pointer {.compilerRtl, noinline, raise
# Use alignment from typ.base if available, otherwise use MemAlign
let alignment = if typ.kind == tyRef and typ.base != nil and
typ.base.align >= MemAlign: typ.base.align else: 0
typ.base.align > 16: typ.base.align else: 0
var res = cast[PCell](rawAlloc(gch.region, size + sizeof(Cell), alignment))
sysAssert(allocInv(gch.region), "newObjRC1 after rawAlloc")
# Check that the user data (after the Cell header) is properly aligned

View File

@@ -168,4 +168,3 @@ for q in 0..100:
new topArr[i]
topArr[i].m.di.b = q
doAssert(cast[uint](addr topArr[i].m.di) mod uint(alignof(DeepInner)) == 0)

10
tests/align/talign2.nim Normal file
View File

@@ -0,0 +1,10 @@
discard """
matrix: "--mm:refc -d:useGcAssert -d:useSysAssert; --mm:orc"
"""
block:
type U = object
d {.align: 16.}: int8
var e: seq[ref U]
for i in 0 ..< 10000: e.add(new U)
doAssert getTotalMem() <= 1052672 * 2

View File

@@ -0,0 +1,12 @@
discard """
cmd: "nim c $file"
"""
import std/asyncdispatch
type
A {.inheritable.} = ref object
B = ref object of A
method a(x: A): Future[A] {.async, base.} =
B(await a(B()))