fix invalid augmented assignment optimization, and a call to pop() that crashed a symbol prefix test because the call wasn't defined as a builtin

This commit is contained in:
Irmen de Jong
2026-03-13 21:49:55 +01:00
parent 01748517ae
commit 9502a6f590
4 changed files with 23 additions and 15 deletions

View File

@@ -946,21 +946,25 @@ _after:
// consolidates simple assignment followed by augmented assignment into a single combined assignment.
// a = simplevalue | a += expression --> a = simplevalue + expression (for all augmented operators)
// NOTE: this is NOT SAFE to do when dealing with pointer arithmetic because the semantics of the combined expression is different!
// NOTE: this is also NOT SAFE when the augmented assignment's RHS references the target variable (e.g., a = b; a *= a)
if(!assignment.isAugmentable && assignment.value.isSimple) {
val next = assignment.nextSibling() as? Assignment
if(next?.isAugmentable==true && next.value is BinaryExpression && next.target.isSameAs(assignment.target, program)) {
val combined = next.value as BinaryExpression
if(combined.left isSameAs assignment.target) {
if(!assignment.target.inferType(program).isPointer && (assignment.value.inferType(program).isPointer || combined.right.inferType(program).isPointer)) {
// avoid pointer arithmetic: a = (simplevalue as uword) + expression
combined.left = TypecastExpression(assignment.value, DataType.UWORD, true, combined.left.position)
} else {
// no pointer arithmetic done, just transform it into a = simplevalue + expression
combined.left = assignment.value
// Check if RHS also references the target variable - if so, can't optimize
if(!(combined.right isSameAs assignment.target)) {
if(!assignment.target.inferType(program).isPointer && (assignment.value.inferType(program).isPointer || combined.right.inferType(program).isPointer)) {
// avoid pointer arithmetic: a = (simplevalue as uword) + expression
combined.left = TypecastExpression(assignment.value, DataType.UWORD, true, combined.left.position)
} else {
// no pointer arithmetic done, just transform it into a = simplevalue + expression
combined.left = assignment.value
}
assignment.value = combined
combined.linkParents(assignment)
return listOf(IAstModification.Remove(next, parent as IStatementContainer))
}
assignment.value = combined
combined.linkParents(assignment)
return listOf(IAstModification.Remove(next, parent as IStatementContainer))
}
}
}

View File

@@ -50,7 +50,7 @@ internal fun makePushPopFunctionCalls(value: PtExpression): Pair<PtFunctionCall,
val popCall = if(popTypecast!=null) {
PtTypeCast(popTypecast, true, value.position).also {
val returnDt = if(pushWord) DataType.UWORD else if(pushLong) DataType.LONG else if(pushFloat) DataType.FLOAT else DataType.UBYTE
it.add(PtFunctionCall(popFunc, false, false, arrayOf(returnDt), value.position))
it.add(PtFunctionCall(popFunc, true, false, arrayOf(returnDt), value.position))
}
} else
PtFunctionCall(popFunc, true, false, arrayOf(value.type), value.position)

View File

@@ -1,9 +1,6 @@
TODO
====
BUG in unzip: lookup error p8s_pop [unzip.p8: line 262 col 16-24]
Known bugs:
- fix chained aliasing errors see test "chained aliasing"
- fix crash in ir loader/vm for deeply nested symbol reference, see test "deeply scoped variable references"

View File

@@ -6,9 +6,16 @@ main {
sub start() {
long @shared z1, z2
z1=1111
z2 = z1*z1
z2=z1
z2*=z2
txt.print_l(z2)
txt.nl()
z1=-1111
z2=z1
z2*=z2
txt.print_l(z2)
txt.nl()
}
}