implicit int to float conversion is now an error if floats are not enabled.

This commit is contained in:
Irmen de Jong 2021-12-15 01:52:28 +01:00
parent 510bda1b28
commit 1ff13723fe
5 changed files with 62 additions and 7 deletions

View File

@ -267,7 +267,7 @@ private fun processAst(program: Program, errors: IErrorReporter, compilerOptions
errors.report()
program.reorderStatements(errors, compilerOptions)
errors.report()
program.addTypecasts(errors)
program.addTypecasts(errors, compilerOptions)
errors.report()
program.variousCleanups(program, errors)
errors.report()
@ -300,7 +300,7 @@ private fun optimizeAst(program: Program, compilerOptions: CompilationOptions, e
}
private fun postprocessAst(program: Program, errors: IErrorReporter, compilerOptions: CompilationOptions) {
program.addTypecasts(errors)
program.addTypecasts(errors, compilerOptions)
errors.report()
program.variousCleanups(program, errors)
program.checkValid(errors, compilerOptions) // check if final tree is still valid

View File

@ -53,8 +53,8 @@ internal fun Program.charLiteralsToUByteLiterals(enc: IStringEncoding) {
walker.applyModifications()
}
internal fun Program.addTypecasts(errors: IErrorReporter) {
val caster = TypecastsAdder(this, errors)
internal fun Program.addTypecasts(errors: IErrorReporter, options: CompilationOptions) {
val caster = TypecastsAdder(this, options, errors)
caster.visit(this)
caster.applyModifications()
}

View File

@ -9,10 +9,11 @@ import prog8.ast.statements.*
import prog8.ast.walk.AstWalker
import prog8.ast.walk.IAstModification
import prog8.compilerinterface.BuiltinFunctions
import prog8.compilerinterface.CompilationOptions
import prog8.compilerinterface.IErrorReporter
class TypecastsAdder(val program: Program, val errors: IErrorReporter) : AstWalker() {
class TypecastsAdder(val program: Program, val options: CompilationOptions, val errors: IErrorReporter) : AstWalker() {
/*
* Make sure any value assignments get the proper type casts if needed to cast them into the target variable's type.
* (this includes function call arguments)
@ -220,7 +221,10 @@ class TypecastsAdder(val program: Program, val errors: IErrorReporter) : AstWalk
override fun after(typecast: TypecastExpression, parent: Node): Iterable<IAstModification> {
// warn about any implicit type casts to Float, because that may not be intended
if(typecast.implicit && typecast.type.oneOf(DataType.FLOAT, DataType.ARRAY_F)) {
errors.warn("integer implicitly converted to float. Suggestion: use float literals, add an explicit cast, or revert to integer arithmetic", typecast.position)
if(options.floats)
errors.warn("integer implicitly converted to float. Suggestion: use float literals, add an explicit cast, or revert to integer arithmetic", typecast.position)
else
errors.err("integer implicitly converted to float but floating point is not enabled via options", typecast.position)
}
return noModifications
}

View File

@ -4,9 +4,15 @@ import io.kotest.assertions.throwables.shouldThrow
import io.kotest.core.spec.style.FunSpec
import io.kotest.matchers.doubles.plusOrMinus
import io.kotest.matchers.shouldBe
import io.kotest.matchers.string.shouldContain
import prog8.ast.toHex
import prog8.compiler.target.C64Target
import prog8.compiler.target.cbm.Mflpt5
import prog8.compilerinterface.InternalCompilerException
import prog8tests.helpers.ErrorReporterForTests
import prog8tests.helpers.assertFailure
import prog8tests.helpers.assertSuccess
import prog8tests.helpers.compileText
class TestNumbers: FunSpec({
@ -105,4 +111,45 @@ class TestNumbers: FunSpec({
Mflpt5(0xd1u, 0x02u, 0xb7u, 0x06u, 0xfbu).toDouble() shouldBe(123.45678e22 plusOrMinus 1.0e15)
Mflpt5(0x3eu, 0xe9u, 0x34u, 0x09u, 0x1bu).toDouble() shouldBe(-123.45678e-22 plusOrMinus epsilon)
}
test("implicit float conversion warning if enabled") {
val src="""
%option enable_floats
main {
sub start() {
uword xx = 10
if xx+99 == 1.23456
xx++
if xx+99 == 1234567
xx++
}
}
"""
val errors = ErrorReporterForTests(keepMessagesAfterReporting = true)
compileText(C64Target, true, src, writeAssembly = false, errors=errors).assertSuccess()
errors.errors.size shouldBe 0
errors.warnings.size shouldBe 2
errors.warnings[0] shouldContain "converted to float"
errors.warnings[1] shouldContain "converted to float"
}
test("implicit float conversion error if not enabled") {
val src="""
main {
sub start() {
uword xx = 10
if xx+99 == 1.23456
xx++
if xx+99 == 1234567
xx++
}
}
"""
val errors = ErrorReporterForTests(keepMessagesAfterReporting = true)
compileText(C64Target, true, src, writeAssembly = false, errors=errors).assertFailure()
errors.errors.size shouldBe 2
errors.warnings.size shouldBe 0
errors.errors[0] shouldContain "converted to float"
errors.errors[1] shouldContain "converted to float"
}
})

View File

@ -1,7 +1,11 @@
main {
sub start() {
uword xx = 10
if xx+99 == 1.234 {
if xx+99 == 1.23456 {
xx++
}
if xx+99 == 1234567 {
xx++
}
}