aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorRobert Griesemer <gri@golang.org>2021-08-22 15:21:29 -0700
committerRobert Griesemer <gri@golang.org>2021-08-22 22:30:38 +0000
commit29d7e5472be79b77f39d81b697d44038179ba1a1 (patch)
treee8fae2612a1cd10fb81c2bf77b59716b20e64a4c /src
parent8fcc614360cac2c23aafeb2fdc637c72ff1d7dfd (diff)
downloadgo-29d7e5472be79b77f39d81b697d44038179ba1a1.tar.gz
go-29d7e5472be79b77f39d81b697d44038179ba1a1.zip
go/types: report argument type for unsafe.OffsetOf
This is a clean port of CL 344252 to go/types. For #47895. Change-Id: I48cbb97ec28fcfb4fdf483594be9d29426c117ac Reviewed-on: https://go-review.googlesource.com/c/go/+/344254 Trust: Robert Griesemer <gri@golang.org> Trust: Dan Scales <danscales@google.com> Run-TryBot: Robert Griesemer <gri@golang.org> Reviewed-by: Dan Scales <danscales@google.com>
Diffstat (limited to 'src')
-rw-r--r--src/go/types/api_test.go3
-rw-r--r--src/go/types/builtins.go9
2 files changed, 12 insertions, 0 deletions
diff --git a/src/go/types/api_test.go b/src/go/types/api_test.go
index 1631215d15..a49f2113b9 100644
--- a/src/go/types/api_test.go
+++ b/src/go/types/api_test.go
@@ -362,6 +362,9 @@ func TestTypesInfo(t *testing.T) {
// issue 45096
{genericPkg + `issue45096; func _[T interface{ ~int8 | ~int16 | ~int32 }](x T) { _ = x < 0 }`, `0`, `generic_issue45096.T₁`},
+
+ // issue 47895
+ {`package p; import "unsafe"; type S struct { f int }; var s S; var _ = unsafe.Offsetof(s.f)`, `s.f`, `int`},
}
for _, test := range tests {
diff --git a/src/go/types/builtins.go b/src/go/types/builtins.go
index 9c772d3844..698435bc20 100644
--- a/src/go/types/builtins.go
+++ b/src/go/types/builtins.go
@@ -671,6 +671,15 @@ func (check *Checker) builtin(x *operand, call *ast.CallExpr, id builtinId) (_ b
// TODO(gri) Should we pass x.typ instead of base (and have indirect report if derefStructPtr indirected)?
check.recordSelection(selx, FieldVal, base, obj, index, false)
+ // record the selector expression (was bug - issue #47895)
+ {
+ mode := value
+ if x.mode == variable || indirect {
+ mode = variable
+ }
+ check.record(&operand{mode, selx, obj.Type(), nil, 0})
+ }
+
// The field offset is considered a variable even if the field is declared before
// the part of the struct which is variable-sized. This makes both the rules
// simpler and also permits (or at least doesn't prevent) a compiler from re-