From f97c0cced020d99cc47a797339982d1b5d2c2a44 Mon Sep 17 00:00:00 2001 From: metagn Date: Thu, 18 Jan 2024 23:14:27 +0300 Subject: [PATCH] error on large integer types as array index range (#23229) fixes #17163, refs #23204 Types that aren't `tyRange` and are bigger than 16 bits, so `int32`, `uint64`, `int` etc, are disallowed as array index range types. `tyRange` is excluded because the max array size is backend independent (except for the specific size of `high(uint64)` which crashes the compiler) and so there should still be an escape hatch for people who want bigger arrays. (cherry picked from commit 3ab8b6b2cf4488c114284aa5ad5b7af0d4055312) --- compiler/semtypes.nim | 9 ++++++--- tests/array/tlargeindex.nim | 18 ++++++++++++++++++ 2 files changed, 24 insertions(+), 3 deletions(-) create mode 100644 tests/array/tlargeindex.nim diff --git a/compiler/semtypes.nim b/compiler/semtypes.nim index 3cf44ebe6d..452863ce1a 100644 --- a/compiler/semtypes.nim +++ b/compiler/semtypes.nim @@ -407,13 +407,16 @@ proc semArray(c: PContext, n: PNode, prev: PType): PType = if indxB.kind in {tyGenericInst, tyAlias, tySink}: indxB = lastSon(indxB) if indxB.kind notin {tyGenericParam, tyStatic, tyFromExpr} and tfUnresolved notin indxB.flags: - if indxB.skipTypes({tyRange}).kind in {tyUInt, tyUInt64}: - discard - elif not isOrdinalType(indxB): + if not isOrdinalType(indxB): localError(c.config, n[1].info, errOrdinalTypeExpected % typeToString(indxB, preferDesc)) elif enumHasHoles(indxB): localError(c.config, n[1].info, "enum '$1' has holes" % typeToString(indxB.skipTypes({tyRange}))) + elif indxB.kind != tyRange and + lengthOrd(c.config, indxB) > high(uint16).int: + # assume range type is intentional + localError(c.config, n[1].info, + "index type '$1' for array is too large" % typeToString(indxB)) base = semTypeNode(c, n[2], nil) # ensure we only construct a tyArray when there was no error (bug #3048): result = newOrPrevType(tyArray, prev, c) diff --git a/tests/array/tlargeindex.nim b/tests/array/tlargeindex.nim new file mode 100644 index 0000000000..61bcbd61d5 --- /dev/null +++ b/tests/array/tlargeindex.nim @@ -0,0 +1,18 @@ +discard """ + cmd: "nim check --hints:off $file" +""" + +# issue #17163 +var e: array[int32, byte] #[tt.Error + ^ index type 'int32' for array is too large]# +var f: array[uint32, byte] #[tt.Error + ^ index type 'uint32' for array is too large]# +var g: array[int64, byte] #[tt.Error + ^ index type 'int64' for array is too large]# +var h: array[uint64, byte] #[tt.Error + ^ index type 'uint64' for array is too large]# + +# crash in issue #23204 +proc y[N](): array[N, int] = default(array[N, int]) #[tt.Error + ^ index type 'int' for array is too large]# +discard y[int]()