From c853afe7697b45db2d401b93fc3190b0532b608f Mon Sep 17 00:00:00 2001 From: Irmen de Jong Date: Thu, 8 Apr 2021 19:45:44 +0200 Subject: [PATCH] fix compiler crash due to certain redundant typecast expressions --- compiler/src/prog8/compiler/Compiler.kt | 4 +-- .../compiler/astprocessing/AstExtensions.kt | 4 +-- .../compiler/astprocessing/VariousCleanups.kt | 36 ++++++++++--------- examples/test.p8 | 7 ++-- 4 files changed, 26 insertions(+), 25 deletions(-) diff --git a/compiler/src/prog8/compiler/Compiler.kt b/compiler/src/prog8/compiler/Compiler.kt index 6cc517b61..45814dcd1 100644 --- a/compiler/src/prog8/compiler/Compiler.kt +++ b/compiler/src/prog8/compiler/Compiler.kt @@ -253,7 +253,7 @@ private fun processAst(programAst: Program, errors: IErrorReporter, compilerOpti errors.report() programAst.addTypecasts(errors) errors.report() - programAst.variousCleanups(errors) + programAst.variousCleanups(programAst, errors) errors.report() programAst.checkValid(compilerOptions, errors, compilerOptions.compTarget) errors.report() @@ -297,7 +297,7 @@ private fun optimizeAst(programAst: Program, errors: IErrorReporter, functions: private fun postprocessAst(programAst: Program, errors: IErrorReporter, compilerOptions: CompilationOptions) { programAst.addTypecasts(errors) errors.report() - programAst.variousCleanups(errors) + programAst.variousCleanups(programAst, errors) programAst.checkValid(compilerOptions, errors, compilerOptions.compTarget) // check if final tree is still valid errors.report() val callGraph = CallGraph(programAst) diff --git a/compiler/src/prog8/compiler/astprocessing/AstExtensions.kt b/compiler/src/prog8/compiler/astprocessing/AstExtensions.kt index 68a674e6e..04326b272 100644 --- a/compiler/src/prog8/compiler/astprocessing/AstExtensions.kt +++ b/compiler/src/prog8/compiler/astprocessing/AstExtensions.kt @@ -61,8 +61,8 @@ internal fun Program.checkIdentifiers(errors: IErrorReporter, compTarget: ICompi } } -internal fun Program.variousCleanups(errors: IErrorReporter) { - val process = VariousCleanups(errors) +internal fun Program.variousCleanups(program: Program, errors: IErrorReporter) { + val process = VariousCleanups(program, errors) process.visit(this) if(errors.noErrors()) process.applyModifications() diff --git a/compiler/src/prog8/compiler/astprocessing/VariousCleanups.kt b/compiler/src/prog8/compiler/astprocessing/VariousCleanups.kt index 73ebca5e6..039815bcd 100644 --- a/compiler/src/prog8/compiler/astprocessing/VariousCleanups.kt +++ b/compiler/src/prog8/compiler/astprocessing/VariousCleanups.kt @@ -3,6 +3,7 @@ package prog8.compiler.astprocessing import prog8.ast.IFunctionCall import prog8.ast.INameScope import prog8.ast.Node +import prog8.ast.Program import prog8.ast.base.FatalAstException import prog8.ast.base.Position import prog8.ast.expressions.* @@ -12,7 +13,7 @@ import prog8.ast.walk.IAstModification import prog8.compiler.IErrorReporter -internal class VariousCleanups(val errors: IErrorReporter): AstWalker() { +internal class VariousCleanups(val program: Program, val errors: IErrorReporter): AstWalker() { override fun before(nopStatement: NopStatement, parent: Node): Iterable { return listOf(IAstModification.Remove(nopStatement, parent as INameScope)) @@ -36,16 +37,6 @@ internal class VariousCleanups(val errors: IErrorReporter): AstWalker() { } } - override fun before(typecast: TypecastExpression, parent: Node): Iterable { - if(typecast.expression is NumericLiteralValue) { - val value = (typecast.expression as NumericLiteralValue).cast(typecast.type) - if(value.isValid) - return listOf(IAstModification.ReplaceNode(typecast, value.valueOrZero(), parent)) - } - - return noModifications - } - override fun before(functionCallStatement: FunctionCallStatement, parent: Node): Iterable { return before(functionCallStatement as IFunctionCall, parent, functionCallStatement.position) } @@ -69,6 +60,23 @@ internal class VariousCleanups(val errors: IErrorReporter): AstWalker() { return noModifications } + override fun after(typecast: TypecastExpression, parent: Node): Iterable { + if(typecast.parent!==parent) + throw FatalAstException("parent node mismatch at $typecast") + + if(typecast.expression is NumericLiteralValue) { + val value = (typecast.expression as NumericLiteralValue).cast(typecast.type) + if(value.isValid) + return listOf(IAstModification.ReplaceNode(typecast, value.valueOrZero(), parent)) + } + + val sourceDt = typecast.expression.inferType(program) + if(sourceDt.istype(typecast.type)) + return listOf(IAstModification.ReplaceNode(typecast, typecast.expression, parent)) + + return noModifications + } + override fun after(subroutine: Subroutine, parent: Node): Iterable { if(subroutine.parent!==parent) throw FatalAstException("parent node mismatch at $subroutine") @@ -99,12 +107,6 @@ internal class VariousCleanups(val errors: IErrorReporter): AstWalker() { return noModifications } - override fun after(typecast: TypecastExpression, parent: Node): Iterable { - if(typecast.parent!==parent) - throw FatalAstException("parent node mismatch at $typecast") - return noModifications - } - override fun after(returnStmt: Return, parent: Node): Iterable { if(returnStmt.parent!==parent) throw FatalAstException("parent node mismatch at $returnStmt") diff --git a/examples/test.p8 b/examples/test.p8 index acdd62e61..8f1696b4d 100644 --- a/examples/test.p8 +++ b/examples/test.p8 @@ -1,12 +1,11 @@ main { sub start() { + uword width - uword world = $2000 - ubyte xx + ; TODO fix compiler crash with noopt: + uword x1 = (width-1 as uword) + 2 - ubyte chr = world[2] - ubyte chr2 = world[xx] } }