Skip to content

Bug Report: AsmFull incorrectly processes MapUpdate operations after the call #5008

@luoliwoshang

Description

@luoliwoshang

Summary

I discovered an issue with device.AsmFull where it incorrectly processes MapUpdate operations that occur after the AsmFull call, causing the function to return unexpected values from future map modifications instead of the values present at call time.

Problem Description

The issue is in compiler/inlineasm.go at line 62, where the code uses break to exit a switch statement but continues processing subsequent MapUpdate operations in the referrers loop:

case *ssa.Call:
    if r.Common() == instr {
        break  // ❌ Only breaks from switch, continues for loop
    }

This means that map updates happening after the AsmFull call are still collected and can affect the result.

Reproduction

package main

import (
    "device"
    "machine"
    "time"
)

func main() {
    machine.Serial.Configure(machine.UARTConfig{BaudRate: 115200})
    time.Sleep(1 * time.Second)
    
    place := map[string]interface{}{
        "input": uint32(42),
    }
    
    result := device.AsmFull("mov {}, {input}", place)
    place["input"] = uint32(44) // This MapUpdate affects the result!
    
    println("Expected: 42, Got:", uint32(result))
}

Expected Result

Expected: 42, Got: 42

Actual Result (Before Fix)

Expected: 42, Got: 44

Root Cause Analysis

The original code appears to intend to stop processing referrers when encountering the AsmFull call itself, but uses break which only exits the switch statement, not the entire for loop. This allows subsequent MapUpdate operations to be processed incorrectly.

Impact

This bug can cause: Unexpected behavior where AsmFull returns "future" values instead of call-time values

Thank you for maintaining TinyGo! This is an amazing project and I'm happy to contribute to its improvement. 😊

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions