From f9612295cb7f1aeda8af2d194c1bae69364a5ef2 Mon Sep 17 00:00:00 2001 From: Alan Donovan Date: Tue, 22 Jul 2014 18:29:56 -0400 Subject: [PATCH] go.tools/oracle: pointsto: if the queried expression is an lvalue, use the type of its value, not its address. (Probable regression caused by recent changes to VarValue.) + regression test. LGTM=gri R=gri CC=golang-codereviews https://golang.org/cl/116160044 --- oracle/pointsto.go | 6 ++++-- oracle/testdata/src/main/pointsto.go | 9 ++++++++- oracle/testdata/src/main/pointsto.golden | 5 +++++ 3 files changed, 17 insertions(+), 3 deletions(-) diff --git a/oracle/pointsto.go b/oracle/pointsto.go index b6ff413d..df8d57f7 100644 --- a/oracle/pointsto.go +++ b/oracle/pointsto.go @@ -132,8 +132,10 @@ func ssaValueForExpr(prog *ssa.Program, qinfo *loader.PackageInfo, path []ast.No func runPTA(o *Oracle, v ssa.Value, isAddr bool) (ptrs []pointerResult, err error) { buildSSA(o) + T := v.Type() if isAddr { o.ptaConfig.AddIndirectQuery(v) + T = deref(T) } else { o.ptaConfig.AddQuery(v) } @@ -150,7 +152,7 @@ func runPTA(o *Oracle, v ssa.Value, isAddr bool) (ptrs []pointerResult, err erro } pts := ptr.PointsTo() - if pointer.CanHaveDynamicTypes(v.Type()) { + if pointer.CanHaveDynamicTypes(T) { // Show concrete types for interface/reflect.Value expression. if concs := pts.DynamicTypes(); concs.Len() > 0 { concs.Iterate(func(conc types.Type, pta interface{}) { @@ -163,7 +165,7 @@ func runPTA(o *Oracle, v ssa.Value, isAddr bool) (ptrs []pointerResult, err erro // Show labels for other expressions. labels := pts.Labels() sort.Sort(byPosAndString(labels)) // to ensure determinism - ptrs = append(ptrs, pointerResult{v.Type(), labels}) + ptrs = append(ptrs, pointerResult{T, labels}) } sort.Sort(byTypeString(ptrs)) // to ensure determinism return ptrs, nil diff --git a/oracle/testdata/src/main/pointsto.go b/oracle/testdata/src/main/pointsto.go index 796ec942..0657facb 100644 --- a/oracle/testdata/src/main/pointsto.go +++ b/oracle/testdata/src/main/pointsto.go @@ -46,7 +46,14 @@ func main() { _ = mapval // @pointsto mapval "mapval" _ = m // @pointsto m "m" - panic(3) // @pointsto builtin-panic "panic" + if false { + panic(3) // @pointsto builtin-panic "panic" + } + + // NB: s.f is addressable per (*ssa.Program).VarValue, + // but our query concerns the object, not its address. + s := struct{ f interface{} }{f: make(chan bool)} + print(s.f) // @pointsto var-ref-s-f "s.f" } func livecode() {} // @pointsto func-live "livecode" diff --git a/oracle/testdata/src/main/pointsto.golden b/oracle/testdata/src/main/pointsto.golden index b7f0e905..98c14413 100644 --- a/oracle/testdata/src/main/pointsto.golden +++ b/oracle/testdata/src/main/pointsto.golden @@ -80,6 +80,11 @@ this map[string]*int may point to these objects: -------- @pointsto builtin-panic -------- Error: pointer analysis wants an expression of reference type; got () +-------- @pointsto var-ref-s-f -------- +this interface{} may contain these dynamic types: + chan bool, may point to: + makechan + -------- @pointsto func-live -------- Error: pointer analysis did not find expression (dead code?)