diff options
author | Araq <rumpf_a@web.de> | 2014-11-27 09:41:36 +0100 |
---|---|---|
committer | Araq <rumpf_a@web.de> | 2014-11-27 09:41:36 +0100 |
commit | c2b223688d032947dbf9dd28760d9fe89745fe76 (patch) | |
tree | 66bd81a85f6ca93605fba3aba040ef8f8ee274e1 /compiler | |
parent | eb69b81859864d8a47272c397971609e56a6d399 (diff) | |
download | Nim-c2b223688d032947dbf9dd28760d9fe89745fe76.tar.gz |
fixes #1539
Diffstat (limited to 'compiler')
-rw-r--r-- | compiler/cgen.nim | 4 | ||||
-rw-r--r-- | compiler/sempass2.nim | 23 |
2 files changed, 18 insertions, 9 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 |