diff options
-rw-r--r-- | compiler/cgmeth.nim | 10 | ||||
-rw-r--r-- | lib/pure/segfaults.nim | 4 | ||||
-rw-r--r-- | lib/system.nim | 8 | ||||
-rw-r--r-- | lib/system/chcks.nim | 6 | ||||
-rw-r--r-- | lib/system/jssys.nim | 4 | ||||
-rw-r--r-- | web/news/e031_version_0_16_2.rst | 3 |
6 files changed, 26 insertions, 9 deletions
diff --git a/compiler/cgmeth.nim b/compiler/cgmeth.nim index d05e395b9..e14306e56 100644 --- a/compiler/cgmeth.nim +++ b/compiler/cgmeth.nim @@ -229,6 +229,7 @@ proc genDispatcher(methods: TSymSeq, relevantCols: IntSet): PSym = var base = lastSon(methods[0].ast).sym result = base var paramLen = sonsLen(base.typ) + var nilchecks = newNodeI(nkStmtList, base.info) var disp = newNodeI(nkIfStmt, base.info) var ands = getSysSym("and") var iss = getSysSym("of") @@ -239,7 +240,11 @@ proc genDispatcher(methods: TSymSeq, relevantCols: IntSet): PSym = if contains(relevantCols, col): var isn = newNodeIT(nkCall, base.info, getSysType(tyBool)) addSon(isn, newSymNode(iss)) - addSon(isn, newSymNode(base.typ.n.sons[col].sym)) + let param = base.typ.n.sons[col].sym + addSon(isn, newSymNode(param)) + if param.typ.skipTypes(abstractInst).kind in {tyRef, tyPtr}: + addSon(nilchecks, newTree(nkCall, + newSymNode(getCompilerProc"chckNilDisp"), newSymNode(param))) addSon(isn, newNodeIT(nkType, base.info, curr.typ.sons[col])) if cond != nil: var a = newNodeIT(nkCall, base.info, getSysType(tyBool)) @@ -270,7 +275,8 @@ proc genDispatcher(methods: TSymSeq, relevantCols: IntSet): PSym = addSon(disp, a) else: disp = ret - result.ast.sons[bodyPos] = disp + nilchecks.add disp + result.ast.sons[bodyPos] = nilchecks proc generateMethodDispatchers*(g: ModuleGraph): PNode = result = newNode(nkStmtList) diff --git a/lib/pure/segfaults.nim b/lib/pure/segfaults.nim index 3823d037c..373508430 100644 --- a/lib/pure/segfaults.nim +++ b/lib/pure/segfaults.nim @@ -13,10 +13,6 @@ ## ## Tested on these OSes: Linux, Windows, OSX -type - NilAccessError* = object of SystemError ## \ - ## Raised on dereferences of ``nil`` pointers. - # do allocate memory upfront: var se: ref NilAccessError new(se) diff --git a/lib/system.nim b/lib/system.nim index 94e10d7df..371cf8544 100644 --- a/lib/system.nim +++ b/lib/system.nim @@ -558,6 +558,10 @@ type ## Raised if it is attempted to send a message to a dead thread. ## ## See the full `exception hierarchy <manual.html#exception-handling-exception-hierarchy>`_. + NilAccessError* = object of SystemError ## \ + ## Raised on dereferences of ``nil`` pointers. + ## + ## This is only raised if the ``segfaults.nim`` module was imported! {.deprecated: [TObject: RootObj, PObject: RootRef, TEffect: RootEffect, FTime: TimeEffect, FIO: IOEffect, FReadIO: ReadIOEffect, @@ -2467,8 +2471,8 @@ template accumulateResult*(iter: untyped) = const NimStackTrace = compileOption("stacktrace") template coroutinesSupportedPlatform(): bool = - when defined(sparc) or defined(ELATE) or compileOption("gc", "v2") or - defined(boehmgc) or defined(gogc) or defined(nogc) or defined(gcStack) or + when defined(sparc) or defined(ELATE) or compileOption("gc", "v2") or + defined(boehmgc) or defined(gogc) or defined(nogc) or defined(gcStack) or defined(gcMarkAndSweep): false else: diff --git a/lib/system/chcks.nim b/lib/system/chcks.nim index 27a3708ea..1520f231e 100644 --- a/lib/system/chcks.nim +++ b/lib/system/chcks.nim @@ -50,7 +50,11 @@ proc chckRangeF(x, a, b: float): float = proc chckNil(p: pointer) = if p == nil: - sysFatal(ValueError, "attempt to write to a nil address") + sysFatal(NilAccessError, "attempt to write to a nil address") + +proc chckNilDisp(p: pointer) {.compilerproc.} = + if p == nil: + sysFatal(NilAccessError, "cannot dispatch; dispatcher is nil") proc chckObj(obj, subclass: PNimType) {.compilerproc.} = # checks if obj is of type subclass: diff --git a/lib/system/jssys.nim b/lib/system/jssys.nim index 39ce1183b..9ef4a02f2 100644 --- a/lib/system/jssys.nim +++ b/lib/system/jssys.nim @@ -642,6 +642,10 @@ proc toU32*(a: int64): int32 {.asmNoStackFrame, compilerproc.} = proc nimMin(a, b: int): int {.compilerproc.} = return if a <= b: a else: b proc nimMax(a, b: int): int {.compilerproc.} = return if a >= b: a else: b +proc chckNilDisp(p: pointer) {.compilerproc.} = + if p == nil: + sysFatal(NilAccessError, "cannot dispatch; dispatcher is nil") + type NimString = string # hack for hti.nim include "system/hti" diff --git a/web/news/e031_version_0_16_2.rst b/web/news/e031_version_0_16_2.rst index 35f3716a3..8517dacb0 100644 --- a/web/news/e031_version_0_16_2.rst +++ b/web/news/e031_version_0_16_2.rst @@ -42,6 +42,9 @@ Changes affecting backwards compatibility AST that is the same as what is used to define an enum. Previously the AST returned had a repeated ``EnumTy`` node and was missing the initial pragma node (which is currently empty for an enum). +- If the dispatcher parameter's value used in multi method is ``nil``, + a ``NilError`` exception is raised. The old behavior was that the method + would be a ``nop`` then. Library Additions |