mirror of
https://github.com/golang/go
synced 2024-11-26 07:27:59 -07:00
cmd/compile/internal/types2: report argument type for unsafe.OffsetOf
Before parameterized types, unsafe.OffsetOf was always evaluating to a constant. With parameterized types, the result may be a run-time value, and unsafe.OffsetOf(x.f) is a call that is recorded. Also record the argument x.f. Fixes #47895. Change-Id: Ia3da25028d4865d7295ce7990c7216bffe9e7c72 Reviewed-on: https://go-review.googlesource.com/c/go/+/344252 Trust: Robert Griesemer <gri@golang.org> Trust: Dan Scales <danscales@google.com> Run-TryBot: Robert Griesemer <gri@golang.org> TryBot-Result: Go Bot <gobot@golang.org> Reviewed-by: Dan Scales <danscales@google.com>
This commit is contained in:
parent
19585826fa
commit
5d0c2840da
@ -346,6 +346,9 @@ func TestTypesInfo(t *testing.T) {
|
|||||||
|
|
||||||
// issue 45096
|
// issue 45096
|
||||||
{genericPkg + `issue45096; func _[T interface{ ~int8 | ~int16 | ~int32 }](x T) { _ = x < 0 }`, `0`, `generic_issue45096.T₁`},
|
{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 {
|
for _, test := range tests {
|
||||||
|
@ -662,6 +662,15 @@ func (check *Checker) builtin(x *operand, call *syntax.CallExpr, id builtinId) (
|
|||||||
// TODO(gri) Should we pass x.typ instead of base (and have indirect report if derefStructPtr indirected)?
|
// 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)
|
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 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
|
// 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-
|
// simpler and also permits (or at least doesn't prevent) a compiler from re-
|
||||||
|
Loading…
Reference in New Issue
Block a user