diff options
author | Robert Griesemer <gri@golang.org> | 2021-08-22 14:09:46 -0700 |
---|---|---|
committer | Robert Griesemer <gri@golang.org> | 2021-08-22 21:43:44 +0000 |
commit | 5d0c2840dae019c722fec7f5a64f371a780e24fd (patch) | |
tree | 1c7b8f7bfd66c212695fd4a86e96e1c86fd6b03d /src | |
parent | 19585826fa52d0580724be91f610db54727c74f0 (diff) | |
download | go-5d0c2840dae019c722fec7f5a64f371a780e24fd.tar.gz go-5d0c2840dae019c722fec7f5a64f371a780e24fd.zip |
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>
Diffstat (limited to 'src')
-rw-r--r-- | src/cmd/compile/internal/types2/api_test.go | 3 | ||||
-rw-r--r-- | src/cmd/compile/internal/types2/builtins.go | 9 |
2 files changed, 12 insertions, 0 deletions
diff --git a/src/cmd/compile/internal/types2/api_test.go b/src/cmd/compile/internal/types2/api_test.go index d6a2eb4eb3..3ed2799a84 100644 --- a/src/cmd/compile/internal/types2/api_test.go +++ b/src/cmd/compile/internal/types2/api_test.go @@ -346,6 +346,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/cmd/compile/internal/types2/builtins.go b/src/cmd/compile/internal/types2/builtins.go index da2dcf54aa..87295fe0e7 100644 --- a/src/cmd/compile/internal/types2/builtins.go +++ b/src/cmd/compile/internal/types2/builtins.go @@ -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)? 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- |