fix compiler crash due to certain redundant typecast expressions

This commit is contained in:
Irmen de Jong 2021-04-08 19:45:44 +02:00
parent 1a64cb38d5
commit c853afe769
4 changed files with 26 additions and 25 deletions

View File

@ -253,7 +253,7 @@ private fun processAst(programAst: Program, errors: IErrorReporter, compilerOpti
errors.report() errors.report()
programAst.addTypecasts(errors) programAst.addTypecasts(errors)
errors.report() errors.report()
programAst.variousCleanups(errors) programAst.variousCleanups(programAst, errors)
errors.report() errors.report()
programAst.checkValid(compilerOptions, errors, compilerOptions.compTarget) programAst.checkValid(compilerOptions, errors, compilerOptions.compTarget)
errors.report() errors.report()
@ -297,7 +297,7 @@ private fun optimizeAst(programAst: Program, errors: IErrorReporter, functions:
private fun postprocessAst(programAst: Program, errors: IErrorReporter, compilerOptions: CompilationOptions) { private fun postprocessAst(programAst: Program, errors: IErrorReporter, compilerOptions: CompilationOptions) {
programAst.addTypecasts(errors) programAst.addTypecasts(errors)
errors.report() errors.report()
programAst.variousCleanups(errors) programAst.variousCleanups(programAst, errors)
programAst.checkValid(compilerOptions, errors, compilerOptions.compTarget) // check if final tree is still valid programAst.checkValid(compilerOptions, errors, compilerOptions.compTarget) // check if final tree is still valid
errors.report() errors.report()
val callGraph = CallGraph(programAst) val callGraph = CallGraph(programAst)

View File

@ -61,8 +61,8 @@ internal fun Program.checkIdentifiers(errors: IErrorReporter, compTarget: ICompi
} }
} }
internal fun Program.variousCleanups(errors: IErrorReporter) { internal fun Program.variousCleanups(program: Program, errors: IErrorReporter) {
val process = VariousCleanups(errors) val process = VariousCleanups(program, errors)
process.visit(this) process.visit(this)
if(errors.noErrors()) if(errors.noErrors())
process.applyModifications() process.applyModifications()

View File

@ -3,6 +3,7 @@ package prog8.compiler.astprocessing
import prog8.ast.IFunctionCall import prog8.ast.IFunctionCall
import prog8.ast.INameScope import prog8.ast.INameScope
import prog8.ast.Node import prog8.ast.Node
import prog8.ast.Program
import prog8.ast.base.FatalAstException import prog8.ast.base.FatalAstException
import prog8.ast.base.Position import prog8.ast.base.Position
import prog8.ast.expressions.* import prog8.ast.expressions.*
@ -12,7 +13,7 @@ import prog8.ast.walk.IAstModification
import prog8.compiler.IErrorReporter 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<IAstModification> { override fun before(nopStatement: NopStatement, parent: Node): Iterable<IAstModification> {
return listOf(IAstModification.Remove(nopStatement, parent as INameScope)) 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<IAstModification> {
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<IAstModification> { override fun before(functionCallStatement: FunctionCallStatement, parent: Node): Iterable<IAstModification> {
return before(functionCallStatement as IFunctionCall, parent, functionCallStatement.position) return before(functionCallStatement as IFunctionCall, parent, functionCallStatement.position)
} }
@ -69,6 +60,23 @@ internal class VariousCleanups(val errors: IErrorReporter): AstWalker() {
return noModifications return noModifications
} }
override fun after(typecast: TypecastExpression, parent: Node): Iterable<IAstModification> {
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<IAstModification> { override fun after(subroutine: Subroutine, parent: Node): Iterable<IAstModification> {
if(subroutine.parent!==parent) if(subroutine.parent!==parent)
throw FatalAstException("parent node mismatch at $subroutine") throw FatalAstException("parent node mismatch at $subroutine")
@ -99,12 +107,6 @@ internal class VariousCleanups(val errors: IErrorReporter): AstWalker() {
return noModifications return noModifications
} }
override fun after(typecast: TypecastExpression, parent: Node): Iterable<IAstModification> {
if(typecast.parent!==parent)
throw FatalAstException("parent node mismatch at $typecast")
return noModifications
}
override fun after(returnStmt: Return, parent: Node): Iterable<IAstModification> { override fun after(returnStmt: Return, parent: Node): Iterable<IAstModification> {
if(returnStmt.parent!==parent) if(returnStmt.parent!==parent)
throw FatalAstException("parent node mismatch at $returnStmt") throw FatalAstException("parent node mismatch at $returnStmt")

View File

@ -1,12 +1,11 @@
main { main {
sub start() { sub start() {
uword width
uword world = $2000 ; TODO fix compiler crash with noopt:
ubyte xx uword x1 = (width-1 as uword) + 2
ubyte chr = world[2]
ubyte chr2 = world[xx]
} }
} }