fix silent typecast on return statements that could lose data (word->byte)

This commit is contained in:
Irmen de Jong 2023-06-17 14:44:36 +02:00
parent c0b398e0ce
commit 5da3abe6b4
3 changed files with 35 additions and 7 deletions

View File

@ -380,12 +380,14 @@ class TypecastsAdder(val program: Program, val options: CompilationOptions, val
override fun after(returnStmt: Return, parent: Node): Iterable<IAstModification> { override fun after(returnStmt: Return, parent: Node): Iterable<IAstModification> {
// add a typecast to the return type if it doesn't match the subroutine's signature // add a typecast to the return type if it doesn't match the subroutine's signature
// but only if no data loss occurs
val returnValue = returnStmt.value val returnValue = returnStmt.value
if(returnValue!=null) { if(returnValue!=null) {
val subroutine = returnStmt.definingSubroutine!! val subroutine = returnStmt.definingSubroutine!!
if(subroutine.returntypes.size==1) { if(subroutine.returntypes.size==1) {
val subReturnType = subroutine.returntypes.first() val subReturnType = subroutine.returntypes.first()
if (returnValue.inferType(program) istype subReturnType) val returnDt = returnValue.inferType(program)
if (returnDt istype subReturnType or returnDt.isNotAssignableTo(subReturnType))
return noModifications return noModifications
if (returnValue is NumericLiteral) { if (returnValue is NumericLiteral) {
val cast = returnValue.cast(subroutine.returntypes.single()) val cast = returnValue.cast(subroutine.returntypes.single())

View File

@ -1003,7 +1003,7 @@ main {
} }
test("byte when choices silently converted to word for convenience") { test("byte when choices silently converted to word for convenience") {
var text=""" val text="""
main { main {
sub start() { sub start() {
uword z = 3 uword z = 3
@ -1016,4 +1016,35 @@ main {
}""" }"""
compileText(C64Target(), false, text, writeAssembly = false) shouldNotBe null compileText(C64Target(), false, text, writeAssembly = false) shouldNotBe null
} }
test("returning smaller dt than returndt is ok") {
val text="""
main {
sub start() {
void test()
}
sub test() -> uword {
return cx16.r0L
}
}"""
compileText(C64Target(), false, text, writeAssembly = false) shouldNotBe null
}
test("returning bigger dt than returndt is not ok") {
val text="""
main {
sub start() {
void test()
}
sub test() -> ubyte {
return cx16.r0
}
}"""
val errors=ErrorReporterForTests()
compileText(C64Target(), false, text, writeAssembly = false, errors=errors) shouldBe null
errors.errors.single() shouldContain "doesn't match"
}
}) })

View File

@ -1,11 +1,6 @@
TODO TODO
==== ====
- this should give a compiler error because word returnvalue:
sub atan_coarse_qd(ubyte quadrant, ubyte xdelta, ubyte ydelta) -> ubyte {
return mkword(math.atan(0, 0, xdelta, ydelta), 0) / 2730
}
- vm: fix syscall.ATAN calculation - vm: fix syscall.ATAN calculation
- document some library modules better (diskio, etc) - document some library modules better (diskio, etc)