]> Cypherpunks repositories - gostls13.git/commitdiff
[release-branch.go1.18] cmd/compile: fix wrong unsafe.Offsetof evaluation inside...
authorCuong Manh Le <cuong.manhle.vn@gmail.com>
Mon, 30 May 2022 14:34:01 +0000 (21:34 +0700)
committerHeschi Kreinick <heschi@google.com>
Wed, 6 Jul 2022 19:31:10 +0000 (19:31 +0000)
For instantiated generic functions, all implicit dot operations are
resolved. Thus unsafe.Offsetof may calculating the offset against the
wrong base selector.

To fix it, we must remove any implicit dot operations to find the first
non-implicit one, which is the right base selector for calculating the
offset.

Fixes #53159

Change-Id: I38504067ce0f274615b306edc8f7d7933bdb631a
Reviewed-on: https://go-review.googlesource.com/c/go/+/409355
Run-TryBot: Cuong Manh Le <cuong.manhle.vn@gmail.com>
Reviewed-by: Dmitri Shuralyov <dmitshur@google.com>
Reviewed-by: Keith Randall <khr@google.com>
TryBot-Result: Gopher Robot <gobot@golang.org>
Reviewed-by: Keith Randall <khr@golang.org>
Reviewed-on: https://go-review.googlesource.com/c/go/+/409494

src/cmd/compile/internal/typecheck/const.go
test/fixedbugs/issue53137.dir/main.go [new file with mode: 0644]
test/fixedbugs/issue53137.go [new file with mode: 0644]

index fbe7c02c49821eb587ea97bf5e27b9f507e3bff6..24058fae584d203a13486f2d90d7a39fe3d230fb 100644 (file)
@@ -895,6 +895,18 @@ func evalunsafe(n ir.Node) int64 {
                sel.X = Expr(sel.X)
                sbase := sel.X
 
+               // Implicit dot may already be resolved for instantiating generic function. So we
+               // need to remove any implicit dot until we reach the first non-implicit one, it's
+               // the right base selector. See issue #53137.
+               var clobberBase func(n ir.Node) ir.Node
+               clobberBase = func(n ir.Node) ir.Node {
+                       if sel, ok := n.(*ir.SelectorExpr); ok && sel.Implicit() {
+                               return clobberBase(sel.X)
+                       }
+                       return n
+               }
+               sbase = clobberBase(sbase)
+
                tsel := Expr(sel)
                n.X = tsel
                if tsel.Type() == nil {
diff --git a/test/fixedbugs/issue53137.dir/main.go b/test/fixedbugs/issue53137.dir/main.go
new file mode 100644 (file)
index 0000000..88632bf
--- /dev/null
@@ -0,0 +1,30 @@
+// Copyright 2022 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package main
+
+import (
+       "unsafe"
+)
+
+type Embedded struct {
+       B int
+}
+
+type S[K any] struct {
+       A K
+       Embedded
+}
+
+func showOffsets[K any](d *S[K]) {
+       o1 := unsafe.Offsetof(d.B)
+       o2 := unsafe.Offsetof(d.Embedded)
+       if o1 != o2 {
+               panic("offset mismatch")
+       }
+}
+
+func main() {
+       showOffsets(new(S[int]))
+}
diff --git a/test/fixedbugs/issue53137.go b/test/fixedbugs/issue53137.go
new file mode 100644 (file)
index 0000000..aefbe67
--- /dev/null
@@ -0,0 +1,7 @@
+// rundir
+
+// Copyright 2022 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package ignored