diff options
Diffstat (limited to 'compiler')
-rw-r--r-- | compiler/ccgcalls.nim | 30 | ||||
-rw-r--r-- | compiler/pragmas.nim | 9 | ||||
-rw-r--r-- | compiler/sempass2.nim | 42 | ||||
-rw-r--r-- | compiler/sigmatch.nim | 25 |
4 files changed, 64 insertions, 42 deletions
diff --git a/compiler/ccgcalls.nim b/compiler/ccgcalls.nim index b9fc694cb..fb878a83e 100644 --- a/compiler/ccgcalls.nim +++ b/compiler/ccgcalls.nim @@ -430,15 +430,27 @@ proc genNamedParamCall(p: BProc, ri: PNode, d: var TLoc) = assert(typ.kind == tyProc) var length = sonsLen(ri) assert(sonsLen(typ) == sonsLen(typ.n)) - - if length > 1: - app(pl, genArg(p, ri.sons[1], typ.n.sons[1].sym, ri)) - app(pl, ~" ") - app(pl, op.r) - if length > 2: - app(pl, ~": ") - app(pl, genArg(p, ri.sons[2], typ.n.sons[2].sym, ri)) - for i in countup(3, length-1): + + # don't call 'ropeToStr' here for efficiency: + let pat = ri.sons[0].sym.loc.r.data + internalAssert pat != nil + var start = 3 + if ' ' in pat: + start = 1 + app(pl, op.r) + if length > 1: + app(pl, ~": ") + app(pl, genArg(p, ri.sons[1], typ.n.sons[1].sym, ri)) + start = 2 + else: + if length > 1: + app(pl, genArg(p, ri.sons[1], typ.n.sons[1].sym, ri)) + app(pl, ~" ") + app(pl, op.r) + if length > 2: + app(pl, ~": ") + app(pl, genArg(p, ri.sons[2], typ.n.sons[2].sym, ri)) + for i in countup(start, length-1): assert(sonsLen(typ) == sonsLen(typ.n)) if i >= sonsLen(typ): internalError(ri.info, "varargs for objective C method?") diff --git a/compiler/pragmas.nim b/compiler/pragmas.nim index 90f87696b..78ee490e2 100644 --- a/compiler/pragmas.nim +++ b/compiler/pragmas.nim @@ -735,11 +735,10 @@ proc singlePragma(c: PContext, sym: PSym, n: PNode, i: int, incl(sym.flags, sfProcvar) if sym.typ != nil: incl(sym.typ.flags, tfThread) of wGcSafe: - if optThreadAnalysis in gGlobalOptions: - noVal(it) - if sym.kind != skType: incl(sym.flags, sfThread) - if sym.typ != nil: incl(sym.typ.flags, tfGcSafe) - else: invalidPragma(it) + noVal(it) + if sym.kind != skType: incl(sym.flags, sfThread) + if sym.typ != nil: incl(sym.typ.flags, tfGcSafe) + else: invalidPragma(it) of wPacked: noVal(it) if sym.typ == nil: invalidPragma(it) diff --git a/compiler/sempass2.nim b/compiler/sempass2.nim index ede556a70..3f78629c8 100644 --- a/compiler/sempass2.nim +++ b/compiler/sempass2.nim @@ -194,6 +194,9 @@ proc warnAboutGcUnsafe(n: PNode) = #assert false message(n.info, warnGcUnsafe, renderTree(n)) +template markGcUnsafe(a: PEffects) = + a.gcUnsafe = true + proc useVar(a: PEffects, n: PNode) = let s = n.sym if isLocalVar(a, s): @@ -209,7 +212,7 @@ proc useVar(a: PEffects, n: PNode) = if (tfHasGCedMem in s.typ.flags or s.typ.isGCedMem) and tfGcSafe notin s.typ.flags: if warnGcUnsafe in gNotes: warnAboutGcUnsafe(n) - a.gcUnsafe = true + markGcUnsafe(a) type TIntersection = seq[tuple[id, count: int]] # a simple count table @@ -448,7 +451,7 @@ proc propagateEffects(tracked: PEffects, n: PNode, s: PSym) = if notGcSafe(s.typ) and sfImportc notin s.flags: if warnGcUnsafe in gNotes: warnAboutGcUnsafe(n) - tracked.gcUnsafe = true + markGcUnsafe(tracked) mergeLockLevels(tracked, n, s.getLockLevel) proc notNilCheck(tracked: PEffects, n: PNode, paramType: PType) = @@ -502,13 +505,13 @@ proc trackOperand(tracked: PEffects, n: PNode, paramType: PType) = # assume GcUnsafe unless in its type; 'forward' does not matter: if notGcSafe(op) and not isOwnedProcVar(a, tracked.owner): if warnGcUnsafe in gNotes: warnAboutGcUnsafe(n) - tracked.gcUnsafe = true + markGcUnsafe(tracked) else: mergeEffects(tracked, effectList.sons[exceptionEffects], n) mergeTags(tracked, effectList.sons[tagEffects], n) if notGcSafe(op): if warnGcUnsafe in gNotes: warnAboutGcUnsafe(n) - tracked.gcUnsafe = true + markGcUnsafe(tracked) notNilCheck(tracked, n, paramType) proc breaksBlock(n: PNode): bool = @@ -656,7 +659,7 @@ proc track(tracked: PEffects, n: PNode) = # and it's not a recursive call: if not (a.kind == nkSym and a.sym == tracked.owner): warnAboutGcUnsafe(n) - tracked.gcUnsafe = true + markGcUnsafe(tracked) for i in 1 .. <len(n): trackOperand(tracked, n.sons[i], paramType(op, i)) if a.kind == nkSym and a.sym.magic in {mNew, mNewFinalize, mNewSeq}: # may not look like an assignment, but it is: @@ -825,7 +828,7 @@ proc trackProc*(s: PSym, body: PNode) = # effects already computed? if sfForward in s.flags: return if effects.len == effectListLen: return - + var t: TEffects initEffects(effects, s, t) track(t, body) @@ -849,19 +852,20 @@ proc trackProc*(s: PSym, body: PNode) = # after the check, use the formal spec: effects.sons[tagEffects] = tagsSpec - if optThreadAnalysis in gGlobalOptions: - if sfThread in s.flags and t.gcUnsafe: - if optThreads in gGlobalOptions: - localError(s.info, "'$1' is not GC-safe" % s.name.s) - else: - localError(s.info, warnGcUnsafe2, s.name.s) - if not t.gcUnsafe: s.typ.flags.incl tfGcSafe - if s.typ.lockLevel == UnspecifiedLockLevel: - s.typ.lockLevel = t.maxLockLevel - elif t.maxLockLevel > s.typ.lockLevel: - localError(s.info, - "declared lock level is $1, but real lock level is $2" % - [$s.typ.lockLevel, $t.maxLockLevel]) + if sfThread in s.flags and t.gcUnsafe: + if optThreads in gGlobalOptions and optThreadAnalysis in gGlobalOptions: + localError(s.info, "'$1' is not GC-safe" % s.name.s) + else: + localError(s.info, warnGcUnsafe2, s.name.s) + if not t.gcUnsafe: + s.typ.flags.incl tfGcSafe + if s.typ.lockLevel == UnspecifiedLockLevel: + s.typ.lockLevel = t.maxLockLevel + elif t.maxLockLevel > s.typ.lockLevel: + #localError(s.info, + message(s.info, warnLockLevel, + "declared lock level is $1, but real lock level is $2" % + [$s.typ.lockLevel, $t.maxLockLevel]) proc trackTopLevelStmt*(module: PSym; n: PNode) = if n.kind in {nkPragma, nkMacroDef, nkTemplateDef, nkProcDef, diff --git a/compiler/sigmatch.nim b/compiler/sigmatch.nim index 9a99d5200..00802e69b 100644 --- a/compiler/sigmatch.nim +++ b/compiler/sigmatch.nim @@ -418,7 +418,8 @@ proc procTypeRel(c: var TCandidate, f, a: PType): TTypeRelation = if tfNoSideEffect in f.flags and tfNoSideEffect notin a.flags: return isNone - elif tfThread in f.flags and a.flags * {tfThread, tfNoSideEffect} == {}: + elif tfThread in f.flags and a.flags * {tfThread, tfNoSideEffect} == {} and + optThreadAnalysis in gGlobalOptions: # noSideEffect implies ``tfThread``! return isNone elif f.flags * {tfIterator} != a.flags * {tfIterator}: @@ -1441,13 +1442,14 @@ proc matchesAux(c: PContext, n, nOrig: PNode, return checkConstraint(n.sons[a].sons[1]) if m.baseTypeMatch: - assert(container == nil) + #assert(container == nil) container = newNodeIT(nkBracket, n.sons[a].info, arrayConstr(c, arg)) addSon(container, arg) setSon(m.call, formal.position + 1, container) if f != formalLen - 1: container = nil - else: + else: setSon(m.call, formal.position + 1, arg) + inc f else: # unnamed param if f >= formalLen: @@ -1466,7 +1468,7 @@ proc matchesAux(c: PContext, n, nOrig: PNode, n.sons[a] = prepareOperand(c, formal.typ, n.sons[a]) var arg = paramTypesMatch(m, formal.typ, n.sons[a].typ, n.sons[a], nOrig.sons[a]) - if (arg != nil) and m.baseTypeMatch and (container != nil): + if arg != nil and m.baseTypeMatch and container != nil: addSon(container, arg) incrIndexType(container.typ) else: @@ -1480,7 +1482,7 @@ proc matchesAux(c: PContext, n, nOrig: PNode, internalError(n.sons[a].info, "matches") return formal = m.callee.n.sons[f].sym - if containsOrIncl(marker, formal.position): + if containsOrIncl(marker, formal.position) and container.isNil: # already in namedParams: localError(n.sons[a].info, errCannotBindXTwice, formal.name.s) m.state = csNoMatch @@ -1493,17 +1495,22 @@ proc matchesAux(c: PContext, n, nOrig: PNode, m.state = csNoMatch return if m.baseTypeMatch: - assert(container == nil) - container = newNodeIT(nkBracket, n.sons[a].info, arrayConstr(c, arg)) + #assert(container == nil) + if container.isNil: + container = newNodeIT(nkBracket, n.sons[a].info, arrayConstr(c, arg)) addSon(container, arg) setSon(m.call, formal.position + 1, implicitConv(nkHiddenStdConv, formal.typ, container, m, c)) - if f != formalLen - 1: container = nil + #if f != formalLen - 1: container = nil + + # pick the formal from the end, so that 'x, y, varargs, z' works: + f = max(f, formalLen - n.len + a + 1) else: setSon(m.call, formal.position + 1, arg) + inc(f) + container = nil checkConstraint(n.sons[a]) inc(a) - inc(f) proc semFinishOperands*(c: PContext, n: PNode) = # this needs to be called to ensure that after overloading resolution every |