From f8aaa2d13c95bd147c0afb6a063526449f3ad06d Mon Sep 17 00:00:00 2001 From: Irmen de Jong Date: Tue, 10 Dec 2024 23:19:41 +0100 Subject: [PATCH] explicit integer type check for @R0-R15 parameters avoids weird type inconsistency for boolean parameters that would get aliased as unsigned byte instead invisibly --- .../compiler/astprocessing/AstPreprocessor.kt | 10 +++-- compiler/test/ast/TestAstChecks.kt | 22 ++++++++++ examples/test.p8 | 40 +++++-------------- 3 files changed, 38 insertions(+), 34 deletions(-) diff --git a/compiler/src/prog8/compiler/astprocessing/AstPreprocessor.kt b/compiler/src/prog8/compiler/astprocessing/AstPreprocessor.kt index 1a338b05e..7b5d9b2f2 100644 --- a/compiler/src/prog8/compiler/astprocessing/AstPreprocessor.kt +++ b/compiler/src/prog8/compiler/astprocessing/AstPreprocessor.kt @@ -232,9 +232,13 @@ class AstPreprocessor(val program: Program, .filter { it.name !in namesInSub && it.name !in existingAliases } .forEach { if (it.registerOrPair in Cx16VirtualRegisters) { - val regname = it.registerOrPair!!.asScopedNameVirtualReg(it.type) - var alias = Alias(it.name, IdentifierReference(regname, it.position), it.position) - mods += IAstModification.InsertFirst(alias, subroutine) + if(it.type.isInteger) { + val regname = it.registerOrPair!!.asScopedNameVirtualReg(it.type) + var alias = Alias(it.name, IdentifierReference(regname, it.position), it.position) + mods += IAstModification.InsertFirst(alias, subroutine) + } else { + errors.err("using R0-R15 as register param requires integer type", it.position) + } } else errors.err("can only use R0-R15 as register param for normal subroutines", it.position) } diff --git a/compiler/test/ast/TestAstChecks.kt b/compiler/test/ast/TestAstChecks.kt index 7ce236954..693bb80be 100644 --- a/compiler/test/ast/TestAstChecks.kt +++ b/compiler/test/ast/TestAstChecks.kt @@ -350,4 +350,26 @@ main { errors.warnings[0] shouldContain "footgun" errors.warnings[1] shouldContain "footgun" } + + test("reg params R0-R15 cannot be used for non integer types") { + val src=""" +main { + sub func(bool flag @R1) { + if flag + return + } + + extsub ${'$'}2000 = extok(bool flag @R0) + + sub start() { + func(true) + extok(true) + } +}""" + val errors = ErrorReporterForTests(keepMessagesAfterReporting = true) + compileText(C64Target(), false, src, writeAssembly = false, errors = errors) shouldBe null + errors.errors.size shouldBe 1 + errors.warnings.size shouldBe 0 + errors.errors[0] shouldContain "requires integer type" + } }) diff --git a/examples/test.p8 b/examples/test.p8 index 3d4754d00..c72f5b3cb 100644 --- a/examples/test.p8 +++ b/examples/test.p8 @@ -3,37 +3,15 @@ %option no_sysinit main { + sub func(bool flag @R1) { + if flag + return + } + + extsub $2000 = extok(bool flag @R0) + sub start() { - cx16.r0 = (cx16.r0 & $a000) | $0055 - cx16.r0 = (cx16.r0 | $a000) ^ $0055 - cx16.r0 = (cx16.r0 ^ $a000) & $0055 - - cx16.r0 = (cx16.r1 & $a000) - cx16.r0 = (cx16.r1 | $a000) - cx16.r0 = (cx16.r1 ^ $a000) - - ; these are optimized already: - cx16.r0 = (cx16.r0 & $a000) - cx16.r0 = (cx16.r0 | $a000) - cx16.r0 = (cx16.r0 ^ $a000) - -/* - sys.set_irqd() - cx16.VERA_IEN = 1 ; only vsync irqs - - repeat { - while (cx16.VERA_ISR & 1)==0 { - ; wait for vsync - } - cx16.VERA_ISR = 1 ; clear vsync irq status - - palette.set_color(6, $ff0) - repeat 2000 { - cx16.r0++ - } - palette.set_color(6, $00f) - - } -*/ + func(true) + extok(true) } }