Initial commit: Go 1.23 release state

This commit is contained in:
Vorapol Rinsatitnon
2024-09-21 23:49:08 +10:00
commit 17cd57a668
13231 changed files with 3114330 additions and 0 deletions

View File

@@ -0,0 +1,45 @@
// Copyright 2023 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 dumpscores
var G int
func inlinable(x int, f func(int) int) int {
if x != 0 {
return 1
}
G += noninl(x)
return f(x)
}
func inlinable2(x int) int {
return noninl(-x)
}
//go:noinline
func noninl(x int) int {
return x + 1
}
func tooLargeToInline(x int) int {
if x > 101 {
// Drive up the cost of inlining this func over the
// regular threshold.
return big(big(big(big(big(G + x)))))
}
if x < 100 {
// make sure this callsite is scored properly
G += inlinable(101, inlinable2)
if G == 101 {
return 0
}
panic(inlinable2(3))
}
return G
}
func big(q int) int {
return noninl(q) + noninl(-q)
}

View File

@@ -0,0 +1,77 @@
// Copyright 2023 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.
Notes on the format of the testcase files in
cmd/compile/internal/inline/inlheur/testdata/props:
- each (compilable) file contains input Go code and expected results
in the form of column-0 comments.
- functions or methods that begin with "T_" are targeted for testing,
as well as "init" functions; all other functions are ignored.
- function header comments begin with a line containing
the file name, function name, definition line, then index
and a count of the number of funcs that share that same
definition line (needed to support generics). Example:
// foo.go T_mumble 35 1 4
Here "T_mumble" is defined at line 35, and it is func 0
out of the 4 funcs that share that same line.
- function property expected results appear as comments in immediately
prior to the function. For example, here we have first the function
name ("T_feeds_if_simple"), then human-readable dump of the function
properties, as well as the JSON for the properties object, each
section separated by a "<>" delimiter.
// params.go T_feeds_if_simple 35 0 1
// RecvrParamFlags:
// 0: ParamFeedsIfOrSwitch
// <endpropsdump>
// {"Flags":0,"RecvrParamFlags":[8],"ReturnFlags":[]}
// callsite: params.go:34:10|0 "CallSiteOnPanicPath" 2
// <endcallsites>
// <endfuncpreamble>
func T_feeds_if_simple(x int) {
if x < 100 {
os.Exit(1)
}
println(x)
}
- when the test runs, it will compile the Go source file with an
option to dump out function properties, then compare the new dump
for each function with the JSON appearing in the header comment for
the function (in the example above, the JSON appears between
"<endpropsdump>" and "<endfuncpreamble>". The material prior to the
dump is simply there for human consumption, so that a developer can
easily see that "RecvrParamFlags":[8] means that the first parameter
has flag ParamFeedsIfOrSwitch.
- when making changes to the compiler (which can alter the expected
results) or edits/additions to the go code in the testcase files,
you can remaster the results by running
go test -v -count=1 .
In the trace output of this run, you'll see messages of the form
=== RUN TestFuncProperties
funcprops_test.go:NNN: update-expected: emitted updated file
testdata/props/XYZ.go.new
funcprops_test.go:MMM: please compare the two files, then overwrite
testdata/props/XYZ.go with testdata/props/XYZ.go.new
at which point you can compare the old and new files by hand, then
overwrite the *.go file with the *.go.new file if you are happy with
the diffs.
- note that the remastering process will strip out any existing
column-0 (unindented) comments; if you write comments that you
want to see preserved, use "/* */" or indent them.

View File

@@ -0,0 +1,214 @@
// Copyright 2023 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.
// DO NOT EDIT (use 'go test -v -update-expected' instead.)
// See cmd/compile/internal/inline/inlheur/testdata/props/README.txt
// for more information on the format of this file.
// <endfilepreamble>
package params
// acrosscall.go T_feeds_indirect_call_via_call_toplevel 19 0 1
// ParamFlags
// 0 ParamFeedsIndirectCall
// <endpropsdump>
// {"Flags":0,"ParamFlags":[8],"ResultFlags":null}
// callsite: acrosscall.go:20:12|0 flagstr "" flagval 0 score 60 mask 0 maskstr ""
// <endcallsites>
// <endfuncpreamble>
func T_feeds_indirect_call_via_call_toplevel(f func(int)) {
callsparam(f)
}
// acrosscall.go T_feeds_indirect_call_via_call_conditional 31 0 1
// ParamFlags
// 0 ParamMayFeedIndirectCall
// <endpropsdump>
// {"Flags":0,"ParamFlags":[16],"ResultFlags":null}
// callsite: acrosscall.go:33:13|0 flagstr "" flagval 0 score 60 mask 0 maskstr ""
// <endcallsites>
// <endfuncpreamble>
func T_feeds_indirect_call_via_call_conditional(f func(int)) {
if G != 101 {
callsparam(f)
}
}
// acrosscall.go T_feeds_conditional_indirect_call_via_call_toplevel 45 0 1
// ParamFlags
// 0 ParamMayFeedIndirectCall
// <endpropsdump>
// {"Flags":0,"ParamFlags":[16],"ResultFlags":null}
// callsite: acrosscall.go:46:23|0 flagstr "" flagval 0 score 64 mask 0 maskstr ""
// <endcallsites>
// <endfuncpreamble>
func T_feeds_conditional_indirect_call_via_call_toplevel(f func(int)) {
callsparamconditional(f)
}
// acrosscall.go T_feeds_if_via_call 57 0 1
// ParamFlags
// 0 ParamFeedsIfOrSwitch
// <endpropsdump>
// {"Flags":0,"ParamFlags":[32],"ResultFlags":null}
// callsite: acrosscall.go:58:9|0 flagstr "" flagval 0 score 8 mask 0 maskstr ""
// <endcallsites>
// <endfuncpreamble>
func T_feeds_if_via_call(x int) {
feedsif(x)
}
// acrosscall.go T_feeds_if_via_call_conditional 69 0 1
// ParamFlags
// 0 ParamMayFeedIfOrSwitch
// <endpropsdump>
// {"Flags":0,"ParamFlags":[64],"ResultFlags":null}
// callsite: acrosscall.go:71:10|0 flagstr "" flagval 0 score 8 mask 0 maskstr ""
// <endcallsites>
// <endfuncpreamble>
func T_feeds_if_via_call_conditional(x int) {
if G != 101 {
feedsif(x)
}
}
// acrosscall.go T_feeds_conditional_if_via_call 83 0 1
// ParamFlags
// 0 ParamMayFeedIfOrSwitch
// <endpropsdump>
// {"Flags":0,"ParamFlags":[64],"ResultFlags":null}
// callsite: acrosscall.go:84:20|0 flagstr "" flagval 0 score 12 mask 0 maskstr ""
// <endcallsites>
// <endfuncpreamble>
func T_feeds_conditional_if_via_call(x int) {
feedsifconditional(x)
}
// acrosscall.go T_multifeeds1 97 0 1
// ParamFlags
// 0 ParamFeedsIndirectCall|ParamMayFeedIndirectCall
// 1 ParamNoInfo
// <endpropsdump>
// {"Flags":0,"ParamFlags":[24,0],"ResultFlags":null}
// callsite: acrosscall.go:98:12|0 flagstr "" flagval 0 score 60 mask 0 maskstr ""
// callsite: acrosscall.go:99:23|1 flagstr "" flagval 0 score 64 mask 0 maskstr ""
// <endcallsites>
// <endfuncpreamble>
func T_multifeeds1(f1, f2 func(int)) {
callsparam(f1)
callsparamconditional(f1)
}
// acrosscall.go T_acrosscall_returnsconstant 110 0 1
// ResultFlags
// 0 ResultAlwaysSameConstant
// <endpropsdump>
// {"Flags":0,"ParamFlags":null,"ResultFlags":[8]}
// callsite: acrosscall.go:111:24|0 flagstr "" flagval 0 score 2 mask 0 maskstr ""
// <endcallsites>
// <endfuncpreamble>
func T_acrosscall_returnsconstant() int {
return returnsconstant()
}
// acrosscall.go T_acrosscall_returnsmem 122 0 1
// ResultFlags
// 0 ResultIsAllocatedMem
// <endpropsdump>
// {"Flags":0,"ParamFlags":null,"ResultFlags":[2]}
// callsite: acrosscall.go:123:19|0 flagstr "" flagval 0 score 2 mask 0 maskstr ""
// <endcallsites>
// <endfuncpreamble>
func T_acrosscall_returnsmem() *int {
return returnsmem()
}
// acrosscall.go T_acrosscall_returnscci 134 0 1
// ResultFlags
// 0 ResultIsConcreteTypeConvertedToInterface
// <endpropsdump>
// {"Flags":0,"ParamFlags":null,"ResultFlags":[4]}
// callsite: acrosscall.go:135:19|0 flagstr "" flagval 0 score 7 mask 0 maskstr ""
// <endcallsites>
// <endfuncpreamble>
func T_acrosscall_returnscci() I {
return returnscci()
}
// acrosscall.go T_acrosscall_multiret 144 0 1
// <endpropsdump>
// {"Flags":0,"ParamFlags":[0],"ResultFlags":[0]}
// callsite: acrosscall.go:146:25|0 flagstr "" flagval 0 score 2 mask 0 maskstr ""
// <endcallsites>
// <endfuncpreamble>
func T_acrosscall_multiret(q int) int {
if q != G {
return returnsconstant()
}
return 0
}
// acrosscall.go T_acrosscall_multiret2 158 0 1
// <endpropsdump>
// {"Flags":0,"ParamFlags":[0],"ResultFlags":[0]}
// callsite: acrosscall.go:160:25|0 flagstr "" flagval 0 score 2 mask 0 maskstr ""
// callsite: acrosscall.go:162:25|1 flagstr "" flagval 0 score 2 mask 0 maskstr ""
// <endcallsites>
// <endfuncpreamble>
func T_acrosscall_multiret2(q int) int {
if q == G {
return returnsconstant()
} else {
return returnsconstant()
}
}
func callsparam(f func(int)) {
f(2)
}
func callsparamconditional(f func(int)) {
if G != 101 {
f(2)
}
}
func feedsif(x int) int {
if x != 101 {
return 42
}
return 43
}
func feedsifconditional(x int) int {
if G != 101 {
if x != 101 {
return 42
}
}
return 43
}
func returnsconstant() int {
return 42
}
func returnsmem() *int {
return new(int)
}
func returnscci() I {
var q Q
return q
}
type I interface {
Foo()
}
type Q int
func (q Q) Foo() {
}
var G int

View File

@@ -0,0 +1,240 @@
// Copyright 2023 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.
// DO NOT EDIT (use 'go test -v -update-expected' instead.)
// See cmd/compile/internal/inline/inlheur/testdata/props/README.txt
// for more information on the format of this file.
// <endfilepreamble>
package calls
import "os"
// calls.go T_call_in_panic_arg 19 0 1
// <endpropsdump>
// {"Flags":0,"ParamFlags":[0],"ResultFlags":null}
// callsite: calls.go:21:15|0 flagstr "CallSiteOnPanicPath" flagval 2 score 42 mask 1 maskstr "panicPathAdj"
// <endcallsites>
// <endfuncpreamble>
func T_call_in_panic_arg(x int) {
if x < G {
panic(callee(x))
}
}
// calls.go T_calls_in_loops 32 0 1
// <endpropsdump>
// {"Flags":0,"ParamFlags":[0,0],"ResultFlags":null}
// callsite: calls.go:34:9|0 flagstr "CallSiteInLoop" flagval 1 score -3 mask 4 maskstr "inLoopAdj"
// callsite: calls.go:37:9|1 flagstr "CallSiteInLoop" flagval 1 score -3 mask 4 maskstr "inLoopAdj"
// <endcallsites>
// <endfuncpreamble>
func T_calls_in_loops(x int, q []string) {
for i := 0; i < x; i++ {
callee(i)
}
for _, s := range q {
callee(len(s))
}
}
// calls.go T_calls_in_pseudo_loop 48 0 1
// <endpropsdump>
// {"Flags":0,"ParamFlags":[0,0],"ResultFlags":null}
// callsite: calls.go:50:9|0 flagstr "" flagval 0 score 2 mask 0 maskstr ""
// callsite: calls.go:54:9|1 flagstr "" flagval 0 score 2 mask 0 maskstr ""
// <endcallsites>
// <endfuncpreamble>
func T_calls_in_pseudo_loop(x int, q []string) {
for i := 0; i < x; i++ {
callee(i)
return
}
for _, s := range q {
callee(len(s))
break
}
}
// calls.go T_calls_on_panic_paths 67 0 1
// <endpropsdump>
// {"Flags":0,"ParamFlags":[0,0],"ResultFlags":null}
// callsite: calls.go:69:9|0 flagstr "CallSiteOnPanicPath" flagval 2 score 42 mask 1 maskstr "panicPathAdj"
// callsite: calls.go:73:9|1 flagstr "CallSiteOnPanicPath" flagval 2 score 42 mask 1 maskstr "panicPathAdj"
// callsite: calls.go:77:12|2 flagstr "CallSiteOnPanicPath" flagval 2 score 102 mask 1 maskstr "panicPathAdj"
// <endcallsites>
// <endfuncpreamble>
func T_calls_on_panic_paths(x int, q []string) {
if x+G == 101 {
callee(x)
panic("ouch")
}
if x < G-101 {
callee(x)
if len(q) == 0 {
G++
}
callsexit(x)
}
}
// calls.go T_calls_not_on_panic_paths 93 0 1
// ParamFlags
// 0 ParamFeedsIfOrSwitch|ParamMayFeedIfOrSwitch
// 1 ParamNoInfo
// <endpropsdump>
// {"Flags":0,"ParamFlags":[96,0],"ResultFlags":null}
// callsite: calls.go:103:9|0 flagstr "" flagval 0 score 2 mask 0 maskstr ""
// callsite: calls.go:112:9|1 flagstr "" flagval 0 score 2 mask 0 maskstr ""
// callsite: calls.go:115:9|2 flagstr "" flagval 0 score 2 mask 0 maskstr ""
// callsite: calls.go:119:12|3 flagstr "CallSiteOnPanicPath" flagval 2 score 102 mask 1 maskstr "panicPathAdj"
// <endcallsites>
// <endfuncpreamble>
func T_calls_not_on_panic_paths(x int, q []string) {
if x != G {
panic("ouch")
/* Notes: */
/* - we only look for post-dominating panic/exit, so */
/* this site will on fact not have a panicpath flag */
/* - vet will complain about this site as unreachable */
callee(x)
}
if x != G {
callee(x)
if x < 100 {
panic("ouch")
}
}
if x+G == 101 {
if x < 100 {
panic("ouch")
}
callee(x)
}
if x < -101 {
callee(x)
if len(q) == 0 {
return
}
callsexit(x)
}
}
// calls.go init.0 129 0 1
// <endpropsdump>
// {"Flags":0,"ParamFlags":null,"ResultFlags":null}
// callsite: calls.go:130:16|0 flagstr "CallSiteInInitFunc" flagval 4 score 22 mask 2 maskstr "initFuncAdj"
// <endcallsites>
// <endfuncpreamble>
func init() {
println(callee(5))
}
// calls.go T_pass_inlinable_func_to_param_feeding_indirect_call 140 0 1
// <endpropsdump>
// {"Flags":0,"ParamFlags":[0],"ResultFlags":[0]}
// callsite: calls.go:141:19|0 flagstr "" flagval 0 score 16 mask 512 maskstr "passInlinableFuncToIndCallAdj"
// callsite: calls.go:141:19|calls.go:232:10|0 flagstr "" flagval 0 score 2 mask 0 maskstr ""
// <endcallsites>
// <endfuncpreamble>
func T_pass_inlinable_func_to_param_feeding_indirect_call(x int) int {
return callsParam(x, callee)
}
// calls.go T_pass_noninlinable_func_to_param_feeding_indirect_call 150 0 1
// <endpropsdump>
// {"Flags":0,"ParamFlags":[0],"ResultFlags":[0]}
// callsite: calls.go:153:19|0 flagstr "" flagval 0 score 36 mask 128 maskstr "passFuncToIndCallAdj"
// <endcallsites>
// <endfuncpreamble>
func T_pass_noninlinable_func_to_param_feeding_indirect_call(x int) int {
// if we inline callsParam we can convert the indirect call
// to a direct call, but we can't inline it.
return callsParam(x, calleeNoInline)
}
// calls.go T_pass_inlinable_func_to_param_feeding_nested_indirect_call 165 0 1
// ParamFlags
// 0 ParamFeedsIfOrSwitch
// <endpropsdump>
// {"Flags":0,"ParamFlags":[32],"ResultFlags":[0]}
// callsite: calls.go:166:25|0 flagstr "" flagval 0 score 27 mask 1024 maskstr "passInlinableFuncToNestedIndCallAdj"
// callsite: calls.go:166:25|calls.go:237:11|0 flagstr "" flagval 0 score 2 mask 0 maskstr ""
// <endcallsites>
// <endfuncpreamble>
func T_pass_inlinable_func_to_param_feeding_nested_indirect_call(x int) int {
return callsParamNested(x, callee)
}
// calls.go T_pass_noninlinable_func_to_param_feeding_nested_indirect_call 177 0 1
// ParamFlags
// 0 ParamFeedsIfOrSwitch
// <endpropsdump>
// {"Flags":0,"ParamFlags":[32],"ResultFlags":[0]}
// callsite: calls.go:178:25|0 flagstr "" flagval 0 score 47 mask 256 maskstr "passFuncToNestedIndCallAdj"
// <endcallsites>
// <endfuncpreamble>
func T_pass_noninlinable_func_to_param_feeding_nested_indirect_call(x int) int {
return callsParamNested(x, calleeNoInline)
}
// calls.go T_call_scoring_in_noninlinable_func 195 0 1
// <endpropsdump>
// {"Flags":0,"ParamFlags":[0,0],"ResultFlags":[0]}
// callsite: calls.go:209:14|0 flagstr "CallSiteOnPanicPath" flagval 2 score 42 mask 1 maskstr "panicPathAdj"
// callsite: calls.go:210:15|1 flagstr "CallSiteOnPanicPath" flagval 2 score 42 mask 1 maskstr "panicPathAdj"
// callsite: calls.go:212:19|2 flagstr "" flagval 0 score 16 mask 512 maskstr "passInlinableFuncToIndCallAdj"
// callsite: calls.go:212:19|calls.go:232:10|0 flagstr "" flagval 0 score 4 mask 0 maskstr ""
// <endcallsites>
// <endfuncpreamble>
// calls.go T_call_scoring_in_noninlinable_func.func1 212 0 1
// <endpropsdump>
// {"Flags":0,"ParamFlags":[0],"ResultFlags":[0]}
// <endcallsites>
// <endfuncpreamble>
func T_call_scoring_in_noninlinable_func(x int, sl []int) int {
if x == 101 {
// Drive up the cost of inlining this funcfunc over the
// regular threshold.
for i := 0; i < 10; i++ {
for j := 0; j < i; j++ {
sl = append(sl, append(sl, append(sl, append(sl, x)...)...)...)
sl = append(sl, sl[0], sl[1], sl[2])
x += calleeNoInline(x)
}
}
}
if x < 100 {
// make sure this callsite is scored properly
G += callee(101)
panic(callee(x))
}
return callsParam(x, func(y int) int { return y + x })
}
var G int
func callee(x int) int {
return x
}
func calleeNoInline(x int) int {
defer func() { G++ }()
return x
}
func callsexit(x int) {
println(x)
os.Exit(x)
}
func callsParam(x int, f func(int) int) int {
return f(x)
}
func callsParamNested(x int, f func(int) int) int {
if x < 0 {
return f(x)
}
return 0
}

View File

@@ -0,0 +1,341 @@
// Copyright 2023 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.
// DO NOT EDIT (use 'go test -v -update-expected' instead.)
// See cmd/compile/internal/inline/inlheur/testdata/props/README.txt
// for more information on the format of this file.
// <endfilepreamble>
package funcflags
import "os"
// funcflags.go T_simple 20 0 1
// Flags FuncPropNeverReturns
// <endpropsdump>
// {"Flags":1,"ParamFlags":null,"ResultFlags":null}
// <endcallsites>
// <endfuncpreamble>
func T_simple() {
panic("bad")
}
// funcflags.go T_nested 32 0 1
// Flags FuncPropNeverReturns
// ParamFlags
// 0 ParamFeedsIfOrSwitch
// <endpropsdump>
// {"Flags":1,"ParamFlags":[32],"ResultFlags":null}
// <endcallsites>
// <endfuncpreamble>
func T_nested(x int) {
if x < 10 {
panic("bad")
} else {
panic("good")
}
}
// funcflags.go T_block1 46 0 1
// Flags FuncPropNeverReturns
// <endpropsdump>
// {"Flags":1,"ParamFlags":[0],"ResultFlags":null}
// <endcallsites>
// <endfuncpreamble>
func T_block1(x int) {
panic("bad")
if x < 10 {
return
}
}
// funcflags.go T_block2 60 0 1
// ParamFlags
// 0 ParamFeedsIfOrSwitch
// <endpropsdump>
// {"Flags":0,"ParamFlags":[32],"ResultFlags":null}
// <endcallsites>
// <endfuncpreamble>
func T_block2(x int) {
if x < 10 {
return
}
panic("bad")
}
// funcflags.go T_switches1 75 0 1
// Flags FuncPropNeverReturns
// ParamFlags
// 0 ParamFeedsIfOrSwitch
// <endpropsdump>
// {"Flags":1,"ParamFlags":[32],"ResultFlags":null}
// <endcallsites>
// <endfuncpreamble>
func T_switches1(x int) {
switch x {
case 1:
panic("one")
case 2:
panic("two")
}
panic("whatev")
}
// funcflags.go T_switches1a 92 0 1
// ParamFlags
// 0 ParamFeedsIfOrSwitch
// <endpropsdump>
// {"Flags":0,"ParamFlags":[32],"ResultFlags":null}
// <endcallsites>
// <endfuncpreamble>
func T_switches1a(x int) {
switch x {
case 2:
panic("two")
}
}
// funcflags.go T_switches2 106 0 1
// ParamFlags
// 0 ParamFeedsIfOrSwitch
// <endpropsdump>
// {"Flags":0,"ParamFlags":[32],"ResultFlags":null}
// <endcallsites>
// <endfuncpreamble>
func T_switches2(x int) {
switch x {
case 1:
panic("one")
case 2:
panic("two")
default:
return
}
panic("whatev")
}
// funcflags.go T_switches3 123 0 1
// <endpropsdump>
// {"Flags":0,"ParamFlags":[0],"ResultFlags":null}
// <endcallsites>
// <endfuncpreamble>
func T_switches3(x interface{}) {
switch x.(type) {
case bool:
panic("one")
case float32:
panic("two")
}
}
// funcflags.go T_switches4 138 0 1
// Flags FuncPropNeverReturns
// <endpropsdump>
// {"Flags":1,"ParamFlags":[0],"ResultFlags":null}
// <endcallsites>
// <endfuncpreamble>
func T_switches4(x int) {
switch x {
case 1:
x++
fallthrough
case 2:
panic("two")
fallthrough
default:
panic("bad")
}
panic("whatev")
}
// funcflags.go T_recov 157 0 1
// <endpropsdump>
// {"Flags":0,"ParamFlags":[0],"ResultFlags":null}
// <endcallsites>
// <endfuncpreamble>
func T_recov(x int) {
if x := recover(); x != nil {
panic(x)
}
}
// funcflags.go T_forloops1 169 0 1
// Flags FuncPropNeverReturns
// <endpropsdump>
// {"Flags":1,"ParamFlags":[0],"ResultFlags":null}
// <endcallsites>
// <endfuncpreamble>
func T_forloops1(x int) {
for {
panic("wokketa")
}
}
// funcflags.go T_forloops2 180 0 1
// <endpropsdump>
// {"Flags":0,"ParamFlags":[0],"ResultFlags":null}
// <endcallsites>
// <endfuncpreamble>
func T_forloops2(x int) {
for {
println("blah")
if true {
break
}
panic("warg")
}
}
// funcflags.go T_forloops3 195 0 1
// <endpropsdump>
// {"Flags":0,"ParamFlags":[0],"ResultFlags":null}
// <endcallsites>
// <endfuncpreamble>
func T_forloops3(x int) {
for i := 0; i < 101; i++ {
println("blah")
if true {
continue
}
panic("plark")
}
for i := range [10]int{} {
println(i)
panic("plark")
}
panic("whatev")
}
// funcflags.go T_hasgotos 215 0 1
// <endpropsdump>
// {"Flags":0,"ParamFlags":[0,0],"ResultFlags":null}
// <endcallsites>
// <endfuncpreamble>
func T_hasgotos(x int, y int) {
{
xx := x
panic("bad")
lab1:
goto lab2
lab2:
if false {
goto lab1
} else {
goto lab4
}
lab4:
if xx < y {
lab3:
if false {
goto lab3
}
}
println(9)
}
}
// funcflags.go T_break_with_label 246 0 1
// ParamFlags
// 0 ParamMayFeedIfOrSwitch
// 1 ParamNoInfo
// <endpropsdump>
// {"Flags":0,"ParamFlags":[64,0],"ResultFlags":null}
// <endcallsites>
// <endfuncpreamble>
func T_break_with_label(x int, y int) {
// presence of break with label should pessimize this func
// (similar to goto).
panic("bad")
lab1:
for {
println("blah")
if x < 0 {
break lab1
}
panic("hubba")
}
}
// funcflags.go T_callsexit 268 0 1
// Flags FuncPropNeverReturns
// ParamFlags
// 0 ParamFeedsIfOrSwitch
// <endpropsdump>
// {"Flags":1,"ParamFlags":[32],"ResultFlags":null}
// <endcallsites>
// <endfuncpreamble>
func T_callsexit(x int) {
if x < 0 {
os.Exit(1)
}
os.Exit(2)
}
// funcflags.go T_exitinexpr 281 0 1
// <endpropsdump>
// {"Flags":0,"ParamFlags":[0],"ResultFlags":null}
// callsite: funcflags.go:286:18|0 flagstr "CallSiteOnPanicPath" flagval 2 score 102 mask 1 maskstr "panicPathAdj"
// <endcallsites>
// <endfuncpreamble>
func T_exitinexpr(x int) {
// This function does indeed unconditionally call exit, since the
// first thing it does is invoke exprcallsexit, however from the
// perspective of this function, the call is not at the statement
// level, so we'll wind up missing it.
if exprcallsexit(x) < 0 {
println("foo")
}
}
// funcflags.go T_select_noreturn 297 0 1
// Flags FuncPropNeverReturns
// <endpropsdump>
// {"Flags":1,"ParamFlags":[0,0,0],"ResultFlags":null}
// <endcallsites>
// <endfuncpreamble>
func T_select_noreturn(chi chan int, chf chan float32, p *int) {
rv := 0
select {
case i := <-chi:
rv = i
case f := <-chf:
rv = int(f)
}
*p = rv
panic("bad")
}
// funcflags.go T_select_mayreturn 314 0 1
// <endpropsdump>
// {"Flags":0,"ParamFlags":[0,0,0],"ResultFlags":[0]}
// <endcallsites>
// <endfuncpreamble>
func T_select_mayreturn(chi chan int, chf chan float32, p *int) int {
rv := 0
select {
case i := <-chi:
rv = i
return i
case f := <-chf:
rv = int(f)
}
*p = rv
panic("bad")
}
// funcflags.go T_calls_callsexit 334 0 1
// Flags FuncPropNeverReturns
// <endpropsdump>
// {"Flags":1,"ParamFlags":[0],"ResultFlags":null}
// callsite: funcflags.go:335:15|0 flagstr "CallSiteOnPanicPath" flagval 2 score 102 mask 1 maskstr "panicPathAdj"
// <endcallsites>
// <endfuncpreamble>
func T_calls_callsexit(x int) {
exprcallsexit(x)
}
func exprcallsexit(x int) int {
os.Exit(x)
return x
}

View File

@@ -0,0 +1,367 @@
// Copyright 2023 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.
// DO NOT EDIT (use 'go test -v -update-expected' instead.)
// See cmd/compile/internal/inline/inlheur/testdata/props/README.txt
// for more information on the format of this file.
// <endfilepreamble>
package params
import "os"
// params.go T_feeds_if_simple 20 0 1
// ParamFlags
// 0 ParamFeedsIfOrSwitch
// <endpropsdump>
// {"Flags":0,"ParamFlags":[32],"ResultFlags":null}
// <endcallsites>
// <endfuncpreamble>
func T_feeds_if_simple(x int) {
if x < 100 {
os.Exit(1)
}
println(x)
}
// params.go T_feeds_if_nested 35 0 1
// ParamFlags
// 0 ParamMayFeedIfOrSwitch
// 1 ParamFeedsIfOrSwitch
// <endpropsdump>
// {"Flags":0,"ParamFlags":[64,32],"ResultFlags":null}
// <endcallsites>
// <endfuncpreamble>
func T_feeds_if_nested(x, y int) {
if y != 0 {
if x < 100 {
os.Exit(1)
}
}
println(x)
}
// params.go T_feeds_if_pointer 51 0 1
// ParamFlags
// 0 ParamFeedsIfOrSwitch
// <endpropsdump>
// {"Flags":0,"ParamFlags":[32],"ResultFlags":null}
// <endcallsites>
// <endfuncpreamble>
func T_feeds_if_pointer(xp *int) {
if xp != nil {
os.Exit(1)
}
println(xp)
}
// params.go T.T_feeds_if_simple_method 66 0 1
// ParamFlags
// 0 ParamFeedsIfOrSwitch
// 1 ParamFeedsIfOrSwitch
// <endpropsdump>
// {"Flags":0,"ParamFlags":[32,32],"ResultFlags":null}
// <endcallsites>
// <endfuncpreamble>
func (r T) T_feeds_if_simple_method(x int) {
if x < 100 {
os.Exit(1)
}
if r != 99 {
os.Exit(2)
}
println(x)
}
// params.go T_feeds_if_blanks 86 0 1
// ParamFlags
// 0 ParamNoInfo
// 1 ParamFeedsIfOrSwitch
// 2 ParamNoInfo
// 3 ParamNoInfo
// <endpropsdump>
// {"Flags":0,"ParamFlags":[0,32,0,0],"ResultFlags":null}
// <endcallsites>
// <endfuncpreamble>
func T_feeds_if_blanks(_ string, x int, _ bool, _ bool) {
// blanks ignored; from a props perspective "x" is param 0
if x < 100 {
os.Exit(1)
}
println(x)
}
// params.go T_feeds_if_with_copy 101 0 1
// ParamFlags
// 0 ParamFeedsIfOrSwitch
// <endpropsdump>
// {"Flags":0,"ParamFlags":[32],"ResultFlags":null}
// <endcallsites>
// <endfuncpreamble>
func T_feeds_if_with_copy(x int) {
// simple copy here -- we get this case
xx := x
if xx < 100 {
os.Exit(1)
}
println(x)
}
// params.go T_feeds_if_with_copy_expr 115 0 1
// <endpropsdump>
// {"Flags":0,"ParamFlags":[0],"ResultFlags":null}
// <endcallsites>
// <endfuncpreamble>
func T_feeds_if_with_copy_expr(x int) {
// this case (copy of expression) currently not handled.
xx := x < 100
if xx {
os.Exit(1)
}
println(x)
}
// params.go T_feeds_switch 131 0 1
// ParamFlags
// 0 ParamFeedsIfOrSwitch
// <endpropsdump>
// {"Flags":0,"ParamFlags":[32],"ResultFlags":null}
// <endcallsites>
// <endfuncpreamble>
func T_feeds_switch(x int) {
switch x {
case 101:
println(101)
case 202:
panic("bad")
}
println(x)
}
// params.go T_feeds_if_toocomplex 146 0 1
// <endpropsdump>
// {"Flags":0,"ParamFlags":[0,0],"ResultFlags":null}
// <endcallsites>
// <endfuncpreamble>
func T_feeds_if_toocomplex(x int, y int) {
// not handled at the moment; we only look for cases where
// an "if" or "switch" can be simplified based on a single
// constant param, not a combination of constant params.
if x < y {
panic("bad")
}
println(x + y)
}
// params.go T_feeds_if_redefined 161 0 1
// <endpropsdump>
// {"Flags":0,"ParamFlags":[0],"ResultFlags":null}
// <endcallsites>
// <endfuncpreamble>
func T_feeds_if_redefined(x int) {
if x < G {
x++
}
if x == 101 {
panic("bad")
}
}
// params.go T_feeds_if_redefined2 175 0 1
// <endpropsdump>
// {"Flags":0,"ParamFlags":[0],"ResultFlags":null}
// <endcallsites>
// <endfuncpreamble>
func T_feeds_if_redefined2(x int) {
// this currently classifies "x" as "no info", since the analysis we
// use to check for reassignments/redefinitions is not flow-sensitive,
// but we could probably catch this case with better analysis or
// high-level SSA.
if x == 101 {
panic("bad")
}
if x < G {
x++
}
}
// params.go T_feeds_multi_if 196 0 1
// ParamFlags
// 0 ParamFeedsIfOrSwitch
// 1 ParamNoInfo
// <endpropsdump>
// {"Flags":0,"ParamFlags":[32,0],"ResultFlags":null}
// <endcallsites>
// <endfuncpreamble>
func T_feeds_multi_if(x int, y int) {
// Here we have one "if" that is too complex (x < y) but one that is
// simple enough. Currently we enable the heuristic for this. It's
// possible to imagine this being a bad thing if the function in
// question is sufficiently large, but if it's too large we probably
// can't inline it anyhow.
if x < y {
panic("bad")
}
if x < 10 {
panic("whatev")
}
println(x + y)
}
// params.go T_feeds_if_redefined_indirectwrite 216 0 1
// <endpropsdump>
// {"Flags":0,"ParamFlags":[0],"ResultFlags":null}
// <endcallsites>
// <endfuncpreamble>
func T_feeds_if_redefined_indirectwrite(x int) {
ax := &x
if G != 2 {
*ax = G
}
if x == 101 {
panic("bad")
}
}
// params.go T_feeds_if_redefined_indirectwrite_copy 231 0 1
// <endpropsdump>
// {"Flags":0,"ParamFlags":[0],"ResultFlags":null}
// <endcallsites>
// <endfuncpreamble>
func T_feeds_if_redefined_indirectwrite_copy(x int) {
// we don't catch this case, "x" is marked as no info,
// since we're conservative about redefinitions.
ax := &x
cx := x
if G != 2 {
*ax = G
}
if cx == 101 {
panic("bad")
}
}
// params.go T_feeds_if_expr1 251 0 1
// ParamFlags
// 0 ParamFeedsIfOrSwitch
// <endpropsdump>
// {"Flags":0,"ParamFlags":[32],"ResultFlags":null}
// <endcallsites>
// <endfuncpreamble>
func T_feeds_if_expr1(x int) {
if x == 101 || x == 102 || x&0xf == 0 {
panic("bad")
}
}
// params.go T_feeds_if_expr2 262 0 1
// <endpropsdump>
// {"Flags":0,"ParamFlags":[0],"ResultFlags":null}
// <endcallsites>
// <endfuncpreamble>
func T_feeds_if_expr2(x int) {
if (x*x)-(x+x)%x == 101 || x&0xf == 0 {
panic("bad")
}
}
// params.go T_feeds_if_expr3 273 0 1
// <endpropsdump>
// {"Flags":0,"ParamFlags":[0],"ResultFlags":null}
// <endcallsites>
// <endfuncpreamble>
func T_feeds_if_expr3(x int) {
if x-(x&0x1)^378 > (1 - G) {
panic("bad")
}
}
// params.go T_feeds_if_shift_may_panic 284 0 1
// <endpropsdump>
// {"Flags":0,"ParamFlags":[0],"ResultFlags":[0]}
// <endcallsites>
// <endfuncpreamble>
func T_feeds_if_shift_may_panic(x int) *int {
// here if "x" is a constant like 2, we could simplify the "if",
// but if we were to pass in a negative value for "x" we can't
// fold the condition due to the need to panic on negative shift.
if 1<<x > 1024 {
return nil
}
return &G
}
// params.go T_feeds_if_maybe_divide_by_zero 299 0 1
// <endpropsdump>
// {"Flags":0,"ParamFlags":[0],"ResultFlags":null}
// <endcallsites>
// <endfuncpreamble>
func T_feeds_if_maybe_divide_by_zero(x int) {
if 99/x == 3 {
return
}
println("blarg")
}
// params.go T_feeds_indcall 313 0 1
// ParamFlags
// 0 ParamMayFeedIndirectCall
// <endpropsdump>
// {"Flags":0,"ParamFlags":[16],"ResultFlags":null}
// <endcallsites>
// <endfuncpreamble>
func T_feeds_indcall(x func()) {
if G != 20 {
x()
}
}
// params.go T_feeds_indcall_and_if 326 0 1
// ParamFlags
// 0 ParamMayFeedIndirectCall|ParamFeedsIfOrSwitch
// <endpropsdump>
// {"Flags":0,"ParamFlags":[48],"ResultFlags":null}
// <endcallsites>
// <endfuncpreamble>
func T_feeds_indcall_and_if(x func()) {
if x != nil {
x()
}
}
// params.go T_feeds_indcall_with_copy 339 0 1
// ParamFlags
// 0 ParamFeedsIndirectCall
// <endpropsdump>
// {"Flags":0,"ParamFlags":[8],"ResultFlags":null}
// <endcallsites>
// <endfuncpreamble>
func T_feeds_indcall_with_copy(x func()) {
xx := x
if G < 10 {
G--
}
xx()
}
// params.go T_feeds_interface_method_call 354 0 1
// ParamFlags
// 0 ParamFeedsInterfaceMethodCall
// <endpropsdump>
// {"Flags":0,"ParamFlags":[2],"ResultFlags":null}
// <endcallsites>
// <endfuncpreamble>
func T_feeds_interface_method_call(i I) {
i.Blarg()
}
var G int
type T int
type I interface {
Blarg()
}
func (r T) Blarg() {
}

View File

@@ -0,0 +1,370 @@
// Copyright 2023 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.
// DO NOT EDIT (use 'go test -v -update-expected' instead.)
// See cmd/compile/internal/inline/inlheur/testdata/props/README.txt
// for more information on the format of this file.
// <endfilepreamble>
package returns1
import "unsafe"
// returns.go T_simple_allocmem 21 0 1
// ResultFlags
// 0 ResultIsAllocatedMem
// <endpropsdump>
// {"Flags":0,"ParamFlags":null,"ResultFlags":[2]}
// <endcallsites>
// <endfuncpreamble>
func T_simple_allocmem() *Bar {
return &Bar{}
}
// returns.go T_allocmem_two_returns 34 0 1
// ParamFlags
// 0 ParamFeedsIfOrSwitch
// ResultFlags
// 0 ResultIsAllocatedMem
// <endpropsdump>
// {"Flags":0,"ParamFlags":[32],"ResultFlags":[2]}
// <endcallsites>
// <endfuncpreamble>
func T_allocmem_two_returns(x int) *Bar {
// multiple returns
if x < 0 {
return new(Bar)
} else {
return &Bar{x: 2}
}
}
// returns.go T_allocmem_three_returns 52 0 1
// ParamFlags
// 0 ParamFeedsIfOrSwitch
// ResultFlags
// 0 ResultIsAllocatedMem
// <endpropsdump>
// {"Flags":0,"ParamFlags":[32],"ResultFlags":[2]}
// <endcallsites>
// <endfuncpreamble>
func T_allocmem_three_returns(x int) []*Bar {
// more multiple returns
switch x {
case 10, 11, 12:
return make([]*Bar, 10)
case 13:
fallthrough
case 15:
return []*Bar{&Bar{x: 15}}
}
return make([]*Bar, 0, 10)
}
// returns.go T_return_nil 72 0 1
// ResultFlags
// 0 ResultAlwaysSameConstant
// <endpropsdump>
// {"Flags":0,"ParamFlags":null,"ResultFlags":[8]}
// <endcallsites>
// <endfuncpreamble>
func T_return_nil() *Bar {
// simple case: no alloc
return nil
}
// returns.go T_multi_return_nil 84 0 1
// ResultFlags
// 0 ResultAlwaysSameConstant
// <endpropsdump>
// {"Flags":0,"ParamFlags":[0,0],"ResultFlags":[8]}
// <endcallsites>
// <endfuncpreamble>
func T_multi_return_nil(x, y bool) *Bar {
if x && y {
return nil
}
return nil
}
// returns.go T_multi_return_nil_anomoly 98 0 1
// ResultFlags
// 0 ResultIsConcreteTypeConvertedToInterface
// <endpropsdump>
// {"Flags":0,"ParamFlags":[0,0],"ResultFlags":[4]}
// <endcallsites>
// <endfuncpreamble>
func T_multi_return_nil_anomoly(x, y bool) Itf {
if x && y {
var qnil *Q
return qnil
}
var barnil *Bar
return barnil
}
// returns.go T_multi_return_some_nil 112 0 1
// <endpropsdump>
// {"Flags":0,"ParamFlags":[0,0],"ResultFlags":[0]}
// <endcallsites>
// <endfuncpreamble>
func T_multi_return_some_nil(x, y bool) *Bar {
if x && y {
return nil
} else {
return &GB
}
}
// returns.go T_mixed_returns 127 0 1
// ParamFlags
// 0 ParamFeedsIfOrSwitch
// <endpropsdump>
// {"Flags":0,"ParamFlags":[32],"ResultFlags":[0]}
// <endcallsites>
// <endfuncpreamble>
func T_mixed_returns(x int) *Bar {
// mix of alloc and non-alloc
if x < 0 {
return new(Bar)
} else {
return &GB
}
}
// returns.go T_mixed_returns_slice 143 0 1
// ParamFlags
// 0 ParamFeedsIfOrSwitch
// <endpropsdump>
// {"Flags":0,"ParamFlags":[32],"ResultFlags":[0]}
// <endcallsites>
// <endfuncpreamble>
func T_mixed_returns_slice(x int) []*Bar {
// mix of alloc and non-alloc
switch x {
case 10, 11, 12:
return make([]*Bar, 10)
case 13:
fallthrough
case 15:
return []*Bar{&Bar{x: 15}}
}
ba := [...]*Bar{&GB, &GB}
return ba[:]
}
// returns.go T_maps_and_channels 167 0 1
// ResultFlags
// 0 ResultNoInfo
// 1 ResultNoInfo
// 2 ResultNoInfo
// 3 ResultAlwaysSameConstant
// <endpropsdump>
// {"Flags":0,"ParamFlags":[0,0],"ResultFlags":[0,0,0,8]}
// <endcallsites>
// <endfuncpreamble>
func T_maps_and_channels(x int, b bool) (bool, map[int]int, chan bool, unsafe.Pointer) {
// maps and channels
return b, make(map[int]int), make(chan bool), nil
}
// returns.go T_assignment_to_named_returns 179 0 1
// ParamFlags
// 0 ParamFeedsIfOrSwitch
// <endpropsdump>
// {"Flags":0,"ParamFlags":[32],"ResultFlags":[0,0]}
// <endcallsites>
// <endfuncpreamble>
func T_assignment_to_named_returns(x int) (r1 *uint64, r2 *uint64) {
// assignments to named returns and then "return" not supported
r1 = new(uint64)
if x < 1 {
*r1 = 2
}
r2 = new(uint64)
return
}
// returns.go T_named_returns_but_return_explicit_values 199 0 1
// ParamFlags
// 0 ParamFeedsIfOrSwitch
// ResultFlags
// 0 ResultIsAllocatedMem
// 1 ResultIsAllocatedMem
// <endpropsdump>
// {"Flags":0,"ParamFlags":[32],"ResultFlags":[2,2]}
// <endcallsites>
// <endfuncpreamble>
func T_named_returns_but_return_explicit_values(x int) (r1 *uint64, r2 *uint64) {
// named returns ok if all returns are non-empty
rx1 := new(uint64)
if x < 1 {
*rx1 = 2
}
rx2 := new(uint64)
return rx1, rx2
}
// returns.go T_return_concrete_type_to_itf 216 0 1
// ResultFlags
// 0 ResultIsConcreteTypeConvertedToInterface
// <endpropsdump>
// {"Flags":0,"ParamFlags":[0,0],"ResultFlags":[4]}
// <endcallsites>
// <endfuncpreamble>
func T_return_concrete_type_to_itf(x, y int) Itf {
return &Bar{}
}
// returns.go T_return_concrete_type_to_itfwith_copy 227 0 1
// ResultFlags
// 0 ResultIsConcreteTypeConvertedToInterface
// <endpropsdump>
// {"Flags":0,"ParamFlags":[0,0],"ResultFlags":[4]}
// <endcallsites>
// <endfuncpreamble>
func T_return_concrete_type_to_itfwith_copy(x, y int) Itf {
b := &Bar{}
println("whee")
return b
}
// returns.go T_return_concrete_type_to_itf_mixed 238 0 1
// <endpropsdump>
// {"Flags":0,"ParamFlags":[0,0],"ResultFlags":[0]}
// <endcallsites>
// <endfuncpreamble>
func T_return_concrete_type_to_itf_mixed(x, y int) Itf {
if x < y {
b := &Bar{}
return b
}
return nil
}
// returns.go T_return_same_func 253 0 1
// ResultFlags
// 0 ResultAlwaysSameInlinableFunc
// <endpropsdump>
// {"Flags":0,"ParamFlags":null,"ResultFlags":[32]}
// <endcallsites>
// <endfuncpreamble>
func T_return_same_func() func(int) int {
if G < 10 {
return foo
} else {
return foo
}
}
// returns.go T_return_different_funcs 266 0 1
// <endpropsdump>
// {"Flags":0,"ParamFlags":null,"ResultFlags":[0]}
// <endcallsites>
// <endfuncpreamble>
func T_return_different_funcs() func(int) int {
if G != 10 {
return foo
} else {
return bar
}
}
// returns.go T_return_same_closure 286 0 1
// ResultFlags
// 0 ResultAlwaysSameInlinableFunc
// <endpropsdump>
// {"Flags":0,"ParamFlags":null,"ResultFlags":[32]}
// <endcallsites>
// <endfuncpreamble>
// returns.go T_return_same_closure.func1 287 0 1
// <endpropsdump>
// {"Flags":0,"ParamFlags":[0],"ResultFlags":[0]}
// <endcallsites>
// <endfuncpreamble>
func T_return_same_closure() func(int) int {
p := func(q int) int { return q }
if G < 10 {
return p
} else {
return p
}
}
// returns.go T_return_different_closures 312 0 1
// <endpropsdump>
// {"Flags":0,"ParamFlags":null,"ResultFlags":[0]}
// <endcallsites>
// <endfuncpreamble>
// returns.go T_return_different_closures.func1 313 0 1
// <endpropsdump>
// {"Flags":0,"ParamFlags":[0],"ResultFlags":[0]}
// <endcallsites>
// <endfuncpreamble>
// returns.go T_return_different_closures.func2 317 0 1
// ResultFlags
// 0 ResultAlwaysSameConstant
// <endpropsdump>
// {"Flags":0,"ParamFlags":[0],"ResultFlags":[8]}
// <endcallsites>
// <endfuncpreamble>
func T_return_different_closures() func(int) int {
p := func(q int) int { return q }
if G < 10 {
return p
} else {
return func(q int) int { return 101 }
}
}
// returns.go T_return_noninlinable 339 0 1
// ResultFlags
// 0 ResultAlwaysSameFunc
// <endpropsdump>
// {"Flags":0,"ParamFlags":[0],"ResultFlags":[16]}
// <endcallsites>
// <endfuncpreamble>
// returns.go T_return_noninlinable.func1 340 0 1
// <endpropsdump>
// {"Flags":0,"ParamFlags":[0],"ResultFlags":[0]}
// callsite: returns.go:343:4|0 flagstr "" flagval 0 score 4 mask 0 maskstr ""
// <endcallsites>
// <endfuncpreamble>
// returns.go T_return_noninlinable.func1.1 341 0 1
// <endpropsdump>
// {"Flags":0,"ParamFlags":null,"ResultFlags":null}
// <endcallsites>
// <endfuncpreamble>
func T_return_noninlinable(x int) func(int) int {
noti := func(q int) int {
defer func() {
println(q + x)
}()
return q
}
return noti
}
type Bar struct {
x int
y string
}
func (b *Bar) Plark() {
}
type Q int
func (q *Q) Plark() {
}
func foo(x int) int { return x }
func bar(x int) int { return -x }
var G int
var GB Bar
type Itf interface {
Plark()
}

View File

@@ -0,0 +1,231 @@
// Copyright 2023 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.
// DO NOT EDIT (use 'go test -v -update-expected' instead.)
// See cmd/compile/internal/inline/inlheur/testdata/props/README.txt
// for more information on the format of this file.
// <endfilepreamble>
package returns2
// returns2.go T_return_feeds_iface_call 18 0 1
// <endpropsdump>
// {"Flags":0,"ParamFlags":null,"ResultFlags":null}
// callsite: returns2.go:19:13|0 flagstr "" flagval 0 score 1 mask 16384 maskstr "returnFeedsConcreteToInterfaceCallAdj"
// <endcallsites>
// <endfuncpreamble>
func T_return_feeds_iface_call() {
b := newBar(10)
b.Plark()
}
// returns2.go T_multi_return_feeds_iface_call 29 0 1
// <endpropsdump>
// {"Flags":0,"ParamFlags":null,"ResultFlags":null}
// callsite: returns2.go:30:20|0 flagstr "" flagval 0 score 3 mask 16384 maskstr "returnFeedsConcreteToInterfaceCallAdj"
// <endcallsites>
// <endfuncpreamble>
func T_multi_return_feeds_iface_call() {
_, b, _ := newBar2(10)
b.Plark()
}
// returns2.go T_returned_inlinable_func_feeds_indirect_call 41 0 1
// <endpropsdump>
// {"Flags":0,"ParamFlags":[0],"ResultFlags":null}
// callsite: returns2.go:42:18|0 flagstr "" flagval 0 score -51 mask 8200 maskstr "passConstToIfAdj|returnFeedsInlinableFuncToIndCallAdj"
// callsite: returns2.go:44:20|1 flagstr "" flagval 0 score -23 mask 8192 maskstr "returnFeedsInlinableFuncToIndCallAdj"
// <endcallsites>
// <endfuncpreamble>
func T_returned_inlinable_func_feeds_indirect_call(q int) {
f := returnsFunc(10)
f(q)
f2 := returnsFunc2()
f2(q)
}
// returns2.go T_returned_noninlineable_func_feeds_indirect_call 54 0 1
// <endpropsdump>
// {"Flags":0,"ParamFlags":[0],"ResultFlags":null}
// callsite: returns2.go:55:30|0 flagstr "" flagval 0 score -23 mask 4096 maskstr "returnFeedsFuncToIndCallAdj"
// <endcallsites>
// <endfuncpreamble>
func T_returned_noninlineable_func_feeds_indirect_call(q int) {
f := returnsNonInlinableFunc()
f(q)
}
// returns2.go T_multi_return_feeds_indirect_call 65 0 1
// <endpropsdump>
// {"Flags":0,"ParamFlags":[0],"ResultFlags":null}
// callsite: returns2.go:66:29|0 flagstr "" flagval 0 score -21 mask 8192 maskstr "returnFeedsInlinableFuncToIndCallAdj"
// <endcallsites>
// <endfuncpreamble>
func T_multi_return_feeds_indirect_call(q int) {
_, f, _ := multiReturnsFunc()
f(q)
}
// returns2.go T_return_feeds_ifswitch 76 0 1
// <endpropsdump>
// {"Flags":0,"ParamFlags":[0],"ResultFlags":[0]}
// callsite: returns2.go:77:14|0 flagstr "" flagval 0 score 10 mask 2048 maskstr "returnFeedsConstToIfAdj"
// <endcallsites>
// <endfuncpreamble>
func T_return_feeds_ifswitch(q int) int {
x := meaning(q)
if x < 42 {
switch x {
case 42:
return 1
}
}
return 0
}
// returns2.go T_multi_return_feeds_ifswitch 93 0 1
// <endpropsdump>
// {"Flags":0,"ParamFlags":[0],"ResultFlags":[0]}
// callsite: returns2.go:94:21|0 flagstr "" flagval 0 score 9 mask 2048 maskstr "returnFeedsConstToIfAdj"
// <endcallsites>
// <endfuncpreamble>
func T_multi_return_feeds_ifswitch(q int) int {
x, y, z := meanings(q)
if x < y {
switch x {
case 42:
return z
}
}
return 0
}
// returns2.go T_two_calls_feed_ifswitch 111 0 1
// <endpropsdump>
// {"Flags":0,"ParamFlags":[0],"ResultFlags":[0]}
// callsite: returns2.go:115:14|0 flagstr "" flagval 0 score 25 mask 0 maskstr ""
// callsite: returns2.go:116:14|1 flagstr "" flagval 0 score 25 mask 0 maskstr ""
// <endcallsites>
// <endfuncpreamble>
func T_two_calls_feed_ifswitch(q int) int {
// This case we don't handle; for the heuristic to kick in,
// all names in a given if/switch cond have to come from the
// same callsite
x := meaning(q)
y := meaning(-q)
if x < y {
switch x + y {
case 42:
return 1
}
}
return 0
}
// returns2.go T_chained_indirect_call 132 0 1
// <endpropsdump>
// {"Flags":0,"ParamFlags":[0,0],"ResultFlags":null}
// callsite: returns2.go:135:18|0 flagstr "" flagval 0 score -31 mask 8192 maskstr "returnFeedsInlinableFuncToIndCallAdj"
// <endcallsites>
// <endfuncpreamble>
func T_chained_indirect_call(x, y int) {
// Here 'returnsFunc' returns an inlinable func that feeds
// directly into a call (no named intermediate).
G += returnsFunc(x - y)(x + y)
}
// returns2.go T_chained_conc_iface_call 144 0 1
// <endpropsdump>
// {"Flags":0,"ParamFlags":[0,0],"ResultFlags":null}
// callsite: returns2.go:148:8|0 flagstr "" flagval 0 score 1 mask 16384 maskstr "returnFeedsConcreteToInterfaceCallAdj"
// <endcallsites>
// <endfuncpreamble>
func T_chained_conc_iface_call(x, y int) {
// Similar to the case above, return from call returning concrete type
// feeds directly into interface call. Note that only the first
// iface call is interesting here.
newBar(10).Plark().Plark()
}
func returnsFunc(x int) func(int) int {
if x < 0 {
G++
}
return adder
}
func returnsFunc2() func(int) int {
return func(x int) int {
return adder(x)
}
}
func returnsNonInlinableFunc() func(int) int {
return adderNoInline
}
func multiReturnsFunc() (int, func(int) int, int) {
return 42, func(x int) int { G++; return 1 }, -42
}
func adder(x int) int {
G += 1
return G
}
func adderNoInline(x int) int {
defer func() { G += x }()
G += 1
return G
}
func meaning(q int) int {
r := 0
for i := 0; i < 42; i++ {
r += q
}
G += r
return 42
}
func meanings(q int) (int, int, int) {
r := 0
for i := 0; i < 42; i++ {
r += q
}
return 42, 43, r
}
type Bar struct {
x int
y string
}
func (b *Bar) Plark() Itf {
return b
}
type Itf interface {
Plark() Itf
}
func newBar(x int) Itf {
s := 0
for i := 0; i < x; i++ {
s += i
}
return &Bar{
x: s,
}
}
func newBar2(x int) (int, Itf, bool) {
s := 0
for i := 0; i < x; i++ {
s += i
}
return 0, &Bar{x: s}, false
}
var G int