Skip to content

Commit 28c198a

Browse files
committed
fix #15704 #15597 wrong VM register was freed
1 parent e18fc69 commit 28c198a

File tree

2 files changed

+131
-1
lines changed

2 files changed

+131
-1
lines changed

compiler/vmgen.nim

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1515,7 +1515,7 @@ proc genAsgn(c: PCtx; le, ri: PNode; requiresCopy: bool) =
15151515
let idx = genField(c, le[1])
15161516
let tmp = c.genx(ri)
15171517
c.preventFalseAlias(le, opcWrObj, dest, idx, tmp)
1518-
c.freeTemp(idx)
1518+
# c.freeTemp(idx) # BUGFIX: idx is an immediate (field position), not a register
15191519
c.freeTemp(tmp)
15201520
c.freeTemp(dest)
15211521
of nkDerefExpr, nkHiddenDeref:

tests/vm/tvmmisc.nim

Lines changed: 130 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -281,3 +281,133 @@ block: # bug #8007
281281
# OK with seq & object variants
282282
const d = @[Cost(kind: Fixed, cost: 999), Cost(kind: Dynamic, handler: foo)]
283283
doAssert $d == "@[(kind: Fixed, cost: 999), (kind: Dynamic, handler: ...)]"
284+
285+
block: # VM wrong register free causes errors in unrelated code
286+
block: # bug #15597
287+
#[
288+
Error: unhandled exception: 'sym' is not accessible using discriminant 'kind' of type 'TNode' [FieldDefect]
289+
in /Users/timothee/git_clone/nim/Nim_prs/compiler/vm.nim(1176) rawExecute
290+
in opcIndCall
291+
in let prc = if not isClosure: bb.sym else: bb[0].sym
292+
]#
293+
proc bar2(head: string): string = "asdf"
294+
proc gook(u1: int) = discard
295+
296+
type PathEntry = object
297+
kind: int
298+
path: string
299+
300+
iterator globOpt(): int =
301+
var u1: int
302+
303+
gook(u1)
304+
gook(u1)
305+
gook(u1)
306+
gook(u1)
307+
gook(u1)
308+
gook(u1)
309+
gook(u1)
310+
gook(u1)
311+
gook(u1)
312+
gook(u1)
313+
gook(u1)
314+
gook(u1)
315+
gook(u1)
316+
gook(u1)
317+
318+
var entry = PathEntry()
319+
entry.path = bar2("")
320+
if false:
321+
echo "here2"
322+
323+
proc processAux(a: float) = discard
324+
325+
template bar(iter: untyped): untyped =
326+
var ret: float
327+
for x in iter: break
328+
ret
329+
330+
proc main() =
331+
processAux(bar(globOpt()))
332+
static: main()
333+
334+
block: # ditto
335+
# D20201024T133245
336+
type Deque = object
337+
proc initDeque2(initialSize: int = 4): Deque = Deque()
338+
proc len2(a: Deque): int = 2
339+
proc baz(dir: string): bool = true
340+
proc bar2(head: string): string = "asdf"
341+
proc bar3(path: var string) = path = path
342+
343+
type PathEntry = object
344+
kind: int
345+
path: string
346+
347+
proc initGlobOpt(dir: string, a1=false,a2=false,a3=false,a4=false): string = dir
348+
349+
iterator globOpt(dir: string): int =
350+
var stack = initDeque2()
351+
doAssert baz("")
352+
let z = stack.len2
353+
if stack.len2 >= 0:
354+
var entry = PathEntry()
355+
let current = if true: stack.len2 else: stack.len2
356+
entry.path = bar2("")
357+
bar3(entry.path)
358+
if false:
359+
echo "here2" # comment here => you get same error as https://github.com/nim-lang/Nim/issues/15704
360+
361+
proc processAux(a: float) = discard
362+
363+
template bar(iter: untyped): untyped =
364+
var ret: float
365+
for x in iter: break
366+
ret
367+
proc main() =
368+
processAux(bar(globOpt(initGlobOpt("."))))
369+
static: main()
370+
371+
block: # bug #15704
372+
#[
373+
Error: attempt to access a nil address kind: rkFloat
374+
]#
375+
type Deque = object
376+
proc initDeque2(initialSize: int = 4): Deque = Deque()
377+
proc len2(a: Deque): int = 2
378+
379+
proc baz(dir: string): bool = true
380+
proc bar2(head: string): string = "asdf"
381+
proc bar3(path: var string) = path = path
382+
383+
type PathEntry = object
384+
kind: int
385+
path: string
386+
depth: int
387+
388+
proc initGlobOpt(dir: string, a1=false,a2=false,a3=false,a4=false): string =
389+
dir
390+
391+
iterator globOpt(dir: string): int =
392+
var stack = initDeque2()
393+
doAssert baz("")
394+
let z = stack.len2
395+
var a5: int
396+
if stack.len2 >= 0:
397+
var entry = PathEntry()
398+
if false:
399+
echo "here"
400+
let current = if true: stack.len2 else: stack.len2
401+
entry.depth = 1
402+
entry.path = bar2("")
403+
bar3(entry.path)
404+
proc processAux(a: float) = discard
405+
template bar(iter: untyped): untyped =
406+
var ret: float
407+
for x in iter:
408+
break
409+
ret
410+
const dir = "."
411+
proc main() =
412+
processAux(bar(globOpt(initGlobOpt(dir))))
413+
static: main()

0 commit comments

Comments
 (0)