From adedfc3a10ca6fb4b3c2f467b2d1f36da678c164 Mon Sep 17 00:00:00 2001 From: Araq Date: Sat, 11 May 2013 10:53:40 +0200 Subject: new effect system should be sound now --- compiler/sempass2.nim | 13 ++++++++++--- 1 file changed, 10 insertions(+), 3 deletions(-) (limited to 'compiler/sempass2.nim') diff --git a/compiler/sempass2.nim b/compiler/sempass2.nim index 9213bd48d..b78e36531 100644 --- a/compiler/sempass2.nim +++ b/compiler/sempass2.nim @@ -79,6 +79,7 @@ type exc: PNode # stack of exceptions tags: PNode # list of tags bottom: int + owner: PSym PEffects = var TEffects @@ -173,11 +174,16 @@ proc trackTryStmt(tracked: PEffects, n: PNode) = track(tracked, b.sons[blen-1]) tracked.bottom = oldBottom -proc isIndirectCall(n: PNode): bool = +proc isIndirectCall(n: PNode, owner: PSym): bool = # we don't count f(...) as an indirect call if 'f' is an parameter. # Instead we track expressions of type tyProc too. See the manual for # details: - result = n.kind != nkSym or n.sym.kind notin (routineKinds+{skParam}) + if n.kind != nkSym: + result = true + elif n.sym.kind == skParam: + result = owner != n.sym.owner or owner == nil + elif n.sym.kind notin routineKinds: + result = true proc isForwardedProc(n: PNode): bool = result = n.kind == nkSym and sfForward in n.sym.flags @@ -274,7 +280,7 @@ proc track(tracked: PEffects, n: PNode) = elif effectList.len == 0: if isForwardedProc(a): propagateEffects(tracked, n, a.sym) - elif isIndirectCall(a): + elif isIndirectCall(a, tracked.owner): addEffect(tracked, createRaise(n)) addTag(tracked, createTag(n)) else: @@ -355,6 +361,7 @@ proc trackProc*(s: PSym, body: PNode) = var t: TEffects t.exc = effects.sons[exceptionEffects] t.tags = effects.sons[tagEffects] + t.owner = s track(t, body) let p = s.ast.sons[pragmasPos] -- cgit 1.4.1-2-gfad0