Merge pull request #8014 from yglukhov/fix-6803

Fixes #6803
This commit is contained in:
Andreas Rumpf 2018-06-11 23:39:27 +02:00 • committed by GitHub
commit 1c58f31a71
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
3 changed files with 129 additions and 19 deletions

View file

@ -204,27 +204,22 @@ proc freshLineInfo(p: BProc; info: TLineInfo): bool =
result = true result = true
proc genLineDir(p: BProc, t: PNode) = proc genLineDir(p: BProc, t: PNode) =
var tt = t let line = t.info.safeLineNm
#while tt.kind in {nkStmtListExpr}+nkCallKinds:
# tt = tt.lastSon
if tt.kind in nkCallKinds and tt.len > 1:
tt = tt.sons[1]
let line = tt.info.safeLineNm
if optEmbedOrigSrc in p.config.globalOptions: if optEmbedOrigSrc in p.config.globalOptions:
add(p.s(cpsStmts), ~"//" & sourceLine(p.config, tt.info) & "\L") add(p.s(cpsStmts), ~"//" & sourceLine(p.config, t.info) & "\L")
genCLineDir(p.s(cpsStmts), toFullPath(p.config, tt.info), line, p.config) genCLineDir(p.s(cpsStmts), toFullPath(p.config, t.info), line, p.config)
if ({optStackTrace, optEndb} * p.options == {optStackTrace, optEndb}) and if ({optStackTrace, optEndb} * p.options == {optStackTrace, optEndb}) and
(p.prc == nil or sfPure notin p.prc.flags): (p.prc == nil or sfPure notin p.prc.flags):
if freshLineInfo(p, tt.info): if freshLineInfo(p, t.info):
linefmt(p, cpsStmts, "#endb($1, $2);$N", linefmt(p, cpsStmts, "#endb($1, $2);$N",
line.rope, makeCString(toFilename(p.config, tt.info))) line.rope, makeCString(toFilename(p.config, t.info)))
elif ({optLineTrace, optStackTrace} * p.options == elif ({optLineTrace, optStackTrace} * p.options ==
{optLineTrace, optStackTrace}) and {optLineTrace, optStackTrace}) and
(p.prc == nil or sfPure notin p.prc.flags) and tt.info.fileIndex != InvalidFileIDX: (p.prc == nil or sfPure notin p.prc.flags) and t.info.fileIndex != InvalidFileIDX:
if freshLineInfo(p, tt.info): if freshLineInfo(p, t.info):
linefmt(p, cpsStmts, "nimln_($1, $2);$n", linefmt(p, cpsStmts, "nimln_($1, $2);$n",
line.rope, quotedFilename(p.config, tt.info)) line.rope, quotedFilename(p.config, t.info))
proc postStmtActions(p: BProc) {.inline.} = proc postStmtActions(p: BProc) {.inline.} =
add(p.s(cpsStmts), p.module.injectStmt) add(p.s(cpsStmts), p.module.injectStmt)

View file

@ -31,6 +31,9 @@ proc semTemplateExpr(c: PContext, n: PNode, s: PSym,
if efNoSemCheck notin flags: result = semAfterMacroCall(c, n, result, s, flags) if efNoSemCheck notin flags: result = semAfterMacroCall(c, n, result, s, flags)
popInfoContext(c.config) popInfoContext(c.config)
# XXX: A more elaborate line info rewrite might be needed
result.info = n.info
proc semFieldAccess(c: PContext, n: PNode, flags: TExprFlags = {}): PNode proc semFieldAccess(c: PContext, n: PNode, flags: TExprFlags = {}): PNode
proc semOperand(c: PContext, n: PNode, flags: TExprFlags = {}): PNode = proc semOperand(c: PContext, n: PNode, flags: TExprFlags = {}): PNode =

View file

@ -1,11 +1,123 @@
discard """ discard """
outputsub: '''tproper_stacktrace.nim(7) tproper_stacktrace''' output: '''ok'''
exitcode: 1
""" """
import strscans, strutils
template fuzzy(x) = proc raiseTestException*() =
echo x[] != 9 raise newException(Exception, "test")
var p: ptr int proc matchStackTrace(actualEntries: openarray[StackTraceEntry], expected: string) =
fuzzy p var expectedEntries = newSeq[StackTraceEntry]()
var i = 0
template checkEqual(actual, expected: typed, subject: string) =
if actual != expected:
echo "Unexpected ", subject, " on line ", i
echo "Actual: ", actual
echo "Expected: ", expected
doAssert(false)
for l in splitLines(expected.strip):
var procname, filename: string
var line: int
if not scanf(l, "$s$w.nim($i) $w", filename, line, procname):
doAssert(false, "Wrong expected stack trace")
checkEqual($actualEntries[i].filename, filename & ".nim", "file name")
if line != 0:
checkEqual(actualEntries[i].line, line, "line number")
checkEqual($actualEntries[i].procname, procname, "proc name")
inc i
doAssert(i == actualEntries.len, "Unexpected number of lines in stack trace")
template verifyStackTrace*(expectedStackTrace: string, body: untyped) =
var verified = false
try:
body
except Exception as e:
verified = true
# echo "Stack trace:"
# echo e.getStackTrace
matchStackTrace(e.getStackTraceEntries(), expectedStackTrace)
doAssert(verified, "No exception was raised")
when isMainModule:
# <-- Align with line 70 in the text editor
block:
proc bar() =
raiseTestException()
proc foo() =
bar()
const expectedStackTrace = """
tproper_stacktrace.nim(86) tproper_stacktrace
tproper_stacktrace.nim(76) foo
tproper_stacktrace.nim(73) bar
tproper_stacktrace.nim(7) raiseTestException
"""
verifyStackTrace expectedStackTrace:
foo()
block:
proc bar(x: int) =
raiseTestException()
template foo(x: int) =
bar(x)
const expectedStackTrace = """
tproper_stacktrace.nim(103) tproper_stacktrace
tproper_stacktrace.nim(90) bar
tproper_stacktrace.nim(7) raiseTestException
"""
verifyStackTrace expectedStackTrace:
var x: int
foo(x)
block: #6803
proc bar(x = 500) =
raiseTestException()
proc foo() =
bar()
const expectedStackTrace = """
tproper_stacktrace.nim(120) tproper_stacktrace
tproper_stacktrace.nim(110) foo
tproper_stacktrace.nim(107) bar
tproper_stacktrace.nim(7) raiseTestException
"""
verifyStackTrace expectedStackTrace:
foo()
echo "ok"