1
0
mirror of https://github.com/golang/go synced 2024-11-26 05:07:59 -07:00

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>
This commit is contained in:
Robert Griesemer 2021-08-22 15:21:29 -07:00
parent 8fcc614360
commit 29d7e5472b
2 changed files with 12 additions and 0 deletions

View File

@ -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 {

View File

@ -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-