diff --git a/src/cmd/compile/internal/ir/expr.go b/src/cmd/compile/internal/ir/expr.go index cf56515a2c..8f7df4b458 100644 --- a/src/cmd/compile/internal/ir/expr.go +++ b/src/cmd/compile/internal/ir/expr.go @@ -853,6 +853,10 @@ func IsAddressable(n Node) bool { // // calling StaticValue on the "int(y)" expression returns the outer // "g()" expression. +// +// NOTE: StaticValue can return a result with a different type than +// n's type because it can traverse through OCONVNOP operations. +// TODO: consider reapplying OCONVNOP operations to the result. See https://go.dev/cl/676517. func StaticValue(n Node) Node { for { switch n1 := n.(type) { diff --git a/src/cmd/compile/internal/walk/order.go b/src/cmd/compile/internal/walk/order.go index 77322286c7..8ba8dd96cc 100644 --- a/src/cmd/compile/internal/walk/order.go +++ b/src/cmd/compile/internal/walk/order.go @@ -249,14 +249,14 @@ func (o *orderState) addrTemp(n ir.Node) ir.Node { if (v.Op() == ir.OSTRUCTLIT || v.Op() == ir.OARRAYLIT) && !base.Ctxt.IsFIPS() { if ir.IsZero(v) && 0 < v.Type().Size() && v.Type().Size() <= abi.ZeroValSize { // This zero value can be represented by the read-only zeroVal. - zeroVal := ir.NewLinksymExpr(v.Pos(), ir.Syms.ZeroVal, v.Type()) + zeroVal := ir.NewLinksymExpr(v.Pos(), ir.Syms.ZeroVal, n.Type()) vstat := typecheck.Expr(zeroVal).(*ir.LinksymOffsetExpr) return vstat } if isStaticCompositeLiteral(v) { // v can be directly represented in the read-only data section. lit := v.(*ir.CompLitExpr) - vstat := readonlystaticname(lit.Type()) + vstat := readonlystaticname(n.Type()) fixedlit(inInitFunction, initKindStatic, lit, vstat, nil) // nil init vstat = typecheck.Expr(vstat).(*ir.Name) return vstat diff --git a/test/fixedbugs/issue73888.go b/test/fixedbugs/issue73888.go new file mode 100644 index 0000000000..b3c1ff768f --- /dev/null +++ b/test/fixedbugs/issue73888.go @@ -0,0 +1,34 @@ +// run + +// Copyright 2025 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 + +type SourceRange struct { + x, y int +} + +func (r *SourceRange) String() string { + return "hello" +} + +type SourceNode interface { + SourceRange() +} + +type testNode SourceRange + +func (tn testNode) SourceRange() { +} + +func main() { + n := testNode(SourceRange{}) // zero value + Errorf(n) +} + +//go:noinline +func Errorf(n SourceNode) { + n.SourceRange() +} diff --git a/test/fixedbugs/issue73888b.go b/test/fixedbugs/issue73888b.go new file mode 100644 index 0000000000..b6e0289cc4 --- /dev/null +++ b/test/fixedbugs/issue73888b.go @@ -0,0 +1,34 @@ +// run + +// Copyright 2025 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 + +type SourceRange struct { + x, y int +} + +func (r *SourceRange) String() string { + return "hello" +} + +type SourceNode interface { + SourceRange() +} + +type testNode SourceRange + +func (tn testNode) SourceRange() { +} + +func main() { + n := testNode(SourceRange{1, 1}) // not zero value + Errorf(n) +} + +//go:noinline +func Errorf(n SourceNode) { + n.SourceRange() +}