if Debug['m'] > 1 {
fmt.Printf("%v: cannot inline escaping closure variable %v\n", n.Line(), n.Left)
}
+ if logopt.Enabled() {
+ logopt.LogOpt(n.Pos, "cannotInlineCall", "inline", Curfn.funcname(),
+ fmt.Sprintf("%v cannot be inlined (escaping closure variable)", n.Left))
+ }
break
}
if Debug['m'] > 1 {
if a != nil {
fmt.Printf("%v: cannot inline re-assigned closure variable at %v: %v\n", n.Line(), a.Line(), a)
+ if logopt.Enabled() {
+ logopt.LogOpt(n.Pos, "cannotInlineCall", "inline", Curfn.funcname(),
+ fmt.Sprintf("%v cannot be inlined (re-assigned closure variable)", a))
+ }
} else {
fmt.Printf("%v: cannot inline global closure variable %v\n", n.Line(), n.Left)
+ if logopt.Enabled() {
+ logopt.LogOpt(n.Pos, "cannotInlineCall", "inline", Curfn.funcname(),
+ fmt.Sprintf("%v cannot be inlined (global closure variable)", n.Left))
+ }
}
}
break
// n.Left = mkinlcall(n.Left, fn, isddd)
func mkinlcall(n, fn *Node, maxCost int32, inlMap map[*Node]bool) *Node {
if fn.Func.Inl == nil {
- // No inlinable body.
+ if logopt.Enabled() {
+ logopt.LogOpt(n.Pos, "cannotInlineCall", "inline", Curfn.funcname(),
+ fmt.Sprintf("%s cannot be inlined", fn.pkgFuncName()))
+ }
return n
}
if fn.Func.Inl.Cost > maxCost {
if Debug['m'] > 2 {
fmt.Printf("%v: Before inlining: %+v\n", n.Line(), n)
}
- if logopt.Enabled() {
- logopt.LogOpt(n.Pos, "inlineCall", "inline", Curfn.funcname(), fn.pkgFuncName())
- }
if ssaDump != "" && ssaDump == Curfn.funcname() {
ssaDumpInlined = append(ssaDumpInlined, fn)
}
return &a[0]
}
+
+// address taking prevents closure inlining
+func n() int {
+ foo := func() int { return 1 }
+ bar := &foo
+ x := (*bar)() + foo()
+ return x
+}
`
func want(t *testing.T, out string, desired string) {
// All this delicacy with uriIfy and filepath.Join is to get this test to work right on Windows.
slogged := normalize(logged, string(uriIfy(dir)), string(uriIfy("tmpdir")))
t.Logf("%s", slogged)
- // below shows proper inlining and nilcheck
- want(t, slogged, `{"range":{"start":{"line":9,"character":13},"end":{"line":9,"character":13}},"severity":3,"code":"nilcheck","source":"go compiler","message":"","relatedInformation":[{"location":{"uri":"file://tmpdir/file.go","range":{"start":{"line":4,"character":11},"end":{"line":4,"character":11}}},"message":"inlineLoc"}]}`)
+ // below shows proper nilcheck
+ want(t, slogged, `{"range":{"start":{"line":9,"character":13},"end":{"line":9,"character":13}},"severity":3,"code":"nilcheck","source":"go compiler","message":"",`+
+ `"relatedInformation":[{"location":{"uri":"file://tmpdir/file.go","range":{"start":{"line":4,"character":11},"end":{"line":4,"character":11}}},"message":"inlineLoc"}]}`)
want(t, slogged, `{"range":{"start":{"line":11,"character":6},"end":{"line":11,"character":6}},"severity":3,"code":"isInBounds","source":"go compiler","message":""}`)
want(t, slogged, `{"range":{"start":{"line":7,"character":6},"end":{"line":7,"character":6}},"severity":3,"code":"canInlineFunction","source":"go compiler","message":"cost: 35"}`)
- want(t, slogged, `{"range":{"start":{"line":9,"character":13},"end":{"line":9,"character":13}},"severity":3,"code":"inlineCall","source":"go compiler","message":"x.bar"}`)
- want(t, slogged, `{"range":{"start":{"line":8,"character":9},"end":{"line":8,"character":9}},"severity":3,"code":"inlineCall","source":"go compiler","message":"x.bar"}`)
+ want(t, slogged, `{"range":{"start":{"line":21,"character":21},"end":{"line":21,"character":21}},"severity":3,"code":"cannotInlineCall","source":"go compiler","message":"foo cannot be inlined (escaping closure variable)"}`)
+
})
}