Skip to content

Detect package level vars that are never modified after initialisation #3

@dave

Description

@dave

From my stack overflow question:

Using static analysis, it should be possible to determine which package-level variables are always read-only... that is, the value once initialised is never changed by the program.

My problem will happily tolerate false negatives - e.g. I only need to know the variables that are definitely read-only. If the analysis is unsure about some variables, they can be included in the read-write set.

For example, in the following program c, f, i and l are never modified:

package main

var a = 1
var b = 1
var c = 1 // never modified
var d = []int{1, 2}
var e = []int{1, 2}
var f = []int{1, 2} // never modified
var g = map[string]int{"a": 1}
var h = map[string]int{"a": 1}
var i = map[string]int{"a": 1} // never modified
var j = T{a: 1}
var k = T{a: 1}
var l = T{a: 1} // never modified

func main() {
    a = 2      // modifies a
    modInt(&b) // modifies b
    useInt(c)  // uses c but doesn't modify

    d[0] = 2     // modifies d
    modSlice(e)  // modifies e
    useInt(f[0]) // uses f but doesn't modify

    g["a"] = 2     // modifies g
    modMap(h)      // modifies h
    useInt(i["a"]) // uses i but doesn't modify

    j.a = 2     // modifies j
    modT(&k)    // modifies k
    useInt(l.a) // uses i but doesn't modify
}

func modInt(in *int) {
    *in = 2
}

func modSlice(in []int) {
    in[0] = 2
}

func modMap(in map[string]int) {
    in["a"] = 2
}

func modT(in *T) {
    in.a = 2
}

func useInt(i int) {
    println(i)
}

type T struct {
    a int
}

I'm familiar with the go/ast packages, and have a working knowledge of go/types, but the ssa and pointer analysis packages are a little outside my sphere of knowledge. It seems there's a whole lot of concepts to digest and I'm a little overwhelmed.

Two questions:

  1. Is there a package that will do this for me?

  2. If not, do you have any advice on what SSA / pointer analysis concepts will help with this?

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions