From 27b698bc2a69e30dd13df20576181031863d6e8d Mon Sep 17 00:00:00 2001 From: Robert Griesemer Date: Fri, 27 Sep 2013 09:33:00 -0700 Subject: [PATCH] go.tools/go/types: x.f is addressable if x is addressable or x.f contains an indirection Fixes golang/go#6487. R=adonovan CC=golang-dev https://golang.org/cl/14047043 --- go/types/call.go | 6 +++++- go/types/testdata/stmt0.src | 15 +++++++++++++++ 2 files changed, 20 insertions(+), 1 deletion(-) diff --git a/go/types/call.go b/go/types/call.go index d57172f0..ebfd00de 100644 --- a/go/types/call.go +++ b/go/types/call.go @@ -286,7 +286,11 @@ func (check *checker) selector(x *operand, e *ast.SelectorExpr) { switch obj := obj.(type) { case *Var: check.recordSelection(e, FieldVal, x.typ, obj, index, indirect) - x.mode = variable + if x.mode == variable || indirect { + x.mode = variable + } else { + x.mode = value + } x.typ = obj.typ case *Func: diff --git a/go/types/testdata/stmt0.src b/go/types/testdata/stmt0.src index 393af5d6..c60e0508 100644 --- a/go/types/testdata/stmt0.src +++ b/go/types/testdata/stmt0.src @@ -92,6 +92,21 @@ func assignments1() { (_) = 0 } +func issue6487() { + type S struct{x int} + _ = &S /* ERROR "cannot take address" */ {}.x + _ = &( /* ERROR "cannot take address" */ S{}.x) + _ = (&S{}).x + S /* ERROR "cannot assign" */ {}.x = 0 + (&S{}).x = 0 + + type M map[string]S + var m M + m /* ERROR "cannot assign" */ ["foo"].x = 0 + _ = &( /* ERROR "cannot take address" */ m["foo"].x) + _ = &m /* ERROR "cannot take address" */ ["foo"].x +} + func shortVarDecls() { const c = 0 type d int