* Make index out of bounds more useful by including the 'bounds'.
* fixes #9880 index out of bounds (remaining cases); revives #10228
* change err msg to: `index 3 not in 0 .. 1`
This commit is contained in:
Timothee Cour 2019-02-10 13:07:11 -08:00 • committed by Andreas Rumpf
commit 4910608394
11 changed files with 88 additions and 36 deletions

View file

@ -27,6 +27,8 @@
include "system/inclrtl.nim"
include "system/hti.nim"
import system/indexerrors
{.pop.}
type
@ -201,14 +203,14 @@ proc `[]`*(x: Any, i: int): Any =
of tyArray:
var bs = x.rawType.base.size
if i >=% x.rawType.size div bs:
raise newException(IndexError, "index out of bounds")
raise newException(IndexError, formatErrorIndexBound(i, x.rawType.size div bs))
return newAny(x.value +!! i*bs, x.rawType.base)
of tySequence:
var s = cast[ppointer](x.value)[]
if s == nil: raise newException(ValueError, "sequence is nil")
var bs = x.rawType.base.size
if i >=% cast[PGenSeq](s).len:
raise newException(IndexError, "index out of bounds")
raise newException(IndexError, formatErrorIndexBound(i, cast[PGenSeq](s).len-1))
return newAny(s +!! (GenericSeqSize+i*bs), x.rawType.base)
else: assert false
@ -218,7 +220,7 @@ proc `[]=`*(x: Any, i: int, y: Any) =
of tyArray:
var bs = x.rawType.base.size
if i >=% x.rawType.size div bs:
raise newException(IndexError, "index out of bounds")
raise newException(IndexError, formatErrorIndexBound(i, x.rawType.size div bs))
assert y.rawType == x.rawType.base
genericAssign(x.value +!! i*bs, y.value, y.rawType)
of tySequence:
@ -226,7 +228,7 @@ proc `[]=`*(x: Any, i: int, y: Any) =
if s == nil: raise newException(ValueError, "sequence is nil")
var bs = x.rawType.base.size
if i >=% cast[PGenSeq](s).len:
raise newException(IndexError, "index out of bounds")
raise newException(IndexError, formatErrorIndexBound(i, cast[PGenSeq](s).len-1))
assert y.rawType == x.rawType.base
genericAssign(s +!! (GenericSeqSize+i*bs), y.value, y.rawType)
else: assert false

View file

@ -12,7 +12,7 @@
type
UncheckedCharArray = UncheckedArray[char]
import system/helpers2
import system/indexerrors
type
Buffer = ptr object

View file

@ -47,7 +47,7 @@
include "system/inclrtl"
import
strutils, pathnorm
strutils, pathnorm, system/indexerrors
const weirdTarget = defined(nimscript) or defined(js)
@ -2551,7 +2551,7 @@ elif defined(windows):
ownArgv = parseCmdLine($getCommandLine())
ownParsedArgv = true
if i < ownArgv.len and i >= 0: return TaintedString(ownArgv[i])
raise newException(IndexError, "invalid index")
raise newException(IndexError, formatErrorIndexBound(i, ownArgv.len-1))
elif defined(genode):
proc paramStr*(i: int): TaintedString =
@ -2570,7 +2570,7 @@ elif not defined(createNimRtl) and
proc paramStr*(i: int): TaintedString {.tags: [ReadIOEffect].} =
# Docstring in nimdoc block.
if i < cmdCount and i >= 0: return TaintedString($cmdLine[i])
raise newException(IndexError, "invalid index")
raise newException(IndexError, formatErrorIndexBound(i, cmdCount-1))
proc paramCount*(): int {.tags: [ReadIOEffect].} =
# Docstring in nimdoc block.

View file

@ -1,7 +1,7 @@
# imported by other modules, unlike helpers.nim which is included
template formatErrorIndexBound*[T](i, a, b: T): string =
"index out of bounds: (a: " & $a & ") <= (i: " & $i & ") <= (b: " & $b & ") "
"index " & $i & " not in " & $a & " .. " & $b
template formatErrorIndexBound*[T](i, n: T): string =
"index out of bounds: (i: " & $i & ") <= (n: " & $n & ") "
formatErrorIndexBound(i, 0, n)

View file

@ -7,6 +7,8 @@
# distribution, for details about the copyright.
#
import system/indexerrors
proc log*(s: cstring) {.importc: "console.log", varargs, nodecl.}
type
@ -157,8 +159,8 @@ proc raiseDivByZero {.exportc: "raiseDivByZero", noreturn, compilerProc.} =
proc raiseRangeError() {.compilerproc, noreturn.} =
raise newException(RangeError, "value out of range")
proc raiseIndexError() {.compilerproc, noreturn.} =
raise newException(IndexError, "index out of bounds")
proc raiseIndexError(i, a, b: int) {.compilerproc, noreturn.} =
raise newException(IndexError, formatErrorIndexBound(int(i), int(a), int(b)))
proc raiseFieldError(f: string) {.compilerproc, noreturn.} =
raise newException(FieldError, f & " is not accessible")
@ -626,7 +628,7 @@ proc arrayConstr(len: int, value: JSRef, typ: PNimType): JSRef {.
proc chckIndx(i, a, b: int): int {.compilerproc.} =
if i >= a and i <= b: return i
else: raiseIndexError()
else: raiseIndexError(i, a, b)
proc chckRange(i, a, b: int): int {.compilerproc.} =
if i >= a and i <= b: return i