fix crash in long address-of

This commit is contained in:
Irmen de Jong
2025-11-08 21:09:35 +01:00
parent da3c7f267f
commit afb458a7da
3 changed files with 30 additions and 43 deletions

View File

@@ -306,26 +306,34 @@ main {
(waDeclV as NumericLiteral).number shouldBe 40960.0 (waDeclV as NumericLiteral).number shouldBe 40960.0
} }
test("address of a const uword pointer array expression") { test("address of a const integer pointer array expression") {
val src = """ val src = """
main { main {
sub start() { sub start() {
const uword buffer = 2000 const uword buffer = 2000
const long bufferl = 999999
uword @shared addr = &buffer[2] uword @shared addr = &buffer[2]
long @shared addr2 = &bufferl[2]
const ubyte width = 100 const uword width = 100
ubyte @shared i uword @shared addr3 = &buffer[width]
ubyte @shared j long @shared addr4 = &bufferl[width]
uword @shared addr2 = &buffer[i * width + j]
} }
}""" }"""
val result = compileText(Cx16Target(), true, src, outputDir, writeAssembly = true)!! val result = compileText(Cx16Target(), true, src, outputDir, writeAssembly = true)!!
val st = result.compilerAst.entrypoint.statements val st = result.compilerAst.entrypoint.statements
st.size shouldBe 11 st.size shouldBe 12
val assignAddr = (st[2] as Assignment).value val assignAddr = (st[3] as Assignment).value as NumericLiteral
(assignAddr as NumericLiteral).number shouldBe 2002.0 assignAddr.number shouldBe 2002.0
val assignAddr2 = (st[9] as Assignment).value as BinaryExpression assignAddr.type shouldBe BaseDataType.UWORD
assignAddr2.operator shouldBe "+" val assignAddr2 = (st[5] as Assignment).value as NumericLiteral
assignAddr2.number shouldBe 1000001.0
assignAddr2.type shouldBe BaseDataType.LONG
val assignAddr3 = (st[8] as Assignment).value as NumericLiteral
assignAddr3.number shouldBe 2100
assignAddr3.type shouldBe BaseDataType.UWORD
val assignAddr4 = (st[10] as Assignment).value as NumericLiteral
assignAddr4.number shouldBe 1000099.0
assignAddr4.type shouldBe BaseDataType.LONG
} }
test("out of range const byte and word give correct error") { test("out of range const byte and word give correct error") {

View File

@@ -572,14 +572,15 @@ data class AddressOf(var identifier: IdentifierReference?, var arrayIndex: Array
val index = arrayIndex?.constIndex() val index = arrayIndex?.constIndex()
if (index != null) { if (index != null) {
address += when { address += when {
target.datatype.isUnsignedWord -> index target.datatype.isInteger -> index
target.datatype.isArray -> program.memsizer.memorySize(targetVar.datatype, index) target.datatype.isArray -> program.memsizer.memorySize(targetVar.datatype, index)
else -> throw FatalAstException("need array or uword ptr") else -> throw FatalAstException("need array or ptr")
} }
} else } else
return null return null
} }
return NumericLiteral(BaseDataType.UWORD, address, position) val addressType = if(targetVar.datatype.isLong) BaseDataType.LONG else BaseDataType.UWORD
return NumericLiteral(addressType, address, position)
} }
} }
} }

View File

@@ -1,33 +1,11 @@
%import textio
main { main {
sub start() { sub start() {
ubyte[] array = ['h', 'e', 'l', 'l', 'o', 0] const long buffer = 2000
str name = "hello" const long bufferl = 999999
uword @shared addr = &buffer[2]
name[5] = '!' ; don't do this in real code... long @shared addr2 = &bufferl[2]
name[5] = 0 const long width = 100
name[6] = 99 ; out of bounds uword @shared addr3 = &buffer[width]
name[-1] = 99 ; ok long @shared addr4 = &bufferl[width]
name[-5] = 99 ; ok
cx16.r0L = name[5]
cx16.r1L = name[6] ; out of bounds
cx16.r1L = name[-1] ; ok
cx16.r1L = name[-5] ; ok
array[5] = '!'
array[5] = 0
array[6] = 99 ; out of bounds
array[-1] = 99 ; ok
array[-5] = 99 ; ok
array[-6] = 99 ; ok
cx16.r0L = array[5]
cx16.r1L = array[6] ; out of bounds
cx16.r1L = array[-1] ; ok
cx16.r1L = array[-5] ; ok
cx16.r1L = array[-6] ; ok
} }
} }