aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/cmd/compile/internal/typecheck/expr.go6
-rw-r--r--test/fixedbugs/issue72844.go70
2 files changed, 73 insertions, 3 deletions
diff --git a/src/cmd/compile/internal/typecheck/expr.go b/src/cmd/compile/internal/typecheck/expr.go
index 2eec8d41ad..44a69f0332 100644
--- a/src/cmd/compile/internal/typecheck/expr.go
+++ b/src/cmd/compile/internal/typecheck/expr.go
@@ -634,16 +634,16 @@ func tcIndex(n *ir.IndexExpr) ir.Node {
func tcLenCap(n *ir.UnaryExpr) ir.Node {
n.X = Expr(n.X)
n.X = DefaultLit(n.X, nil)
- n.X = implicitstar(n.X)
l := n.X
t := l.Type()
if t == nil {
n.SetType(nil)
return n
}
-
var ok bool
- if n.Op() == ir.OLEN {
+ if t.IsPtr() && t.Elem().IsArray() {
+ ok = true
+ } else if n.Op() == ir.OLEN {
ok = okforlen[t.Kind()]
} else {
ok = okforcap[t.Kind()]
diff --git a/test/fixedbugs/issue72844.go b/test/fixedbugs/issue72844.go
new file mode 100644
index 0000000000..0322841ded
--- /dev/null
+++ b/test/fixedbugs/issue72844.go
@@ -0,0 +1,70 @@
+// 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
+
+//go:noinline
+func nilPtrFunc() *[4]int {
+ return nil
+}
+
+var nilPtrVar *[4]int
+
+func testLen1() {
+ _ = len(*nilPtrFunc())
+}
+
+func testLen2() {
+ _ = len(nilPtrFunc())
+}
+
+func testLen3() {
+ _ = len(*nilPtrVar)
+}
+
+func testLen4() {
+ _ = len(nilPtrVar)
+}
+
+func testRange1() {
+ for range *nilPtrFunc() {
+ }
+}
+func testRange2() {
+ for range nilPtrFunc() {
+ }
+}
+func testRange3() {
+ for range *nilPtrVar {
+ }
+}
+func testRange4() {
+ for range nilPtrVar {
+ }
+}
+
+func main() {
+ //shouldPanic(testLen1)
+ shouldNotPanic(testLen2)
+ shouldNotPanic(testLen3)
+ shouldNotPanic(testLen4)
+ //shouldPanic(testRange1)
+ shouldNotPanic(testRange2)
+ shouldNotPanic(testRange3)
+ shouldNotPanic(testRange4)
+}
+
+func shouldPanic(f func()) {
+ defer func() {
+ if e := recover(); e == nil {
+ panic("should have panicked")
+ }
+ }()
+ f()
+}
+func shouldNotPanic(f func()) {
+ f()
+}