fixes #1539
This commit is contained in:
parent
eb69b81859
commit
c2b223688d
4 changed files with 38 additions and 119 deletions
|
|
@ -506,9 +506,7 @@ proc assignLocalVar(p: BProc, s: PSym) =
|
||||||
if sfRegister in s.flags: app(decl, " register")
|
if sfRegister in s.flags: app(decl, " register")
|
||||||
#elif skipTypes(s.typ, abstractInst).kind in GcTypeKinds:
|
#elif skipTypes(s.typ, abstractInst).kind in GcTypeKinds:
|
||||||
# app(decl, " GC_GUARD")
|
# app(decl, " GC_GUARD")
|
||||||
if sfVolatile in s.flags or (p.nestedTryStmts.len > 0 and
|
if sfVolatile in s.flags: app(decl, " volatile")
|
||||||
not p.module.compileToCpp):
|
|
||||||
app(decl, " volatile")
|
|
||||||
appf(decl, " $1;$n", [s.loc.r])
|
appf(decl, " $1;$n", [s.loc.r])
|
||||||
else:
|
else:
|
||||||
decl = ropef(s.cgDeclFrmt & ";$n", decl, s.loc.r)
|
decl = ropef(s.cgDeclFrmt & ";$n", decl, s.loc.r)
|
||||||
|
|
|
||||||
|
|
@ -69,7 +69,7 @@ type
|
||||||
TEffects = object
|
TEffects = object
|
||||||
exc: PNode # stack of exceptions
|
exc: PNode # stack of exceptions
|
||||||
tags: PNode # list of tags
|
tags: PNode # list of tags
|
||||||
bottom: int
|
bottom, inTryStmt: int
|
||||||
owner: PSym
|
owner: PSym
|
||||||
init: seq[int] # list of initialized variables
|
init: seq[int] # list of initialized variables
|
||||||
guards: TModel # nested guards
|
guards: TModel # nested guards
|
||||||
|
|
@ -165,10 +165,17 @@ proc guardDotAccess(a: PEffects; n: PNode) =
|
||||||
else:
|
else:
|
||||||
guardGlobal(a, n, g)
|
guardGlobal(a, n, g)
|
||||||
|
|
||||||
proc initVar(a: PEffects, n: PNode) =
|
proc makeVolatile(a: PEffects; s: PSym) {.inline.} =
|
||||||
|
template compileToCpp(a): expr =
|
||||||
|
gCmd == cmdCompileToCpp or sfCompileToCpp in getModule(a.owner).flags
|
||||||
|
if a.inTryStmt > 0 and not compileToCpp(a):
|
||||||
|
incl(s.flags, sfVolatile)
|
||||||
|
|
||||||
|
proc initVar(a: PEffects, n: PNode; volatileCheck: bool) =
|
||||||
if n.kind != nkSym: return
|
if n.kind != nkSym: return
|
||||||
let s = n.sym
|
let s = n.sym
|
||||||
if isLocalVar(a, s):
|
if isLocalVar(a, s):
|
||||||
|
if volatileCheck: makeVolatile(a, s)
|
||||||
for x in a.init:
|
for x in a.init:
|
||||||
if x == s.id: return
|
if x == s.id: return
|
||||||
a.init.add s.id
|
a.init.add s.id
|
||||||
|
|
@ -179,7 +186,9 @@ proc initVarViaNew(a: PEffects, n: PNode) =
|
||||||
if {tfNeedsInit, tfNotNil} * s.typ.flags <= {tfNotNil}:
|
if {tfNeedsInit, tfNotNil} * s.typ.flags <= {tfNotNil}:
|
||||||
# 'x' is not nil, but that doesn't mean its "not nil" children
|
# 'x' is not nil, but that doesn't mean its "not nil" children
|
||||||
# are initialized:
|
# are initialized:
|
||||||
initVar(a, n)
|
initVar(a, n, volatileCheck=true)
|
||||||
|
elif isLocalVar(a, s):
|
||||||
|
makeVolatile(a, s)
|
||||||
|
|
||||||
proc warnAboutGcUnsafe(n: PNode) =
|
proc warnAboutGcUnsafe(n: PNode) =
|
||||||
#assert false
|
#assert false
|
||||||
|
|
@ -304,7 +313,9 @@ proc trackTryStmt(tracked: PEffects, n: PNode) =
|
||||||
let oldState = tracked.init.len
|
let oldState = tracked.init.len
|
||||||
var inter: TIntersection = @[]
|
var inter: TIntersection = @[]
|
||||||
|
|
||||||
|
inc tracked.inTryStmt
|
||||||
track(tracked, n.sons[0])
|
track(tracked, n.sons[0])
|
||||||
|
dec tracked.inTryStmt
|
||||||
for i in oldState.. <tracked.init.len:
|
for i in oldState.. <tracked.init.len:
|
||||||
addToIntersection(inter, tracked.init[i])
|
addToIntersection(inter, tracked.init[i])
|
||||||
|
|
||||||
|
|
@ -660,7 +671,7 @@ proc track(tracked: PEffects, n: PNode) =
|
||||||
of nkPragma: trackPragmaStmt(tracked, n)
|
of nkPragma: trackPragmaStmt(tracked, n)
|
||||||
of nkAsgn, nkFastAsgn:
|
of nkAsgn, nkFastAsgn:
|
||||||
track(tracked, n.sons[1])
|
track(tracked, n.sons[1])
|
||||||
initVar(tracked, n.sons[0])
|
initVar(tracked, n.sons[0], volatileCheck=true)
|
||||||
invalidateFacts(tracked.guards, n.sons[0])
|
invalidateFacts(tracked.guards, n.sons[0])
|
||||||
track(tracked, n.sons[0])
|
track(tracked, n.sons[0])
|
||||||
addAsgnFact(tracked.guards, n.sons[0], n.sons[1])
|
addAsgnFact(tracked.guards, n.sons[0], n.sons[1])
|
||||||
|
|
@ -672,7 +683,7 @@ proc track(tracked: PEffects, n: PNode) =
|
||||||
if child.kind == nkIdentDefs and last.kind != nkEmpty:
|
if child.kind == nkIdentDefs and last.kind != nkEmpty:
|
||||||
track(tracked, last)
|
track(tracked, last)
|
||||||
for i in 0 .. child.len-3:
|
for i in 0 .. child.len-3:
|
||||||
initVar(tracked, child.sons[i])
|
initVar(tracked, child.sons[i], volatileCheck=false)
|
||||||
addAsgnFact(tracked.guards, child.sons[i], last)
|
addAsgnFact(tracked.guards, child.sons[i], last)
|
||||||
notNilCheck(tracked, last, child.sons[i].typ)
|
notNilCheck(tracked, last, child.sons[i].typ)
|
||||||
# since 'var (a, b): T = ()' is not even allowed, there is always type
|
# since 'var (a, b): T = ()' is not even allowed, there is always type
|
||||||
|
|
|
||||||
110
doc/rst.txt
110
doc/rst.txt
|
|
@ -1,110 +0,0 @@
|
||||||
===========================================================================
|
|
||||||
Nim's implementation of |rst|
|
|
||||||
===========================================================================
|
|
||||||
|
|
||||||
:Author: Andreas Rumpf
|
|
||||||
:Version: |nimversion|
|
|
||||||
|
|
||||||
.. contents::
|
|
||||||
|
|
||||||
Introduction
|
|
||||||
============
|
|
||||||
|
|
||||||
This document describes the subset of `Docutils`_' `reStructuredText`_ as it
|
|
||||||
has been implemented in the Nim compiler for generating documentation.
|
|
||||||
Elements of |rst| that are not listed here have not been implemented.
|
|
||||||
Unfortunately, the specification of |rst| is quite vague, so Nim is not as
|
|
||||||
compatible to the original implementation as one would like.
|
|
||||||
|
|
||||||
Even though Nim's |rst| parser does not parse all constructs, it is pretty
|
|
||||||
usable. The missing features can easily be circumvented. An indication of this
|
|
||||||
fact is that Nim's *whole* documentation itself (including this document) is
|
|
||||||
processed by Nim's |rst| parser. (Which is an order of magnitude faster than
|
|
||||||
Docutils' parser.)
|
|
||||||
|
|
||||||
|
|
||||||
Inline elements
|
|
||||||
===============
|
|
||||||
|
|
||||||
Ordinary text may contain *inline elements*.
|
|
||||||
|
|
||||||
|
|
||||||
Bullet lists
|
|
||||||
============
|
|
||||||
|
|
||||||
*Bullet lists* look like this::
|
|
||||||
|
|
||||||
* Item 1
|
|
||||||
* Item 2 that
|
|
||||||
spans over multiple lines
|
|
||||||
* Item 3
|
|
||||||
* Item 4
|
|
||||||
- bullet lists may nest
|
|
||||||
- item 3b
|
|
||||||
- valid bullet characters are ``+``, ``*`` and ``-``
|
|
||||||
|
|
||||||
This results in:
|
|
||||||
* Item 1
|
|
||||||
* Item 2 that
|
|
||||||
spans over multiple lines
|
|
||||||
* Item 3
|
|
||||||
* Item 4
|
|
||||||
- bullet lists may nest
|
|
||||||
- item 3b
|
|
||||||
- valid bullet characters are ``+``, ``*`` and ``-``
|
|
||||||
|
|
||||||
|
|
||||||
Enumerated lists
|
|
||||||
================
|
|
||||||
|
|
||||||
*Enumerated lists*
|
|
||||||
|
|
||||||
|
|
||||||
Definition lists
|
|
||||||
================
|
|
||||||
|
|
||||||
Save this code to the file "greeting.nim". Now compile and run it:
|
|
||||||
|
|
||||||
``nim run greeting.nim``
|
|
||||||
|
|
||||||
As you see, with the ``run`` command Nim executes the file automatically
|
|
||||||
after compilation. You can even give your program command line arguments by
|
|
||||||
appending them after the filename that is to be compiled and run:
|
|
||||||
|
|
||||||
``nim run greeting.nim arg1 arg2``
|
|
||||||
|
|
||||||
|
|
||||||
Tables
|
|
||||||
======
|
|
||||||
|
|
||||||
Nim only implements simple tables of the form::
|
|
||||||
|
|
||||||
================== =============== ===================
|
|
||||||
header 1 header 2 header n
|
|
||||||
================== =============== ===================
|
|
||||||
Cell 1 Cell 2 Cell 3
|
|
||||||
Cell 4 Cell 5; any Cell 6
|
|
||||||
cell that is
|
|
||||||
not in column 1
|
|
||||||
may span over
|
|
||||||
multiple lines
|
|
||||||
Cell 7 Cell 8 Cell 9
|
|
||||||
================== =============== ===================
|
|
||||||
|
|
||||||
This results in:
|
|
||||||
================== =============== ===================
|
|
||||||
header 1 header 2 header n
|
|
||||||
================== =============== ===================
|
|
||||||
Cell 1 Cell 2 Cell 3
|
|
||||||
Cell 4 Cell 5; any Cell 6
|
|
||||||
cell that is
|
|
||||||
not in column 1
|
|
||||||
may span over
|
|
||||||
multiple lines
|
|
||||||
Cell 7 Cell 8 Cell 9
|
|
||||||
================== =============== ===================
|
|
||||||
|
|
||||||
|
|
||||||
.. |rst| replace:: reStructuredText
|
|
||||||
.. _reStructuredText: http://docutils.sourceforge.net/rst.html#reference-documentation
|
|
||||||
.. _docutils: http://docutils.sourceforge.net/
|
|
||||||
20
tests/ccgbugs/tmissingvolatile.nim
Normal file
20
tests/ccgbugs/tmissingvolatile.nim
Normal file
|
|
@ -0,0 +1,20 @@
|
||||||
|
discard """
|
||||||
|
output: "1"
|
||||||
|
cmd: r"nim c --hints:on $options -d:release $file"
|
||||||
|
ccodecheck: "'NI volatile state;'"
|
||||||
|
"""
|
||||||
|
|
||||||
|
# bug #1539
|
||||||
|
|
||||||
|
proc err() =
|
||||||
|
raise newException(Exception, "test")
|
||||||
|
|
||||||
|
proc main() =
|
||||||
|
var state: int
|
||||||
|
try:
|
||||||
|
state = 1
|
||||||
|
err()
|
||||||
|
except:
|
||||||
|
echo state
|
||||||
|
|
||||||
|
main()
|
||||||
Loading…
Add table
Add a link
Reference in a new issue