if ro == nil {
base.Fatalf("no ReassignOracle for function %v with closure parent %v", fn, fn.ClosureParent)
}
- if s := ro.StaticValue(*r); s.Op() == ir.OLITERAL {
+
+ s := ro.StaticValue(*r)
+ switch s.Op() {
+ case ir.OLITERAL:
lit, ok := s.(*ir.BasicLit)
if !ok || lit.Val().Kind() != constant.Int {
base.Fatalf("unexpected BasicLit Kind")
assignTemp(n.Pos(), *r, n.PtrInit())
*r = ir.NewBasicLit(n.Pos(), (*r).Type(), lit.Val())
}
+ case ir.OLEN:
+ x := ro.StaticValue(s.(*ir.UnaryExpr).X)
+ if x.Op() == ir.OSLICELIT {
+ x := x.(*ir.CompLitExpr)
+ // Preserve any side effects of the original expression, then update the value.
+ assignTemp(n.Pos(), *r, n.PtrInit())
+ *r = ir.NewBasicLit(n.Pos(), types.Types[types.TINT], constant.MakeInt64(x.Len))
+ }
}
}
case ir.OCONVIFACE:
func newM(l int) m { // ERROR "can inline"
return m{make(map[string]int, l)} // ERROR "make.*escapes to heap"
}
+
+//go:noinline
+func testLenOfSliceLit() {
+ ints := []int{0, 1, 2, 3, 4, 5} // ERROR "\[\]int\{\.\.\.\} does not escape"'
+ _ = make([]int, len(ints)) // ERROR "make\(\[\]int, 6\) does not escape"
+ _ = allocLenOf(ints) // ERROR "inlining call", "make\(\[\]int, 6\) does not escape"
+
+ _ = make([]int, 2, len(ints)) // ERROR "make\(\[\]int, 2, 6\) does not escape"
+ _ = make([]int, len(ints), 2) // ERROR "make\(\[\]int, len\(ints\), 2\) does not escape"
+ _ = make([]int, 10, len(ints)) // ERROR "make\(\[\]int, 10, 6\) does not escape"
+}
+
+func allocLenOf(s []int) []int { // ERROR "can inline" "s does not escape"
+ return make([]int, len(s)) // ERROR "escapes to heap"
+}