stricter type checking in multivalue assigns, avoids possible invalid output due to missing type cast

This commit is contained in:
Irmen de Jong 2024-12-26 22:20:08 +01:00
parent 5a85474712
commit bdccffbb8e
3 changed files with 43 additions and 5 deletions

View File

@ -642,7 +642,7 @@ internal class AstChecker(private val program: Program,
fcallTarget.returntypes.zip(targets).withIndex().forEach { (index, p) ->
val (returnType, target) = p
val targetDt = target.inferType(program).getOrUndef()
if (!target.void && !(returnType isAssignableTo targetDt))
if (!target.void && returnType != targetDt)
errors.err("can't assign returnvalue #${index + 1} to corresponding target; $returnType vs $targetDt", target.position)
}
}

View File

@ -417,4 +417,31 @@ main {
errors.errors[1] shouldContain ":6:16: argument 1 type mismatch"
errors.errors[2] shouldContain ":12:16: this pass-by-reference type can't be used as a parameter type"
}
test("proper type checking for multi-value assigns") {
val src="""
main {
sub start() {
bool bb
ubyte ub
uword uw
uw, void = thing2()
uw, bb = thing2()
uw, ub = thing2()
}
asmsub thing2() -> ubyte @A, bool @Pc {
%asm {{
rts
}}
}
}"""
val errors = ErrorReporterForTests()
compileText(C64Target(), false, src, writeAssembly = false, errors = errors) shouldBe null
errors.errors.size shouldBe 4
errors.errors[0] shouldContain "can't assign returnvalue #1 to corresponding target; ubyte vs uword"
errors.errors[1] shouldContain "can't assign returnvalue #1 to corresponding target; ubyte vs uword"
errors.errors[2] shouldContain "can't assign returnvalue #1 to corresponding target; ubyte vs uword"
errors.errors[3] shouldContain "can't assign returnvalue #2 to corresponding target; bool vs ubyte"
}
})

View File

@ -1,11 +1,22 @@
%import textio
%zeropage basicsafe
%option no_sysinit
main {
sub start() {
txt.plot(20,5)
txt.print("hello")
bool bb
ubyte ub
uword uw
uw, void = thing2()
uw, bb = thing2()
uw, ub = thing2()
}
asmsub thing2() -> ubyte @A, bool @Pc {
%asm {{
lda #$aa
clc
rts
}}
}
}