Skip to content

Commit

Permalink
fixes #15325 (#15340)
Browse files Browse the repository at this point in the history
  • Loading branch information
Araq authored Sep 16, 2020
1 parent de7f237 commit ae4ede6
Show file tree
Hide file tree
Showing 5 changed files with 144 additions and 4 deletions.
3 changes: 3 additions & 0 deletions compiler/commands.nim
Original file line number Diff line number Diff line change
Expand Up @@ -891,6 +891,9 @@ proc processSwitch*(switch, arg: string, pass: TCmdLinePass, info: TLineInfo;
processOnOffSwitchG(conf, {optProfileVM}, arg, pass, info)
of "sinkinference":
processOnOffSwitch(conf, {optSinkInference}, arg, pass, info)
of "cursorinference":
# undocumented, for debugging purposes only:
processOnOffSwitch(conf, {optCursorInference}, arg, pass, info)
of "panics":
processOnOffSwitchG(conf, {optPanics}, arg, pass, info)
if optPanics in conf.globalOptions:
Expand Down
3 changes: 2 additions & 1 deletion compiler/injectdestructors.nim
Original file line number Diff line number Diff line change
Expand Up @@ -1006,7 +1006,8 @@ proc injectDestructorCalls*(g: ModuleGraph; owner: PSym; n: PNode): PNode =
echoCfg(c.g)
echo n

computeCursors(owner, n, g.config)
if optCursorInference in g.config.options:
computeCursors(owner, n, g.config)

var scope: Scope
let body = p(n, c, scope, normal)
Expand Down
3 changes: 2 additions & 1 deletion compiler/options.nim
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,7 @@ type # please make sure we have under 32 options
optMemTracker,
optNilSeqs,
optSinkInference # 'sink T' inference
optCursorInference


TOptions* = set[TOption]
Expand Down Expand Up @@ -372,7 +373,7 @@ const
DefaultOptions* = {optObjCheck, optFieldCheck, optRangeCheck,
optBoundsCheck, optOverflowCheck, optAssert, optWarns, optRefCheck,
optHints, optStackTrace, optLineTrace, # consider adding `optStackTraceMsgs`
optTrMacros, optStyleCheck}
optTrMacros, optStyleCheck, optCursorInference}
DefaultGlobalOptions* = {optThreadAnalysis,
optExcessiveStackTrace, optListFullPaths}

Expand Down
13 changes: 11 additions & 2 deletions compiler/varpartitions.nim
Original file line number Diff line number Diff line change
Expand Up @@ -392,9 +392,18 @@ proc deps(c: var Partitions; dest, src: PNode) =
analyseAsgn(c, c.s[vid], src)
# do not borrow from a different local variable, this is easier
# than tracking reassignments, consider 'var cursor = local; local = newNode()'
if src.kind == nkSym and (src.sym.kind in {skVar, skResult, skTemp} or
if src.kind == nkSym:
if (src.sym.kind in {skVar, skResult, skTemp} or
(src.sym.kind in {skLet, skParam, skForVar} and hasDisabledAsgn(src.sym.typ))):
c.s[vid].flags.incl preventCursor
c.s[vid].flags.incl preventCursor
elif src.sym.kind in {skVar, skResult, skTemp, skLet, skForVar}:
# XXX: we need to compute variable alive ranges before doing anything else:
let srcid = variableId(c, src.sym)
if srcid >= 0 and preventCursor in c.s[srcid].flags:
# you cannot borrow from a local that lives shorter than 'vid':
if c.s[srcid].aliveStart > c.s[vid].aliveStart or
c.s[srcid].aliveEnd < c.s[vid].aliveEnd:
c.s[vid].flags.incl preventCursor

if src.kind == nkSym and hasDestructor(src.typ):
rhsIsSink(c, src)
Expand Down
126 changes: 126 additions & 0 deletions tests/arc/tcursor_on_localvar.nim
Original file line number Diff line number Diff line change
@@ -0,0 +1,126 @@
discard """
output: '''Section: common
Param: Floats1
Section: local
Param: Str
Param: Bool
Param: Floats2'''
cmd: '''nim c --gc:arc $file'''
"""

# bug #15325

import tables
import strutils

const defaultSection = "***"

type
Config* = ref object
table: OrderedTableRef[string, OrderedTable[string, string]]

# ----------------------------------------------------------------------------------------------------------------------
proc newConfig*(): Config =
result = new(Config)
result.table = newOrderedTable[string, OrderedTable[string, string]]()

# ----------------------------------------------------------------------------------------------------------------------
proc add*(self: Config, param, value, section: string) {.nosinks.} =
let s = if section == "": defaultSection else: section

if not self.table.contains(s):
self.table[s] = initOrderedTable[string, string]()

self.table[s][param] = value

# ----------------------------------------------------------------------------------------------------------------------
proc sections*(self: Config): seq[string] =
for i in self.table.keys:
let s = if i == defaultSection: "" else: i
result.add(s)

# ----------------------------------------------------------------------------------------------------------------------
proc params*(self: Config, section: string): seq[string] =
let s = if section == "": defaultSection else: section

if self.table.contains(s):
for i in self.table[s].keys:
result.add(i)

# ----------------------------------------------------------------------------------------------------------------------
proc extract*(str, start, finish: string): string =
let startPos = str.find(start)

if startPos < 0:
return ""

let endPos = str.find(finish, startPos)

if endPos < 0:
return ""

return str[startPos + start.len() ..< endPos]

# ----------------------------------------------------------------------------------------------------------------------
proc loadString*(self: Config, text: string): tuple[valid: bool, errorInLine: int] {.discardable.} =
self.table.clear()

var data = ""

data = text

var
actualSection = ""
lineCount = 0

for i in splitLines(data):
lineCount += 1

var line = strip(i)

if line.len() == 0:
continue

if line[0] == '#' or line[0] == ';':
continue

if line[0] == '[':
let section = strip(extract(line, "[", "]"))

if section.len() != 0:
actualSection = section
else:
self.table.clear()
return (false, lineCount)
else:
let equal = find(line, '=')

if equal <= 0:
self.table.clear()
return (false, lineCount)
else:
let
param = strip(line[0 .. equal - 1])
value = strip(line[equal + 1 .. ^1])

if param.len() == 0:
self.table.clear()
return (false, lineCount)
else:
self.add(param, value, actualSection)

return (true, 0)

# ----------------------------------------------------------------------------------------------------------------------
when isMainModule:
var cfg = newConfig()

cfg.loadString("[common]\nFloats1 = 1,2,3\n[local]\nStr = \"String...\"\nBool = true\nFloats2 = 4, 5, 6\n")

for s in cfg.sections():
echo "Section: " & s

for p in cfg.params(s):
echo " Param: " & p


0 comments on commit ae4ede6

Please sign in to comment.