//
// 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) {
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
--- /dev/null
+// 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()
+}
--- /dev/null
+// 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()
+}