mirror of
https://github.com/nim-lang/Nim.git
synced 2026-02-15 07:43:26 +00:00
* fixes #17033 [backport:1.4] * make test robust against stdlib gensym things * cleanup assertions.nim to make topt_no_cursor easier to get right
This commit is contained in:
@@ -57,6 +57,7 @@ type
|
||||
ownsData,
|
||||
preventCursor,
|
||||
isReassigned,
|
||||
isConditionallyReassigned,
|
||||
viewDoesMutate,
|
||||
viewBorrowsFromConst
|
||||
|
||||
@@ -98,6 +99,7 @@ type
|
||||
goals: set[Goal]
|
||||
unanalysableMutation: bool
|
||||
inAsgnSource, inConstructor, inNoSideEffectSection: int
|
||||
inConditional, inLoop: int
|
||||
owner: PSym
|
||||
g: ModuleGraph
|
||||
|
||||
@@ -748,6 +750,13 @@ proc traverse(c: var Partitions; n: PNode) =
|
||||
else:
|
||||
for child in n: traverse(c, child)
|
||||
|
||||
proc markAsReassigned(c: var Partitions; vid: int) {.inline.} =
|
||||
c.s[vid].flags.incl isReassigned
|
||||
if c.inConditional > 0 and c.inLoop > 0:
|
||||
# bug #17033: live ranges with loops and conditionals are too
|
||||
# complex for our current analysis, so we prevent the cursorfication.
|
||||
c.s[vid].flags.incl isConditionallyReassigned
|
||||
|
||||
proc computeLiveRanges(c: var Partitions; n: PNode) =
|
||||
# first pass: Compute live ranges for locals.
|
||||
# **Watch out!** We must traverse the tree like 'traverse' does
|
||||
@@ -777,7 +786,7 @@ proc computeLiveRanges(c: var Partitions; n: PNode) =
|
||||
if n[1].kind == nkSym and (c.s[vid].reassignedTo == 0 or c.s[vid].reassignedTo == n[1].sym.id):
|
||||
c.s[vid].reassignedTo = n[1].sym.id
|
||||
else:
|
||||
c.s[vid].flags.incl isReassigned
|
||||
markAsReassigned(c, vid)
|
||||
|
||||
of nkSym:
|
||||
dec c.abstractTime
|
||||
@@ -804,7 +813,7 @@ proc computeLiveRanges(c: var Partitions; n: PNode) =
|
||||
if not paramType.isCompileTimeOnly and paramType.kind == tyVar:
|
||||
let vid = variableId(c, it.sym)
|
||||
if vid >= 0:
|
||||
c.s[vid].flags.incl isReassigned
|
||||
markAsReassigned(c, vid)
|
||||
|
||||
of nkAddr, nkHiddenAddr:
|
||||
computeLiveRanges(c, n[0])
|
||||
@@ -822,7 +831,13 @@ proc computeLiveRanges(c: var Partitions; n: PNode) =
|
||||
# while cond:
|
||||
# mutate(graph)
|
||||
# connect(graph, cursorVar)
|
||||
inc c.inLoop
|
||||
for child in n: computeLiveRanges(c, child)
|
||||
inc c.inLoop
|
||||
of nkElifBranch, nkElifExpr, nkElse, nkOfBranch:
|
||||
inc c.inConditional
|
||||
for child in n: computeLiveRanges(c, child)
|
||||
dec c.inConditional
|
||||
else:
|
||||
for child in n: computeLiveRanges(c, child)
|
||||
|
||||
@@ -896,7 +911,8 @@ proc computeCursors*(s: PSym; n: PNode; g: ModuleGraph) =
|
||||
var par = computeGraphPartitions(s, n, g, {cursorInference})
|
||||
for i in 0 ..< par.s.len:
|
||||
let v = addr(par.s[i])
|
||||
if v.flags * {ownsData, preventCursor} == {} and v.sym.kind notin {skParam, skResult} and
|
||||
if v.flags * {ownsData, preventCursor, isConditionallyReassigned} == {} and
|
||||
v.sym.kind notin {skParam, skResult} and
|
||||
v.sym.flags * {sfThread, sfGlobal} == {} and hasDestructor(v.sym.typ) and
|
||||
v.sym.typ.skipTypes({tyGenericInst, tyAlias}).kind != tyOwned:
|
||||
let rid = root(par, i)
|
||||
|
||||
@@ -86,13 +86,11 @@ template assert*(cond: untyped, msg = "") =
|
||||
##
|
||||
## No code will be generated for `assert` when passing `-d:danger` (implied by `--assertions:off`).
|
||||
## See `command line switches <nimc.html#compiler-usage-commandminusline-switches>`_.
|
||||
const expr = astToStr(cond)
|
||||
assertImpl(cond, msg, expr, compileOption("assertions"))
|
||||
assertImpl(cond, msg, astToStr(cond), compileOption("assertions"))
|
||||
|
||||
template doAssert*(cond: untyped, msg = "") =
|
||||
## Similar to `assert <#assert.t,untyped,string>`_ but is always turned on regardless of `--assertions`.
|
||||
const expr = astToStr(cond)
|
||||
assertImpl(cond, msg, expr, true)
|
||||
assertImpl(cond, msg, astToStr(cond), true)
|
||||
|
||||
template onFailedAssert*(msg, code: untyped): untyped {.dirty.} =
|
||||
## Sets an assertion failure handler that will intercept any assert
|
||||
|
||||
@@ -3,8 +3,12 @@ discard """
|
||||
doing shady stuff...
|
||||
3
|
||||
6
|
||||
(@[1], @[2])'''
|
||||
cmd: '''nim c --gc:arc --expandArc:newTarget --expandArc:delete --expandArc:p1 --expandArc:tt --hint:Performance:off $file'''
|
||||
(@[1], @[2])
|
||||
192.168.0.1
|
||||
192.168.0.1
|
||||
192.168.0.1
|
||||
192.168.0.1'''
|
||||
cmd: '''nim c --gc:arc --expandArc:newTarget --expandArc:delete --expandArc:p1 --expandArc:tt --hint:Performance:off --assertions:off --expandArc:extractConfig $file'''
|
||||
nimout: '''--expandArc: newTarget
|
||||
|
||||
var
|
||||
@@ -78,6 +82,31 @@ try:
|
||||
finally:
|
||||
`=destroy`(:tmpD_2)
|
||||
`=destroy_1`(a)
|
||||
-- end of expandArc ------------------------
|
||||
--expandArc: extractConfig
|
||||
|
||||
var lan_ip
|
||||
try:
|
||||
lan_ip = ""
|
||||
block :tmp:
|
||||
var line
|
||||
var i = 0
|
||||
let L = len(txt)
|
||||
block :tmp_1:
|
||||
while i < L:
|
||||
var splitted
|
||||
try:
|
||||
line = txt[i]
|
||||
splitted = split(line, " ", -1)
|
||||
if splitted[0] == "opt":
|
||||
`=copy`(lan_ip, splitted[1])
|
||||
echo [lan_ip]
|
||||
echo [splitted[1]]
|
||||
inc(i, 1)
|
||||
finally:
|
||||
`=destroy`(splitted)
|
||||
finally:
|
||||
`=destroy_1`(lan_ip)
|
||||
-- end of expandArc ------------------------'''
|
||||
"""
|
||||
|
||||
@@ -194,3 +223,56 @@ proc plus(input: string) =
|
||||
(rvalue, rnext) = rresult
|
||||
|
||||
plus("123;")
|
||||
|
||||
func substrEq(s: string, pos: int, substr: string): bool =
|
||||
var i = 0
|
||||
var length = substr.len
|
||||
while i < length and pos+i < s.len and s[pos+i] == substr[i]:
|
||||
inc i
|
||||
return i == length
|
||||
|
||||
template stringHasSep(s: string, index: int, sep: string): bool =
|
||||
s.substrEq(index, sep)
|
||||
|
||||
template splitCommon(s, sep, maxsplit, sepLen) =
|
||||
var last = 0
|
||||
var splits = maxsplit
|
||||
|
||||
while last <= len(s):
|
||||
var first = last
|
||||
while last < len(s) and not stringHasSep(s, last, sep):
|
||||
inc(last)
|
||||
if splits == 0: last = len(s)
|
||||
yield substr(s, first, last-1)
|
||||
if splits == 0: break
|
||||
dec(splits)
|
||||
inc(last, sepLen)
|
||||
|
||||
iterator split(s: string, sep: string, maxsplit = -1): string =
|
||||
splitCommon(s, sep, maxsplit, sep.len)
|
||||
|
||||
template accResult(iter: untyped) =
|
||||
result = @[]
|
||||
for x in iter: add(result, x)
|
||||
|
||||
func split*(s: string, sep: string, maxsplit = -1): seq[string] =
|
||||
accResult(split(s, sep, maxsplit))
|
||||
|
||||
|
||||
let txt = @["opt 192.168.0.1", "static_lease 192.168.0.1"]
|
||||
|
||||
# bug #17033
|
||||
|
||||
proc extractConfig() =
|
||||
var lan_ip = ""
|
||||
|
||||
for line in txt:
|
||||
let splitted = line.split(" ")
|
||||
if splitted[0] == "opt":
|
||||
lan_ip = splitted[1] # "borrow" is conditional and inside a loop.
|
||||
# Not good enough...
|
||||
# we need a flag that live-ranges are disjoint
|
||||
echo lan_ip
|
||||
echo splitted[1] # Without this line everything works
|
||||
|
||||
extractConfig()
|
||||
|
||||
Reference in New Issue
Block a user