summary refs log tree commit diff stats
diff options
context:
space:
mode:
-rw-r--r--compiler/cgen.nim4
-rw-r--r--compiler/sempass2.nim23
-rw-r--r--doc/rst.txt110
-rw-r--r--tests/ccgbugs/tmissingvolatile.nim20
4 files changed, 38 insertions, 119 deletions
diff --git a/compiler/cgen.nim b/compiler/cgen.nim
index 51c426d79..c645b81aa 100644
--- a/compiler/cgen.nim
+++ b/compiler/cgen.nim
@@ -506,9 +506,7 @@ proc assignLocalVar(p: BProc, s: PSym) =
     if sfRegister in s.flags: app(decl, " register")
     #elif skipTypes(s.typ, abstractInst).kind in GcTypeKinds:
     #  app(decl, " GC_GUARD")
-    if sfVolatile in s.flags or (p.nestedTryStmts.len > 0 and
-                                 not p.module.compileToCpp):
-      app(decl, " volatile")
+    if sfVolatile in s.flags: app(decl, " volatile")
     appf(decl, " $1;$n", [s.loc.r])
   else:
     decl = ropef(s.cgDeclFrmt & ";$n", decl, s.loc.r)
diff --git a/compiler/sempass2.nim b/compiler/sempass2.nim
index 0d8c7c479..f41e169e3 100644
--- a/compiler/sempass2.nim
+++ b/compiler/sempass2.nim
@@ -69,7 +69,7 @@ type
   TEffects = object
     exc: PNode  # stack of exceptions
     tags: PNode # list of tags
-    bottom: int
+    bottom, inTryStmt: int
     owner: PSym
     init: seq[int] # list of initialized variables
     guards: TModel # nested guards
@@ -165,10 +165,17 @@ proc guardDotAccess(a: PEffects; n: PNode) =
   else:
     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
   let s = n.sym
   if isLocalVar(a, s):
+    if volatileCheck: makeVolatile(a, s)
     for x in a.init:
       if x == s.id: return
     a.init.add s.id
@@ -179,7 +186,9 @@ proc initVarViaNew(a: PEffects, n: PNode) =
   if {tfNeedsInit, tfNotNil} * s.typ.flags <= {tfNotNil}:
     # 'x' is not nil, but that doesn't mean its "not nil" children
     # are initialized:
-    initVar(a, n)
+    initVar(a, n, volatileCheck=true)
+  elif isLocalVar(a, s):
+    makeVolatile(a, s)
 
 proc warnAboutGcUnsafe(n: PNode) =
   #assert false
@@ -304,7 +313,9 @@ proc trackTryStmt(tracked: PEffects, n: PNode) =
   let oldState = tracked.init.len
   var inter: TIntersection = @[]
 
-  track(tracked, n.sons[0])  
+  inc tracked.inTryStmt
+  track(tracked, n.sons[0])
+  dec tracked.inTryStmt
   for i in oldState.. <tracked.init.len:
     addToIntersection(inter, tracked.init[i])
   
@@ -660,7 +671,7 @@ proc track(tracked: PEffects, n: PNode) =
   of nkPragma: trackPragmaStmt(tracked, n)
   of nkAsgn, nkFastAsgn:
     track(tracked, n.sons[1])
-    initVar(tracked, n.sons[0])
+    initVar(tracked, n.sons[0], volatileCheck=true)
     invalidateFacts(tracked.guards, n.sons[0])
     track(tracked, n.sons[0])
     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:
         track(tracked, last)
         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)
           notNilCheck(tracked, last, child.sons[i].typ)
       # since 'var (a, b): T = ()' is not even allowed, there is always type
diff --git a/doc/rst.txt b/doc/rst.txt
deleted file mode 100644
index 1e858d617..000000000
--- a/doc/rst.txt
+++ /dev/null
@@ -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/
diff --git a/tests/ccgbugs/tmissingvolatile.nim b/tests/ccgbugs/tmissingvolatile.nim
new file mode 100644
index 000000000..4d25e5c22
--- /dev/null
+++ b/tests/ccgbugs/tmissingvolatile.nim
@@ -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()