From bdccffbb8e8062f2e7aa4d44378bed9ef8f6498d Mon Sep 17 00:00:00 2001 From: Irmen de Jong Date: Thu, 26 Dec 2024 22:20:08 +0100 Subject: [PATCH] stricter type checking in multivalue assigns, avoids possible invalid output due to missing type cast --- .../compiler/astprocessing/AstChecker.kt | 2 +- compiler/test/ast/TestAstChecks.kt | 27 +++++++++++++++++++ examples/test.p8 | 19 ++++++++++--- 3 files changed, 43 insertions(+), 5 deletions(-) diff --git a/compiler/src/prog8/compiler/astprocessing/AstChecker.kt b/compiler/src/prog8/compiler/astprocessing/AstChecker.kt index 4d5367f87..e256f4fac 100644 --- a/compiler/src/prog8/compiler/astprocessing/AstChecker.kt +++ b/compiler/src/prog8/compiler/astprocessing/AstChecker.kt @@ -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) } } diff --git a/compiler/test/ast/TestAstChecks.kt b/compiler/test/ast/TestAstChecks.kt index b1d83435b..9cfc9728e 100644 --- a/compiler/test/ast/TestAstChecks.kt +++ b/compiler/test/ast/TestAstChecks.kt @@ -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" + } }) diff --git a/examples/test.p8 b/examples/test.p8 index 0c644c39c..0df7cabe6 100644 --- a/examples/test.p8 +++ b/examples/test.p8 @@ -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 + }} } }