The error check patterns in this test are more complex than necessary
because f2 gets inlined into f1. This behavior isn't important to the
test, so disable inlining of f2 and simplify the error check patterns.
Change-Id: Ia8aee92a52f9217ad71b89b2931494047e8d2185
Reviewed-on: https://go-review.googlesource.com/31132
Run-TryBot: Austin Clements <austin@google.com>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: Keith Randall <khr@golang.org>
This adds a //go:notinheap pragma for declarations of types that must
not be heap allocated. We ensure these rules by disallowing new(T),
make([]T), append([]T), or implicit allocation of T, by disallowing
conversions to notinheap types, and by propagating notinheap to any
struct or array that contains notinheap elements.
The utility of this pragma is that we can eliminate write barriers for
writes to pointers to go:notinheap types, since the write barrier is
guaranteed to be a no-op. This will let us mark several scheduler and
memory allocator structures as go:notinheap, which will let us
disallow write barriers in the scheduler and memory allocator much
more thoroughly and also eliminate some problematic hybrid write
barriers.
This also makes go:nowritebarrierrec and go:yeswritebarrierrec much
more powerful. Currently we use go:nowritebarrier all over the place,
but it's almost never what you actually want: when write barriers are
illegal, they're typically illegal for a whole dynamic scope. Partly
this is because go:nowritebarrier has been around longer, but it's
also because go:nowritebarrierrec couldn't be used in situations that
had no-op write barriers or where some nested scope did allow write
barriers. go:notinheap eliminates many no-op write barriers and
go:yeswritebarrierrec makes it possible to opt back in to write
barriers, so these two changes will let us use go:nowritebarrierrec
far more liberally.
This updates #13386, which is about controlling pointers from non-GC'd
memory to GC'd memory. That would require some additional pragma (or
pragmas), but could build on this pragma.
Change-Id: I6314f8f4181535dd166887c9ec239977b54940bd
Reviewed-on: https://go-review.googlesource.com/30939
Reviewed-by: Keith Randall <khr@golang.org>
Reviewed-by: Matthew Dempsky <mdempsky@google.com>
This pragma cancels the effect of go:nowritebarrierrec. This is useful
in the scheduler because there are places where we enter a function
without a valid P (and hence cannot have write barriers), but then
obtain a P. This allows us to annotate the function with
go:nowritebarrierrec and split out the part after we've obtained a P
into a go:yeswritebarrierrec function.
Change-Id: Ic8ce4b6d3c074a1ecd8280ad90eaf39f0ffbcc2a
Reviewed-on: https://go-review.googlesource.com/30938
Reviewed-by: Matthew Dempsky <mdempsky@google.com>
Reviewed-by: Keith Randall <khr@golang.org>
"abc"[1] is not like 'b', in that -"abc"[1] is uint8 math, not ideal constant math.
Delay the constantification until after ideal constant folding is over.
Fixes#11370.
Change-Id: Iba2fc00ca2455959e7bab8f4b8b4aac14b1f9858
Reviewed-on: https://go-review.googlesource.com/15740
Run-TryBot: Russ Cox <rsc@golang.org>
Reviewed-by: Russ Cox <rsc@golang.org>
TryBot-Result: Gobot Gobot <gobot@golang.org>
To compile:
m[k] = v
instead of:
mapassign(maptype, m, &k, &v), do
do:
*mapassign(maptype, m, &k) = v
mapassign returns a pointer to the value slot in the map. It is just
like mapaccess except that it will allocate a new slot if k is not
already present in the map.
This makes map accesses faster but potentially larger (codewise).
It is faster because the write into the map is done when the compiler
knows the concrete type, so it can be done with a few store
instructions instead of calling typedmemmove. We also potentially
avoid stack temporaries to hold v.
The code can be larger when the map has pointers in its value type,
since there is a write barrier call in addition to the mapassign call.
That makes the code at the callsite a bit bigger (go binary is 0.3%
bigger).
This CL is in preparation for doing operations like m[k] += v with
only a single runtime call. That will roughly double the speed of
such operations.
Update #17133
Update #5147
Change-Id: Ia435f032090a2ed905dac9234e693972fe8c2dc5
Reviewed-on: https://go-review.googlesource.com/30815
Run-TryBot: Keith Randall <khr@golang.org>
Reviewed-by: Matthew Dempsky <mdempsky@google.com>
TryBot-Result: Gobot Gobot <gobot@golang.org>
In some cases the members of the root set from which flood
runs themselves escape, without their referents being also
tagged as escaping. Fix this by reflooding from those roots
whose escape increases, and also enhance the "leak" test to
include reachability from a heap-escaped root.
Fixes#17318.
Change-Id: Ied1e75cee17ede8ca72a8b9302ce8201641ec593
Reviewed-on: https://go-review.googlesource.com/30693
Run-TryBot: David Chase <drchase@google.com>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: Russ Cox <rsc@golang.org>
This is a followup to issue #13805. That change avoid leaks for types that
don't have any pointers for the single assignment form of a dottype expression.
This does the same for the double assignment form.
Fixes#15796
Change-Id: I27474cade0ff1f3025cb6392f47b87b33542bc0f
Reviewed-on: https://go-review.googlesource.com/24906
Run-TryBot: Michael Matloob <matloob@golang.org>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: David Chase <drchase@google.com>
With this change, the code in bug #15609 compiles and runs properly:
0000000000401070 <main.jump>:
401070: ff 15 aa 7e 06 00 callq *0x67eaa(%rip) # 468f20 <main.pointer>
401076: c3 retq
0000000000468f20 g O .rodata 0000000000000008 main.pointer
Fixes#15609
Change-Id: Iebb4d5a9f9fff335b693f4efcc97882fe04eefd7
Reviewed-on: https://go-review.googlesource.com/22950
Run-TryBot: David Chase <drchase@google.com>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: David Chase <drchase@google.com>
It tests the behavior of the old deleted compiler.
Fixes#17362.
Change-Id: Ia2fdec734c5cbe724a9de562ed71598f67244ab3
Reviewed-on: https://go-review.googlesource.com/30593
Reviewed-by: Brad Fitzpatrick <bradfitz@golang.org>
Fold MOVDaddr ops into MOVXstorezero ops.
Also fold ADDconst into MOVDaddr so we're sure there isn't
(MOVDstorezero (ADDconst (MOVDaddr ..)))
Without this CL, we get:
v1 = MOVDaddr {s}
v2 = VARDEF {s}
v3 = MOVDstorezero v1 v2
The liveness pass thinks the MOVDaddr is a read of s, so s is
incorrectly thought to be live at the start of the function.
Fixes#17194
Change-Id: I2b4a2f13b12aa5b072941ee1c7b89f3793650cdc
Reviewed-on: https://go-review.googlesource.com/30086
Run-TryBot: Keith Randall <khr@golang.org>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: Lynn Boger <laboger@linux.vnet.ibm.com>
Reviewed-by: Michael Munday <munday@ca.ibm.com>
Update gc liveness to remove special conservative treatment
of ambiguously live vars, since there is no longer a need to
protect against GCDEBUG=gcdead.
Change-Id: Id6e2d03218f7d67911e8436d283005a124e6957f
Reviewed-on: https://go-review.googlesource.com/24896
Reviewed-by: David Chase <drchase@google.com>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Run-TryBot: Ian Lance Taylor <iant@golang.org>
Fixes#4215.
Fixes#6750.
Improves the error message for wrong number of arguments by comparing
the signature of the return call site arguments, versus the function's
expected return arguments.
In this CL, the signature representation of:
+ ideal numbers(TIDEAL) ie float*, complex*, rune, int is
"number" instead of "untyped number".
+ idealstring is "string" instead of "untyped string".
+ idealbool is "bool" instead of "untyped bool".
However, the representation of other types remains as the compiler
would produce.
* Example 1(in the error messages, if all lines were printed):
$ cat main.go && go run main.go
package main
func foo() (int, int) {
return 2.3
}
func foo2() {
return int(2), 2
}
func foo3(v int) (a, b, c, d int) {
if v >= 5 {
return 1
}
return 2, 3
}
func foo4(name string) (string, int) {
switch name {
case "cow":
return "moo"
case "dog":
return "dog", 10, true
case "fish":
return ""
default:
return "lizard", 10
}
}
type S int
type T string
type U float64
func foo5() (S, T, U) {
if false {
return ""
} else {
ptr := new(T)
return ptr
}
return new(S), 12.34, 1 + 0i, 'r', true
}
func foo6() (T, string) {
return "T"
}
./issue4215.go:4: not enough arguments to return, got (number) want (int, int)
./issue4215.go:8: too many arguments to return, got (int, number) want ()
./issue4215.go:13: not enough arguments to return, got (number) want (int, int, int, int)
./issue4215.go:15: not enough arguments to return, got (number, number) want (int, int, int, int)
./issue4215.go:21: not enough arguments to return, got (string) want (string, int)
./issue4215.go:23: too many arguments to return, got (string, number, bool) want (string, int)
./issue4215.go:25: not enough arguments to return, got (string) want (string, int)
./issue4215.go:37: not enough arguments to return, got (string) want (S, T, U)
./issue4215.go:40: not enough arguments to return, got (*T) want (S, T, U)
./issue4215.go:42: too many arguments to return, got (*S, number, number, number, bool) want (S, T, U)
./issue4215.go:46: not enough arguments to return, got (string) want (T, string)
./issue4215.go:46: too many errors
* Example 2:
$ cat 6750.go && go run 6750.go
package main
import "fmt"
func printmany(nums ...int) {
for i, n := range nums {
fmt.Printf("%d: %d\n", i, n)
}
fmt.Printf("\n")
}
func main() {
printmany(1, 2, 3)
printmany([]int{1, 2, 3}...)
printmany(1, "abc", []int{2, 3}...)
}
./issue6750.go:15: too many arguments in call to printmany, got (number, string, []int) want (...int)
Change-Id: I6fdce78553ae81770840070e2c975d3e3c83d5d8
Reviewed-on: https://go-review.googlesource.com/25156
Run-TryBot: Matthew Dempsky <mdempsky@google.com>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: Keith Randall <khr@golang.org>
Mark nil check operations as faulting if their arg is zero.
This lets the late nilcheck pass remove duplicates.
Fixes#17242.
Change-Id: I4c9938d8a5a1e43edd85b4a66f0b34004860bcd9
Reviewed-on: https://go-review.googlesource.com/29952
Run-TryBot: Keith Randall <khr@golang.org>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: Cherry Zhang <cherryyz@google.com>
When processing a fallthrough, the casebody function in swt.go
checks that the last statement has indeed Op == OXFALL (not-processed
fallthrough) before setting it to OFALL (processed fallthrough).
Unfortunately, sometimes the fallthrough statement won't be in the
last node. For example, in
case 0:
return func() int {return 1}()
fallthrough
the compiler generates
autotmp_0 = (func literal)(); return autotmp_0; fallthrough; <node VARKILL>
with an OVARKILL node in the last position. casebody will find that
last.Op != OXFALL, won't mark the fallthrough as processed, and the
fallthrough line will cause a "fallthrough statement out of place" error.
To fix this, we change casebody so that it searches for the fallthrough
statement backwards in the statements list, without assuming that it'll
be in the last position.
Fixes#13262
Change-Id: I366c6caa7fd7442d365bd7a08cc66a552212d9b2
Reviewed-on: https://go-review.googlesource.com/22921
Run-TryBot: Quentin Smith <quentin@golang.org>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: Quentin Smith <quentin@golang.org>
Also adds the 'find leftmost one' instruction (FLOGR) and replaces the
WORD-encoded use of FLOGR in math/big with it.
Change-Id: I18e7cd19e75b8501a6ae8bd925471f7e37ded206
Reviewed-on: https://go-review.googlesource.com/29372
Reviewed-by: Cherry Zhang <cherryyz@google.com>
Run-TryBot: Michael Munday <munday@ca.ibm.com>
TryBot-Result: Gobot Gobot <gobot@golang.org>
We're dropping this behavior in favor of runtime.KeepAlive.
Implement runtime.KeepAlive as an intrinsic.
Update #15843
Change-Id: Ib60225bd30d6770ece1c3c7d1339a06aa25b1cbc
Reviewed-on: https://go-review.googlesource.com/28310
Run-TryBot: Keith Randall <khr@golang.org>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: David Chase <drchase@google.com>
No point in calling a function when we can build the interface
using a known type (or itab) and the address of a local.
Get rid of third arg (preallocated stack space) to convT2{I,E}.
Makes go binary smaller by 0.2%
benchmark old ns/op new ns/op delta
BenchmarkEfaceInteger-8 16.7 10.1 -39.52%
Update #17118
Update #15375
Change-Id: I9724a1f802bfa1e3957bf1856b55558278e198a2
Reviewed-on: https://go-review.googlesource.com/29373
Run-TryBot: Keith Randall <khr@golang.org>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: Matthew Dempsky <mdempsky@google.com>
The compiler incorrectly will error when comparing a nil pointer
interface to a nil pointer of any other type. Example:
(*int)(nil) == interface{}(nil)
Will error with "gc: illegal constant expression: *int == interface {}"
Fixes#16702
Change-Id: I1a15d651df2cfca6762b1783a28b377b2e6ff8c6
Reviewed-on: https://go-review.googlesource.com/27591
Run-TryBot: Matthew Dempsky <mdempsky@google.com>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: Matthew Dempsky <mdempsky@google.com>
ppc64 has an extraneous variable live in some situations.
We need a better tighten pass to get rid of this extra variable.
I'm working on it, but fix the test in the meantime.
Fixes build for ppc64.
Change-Id: I1efb9ccb234a64f2a1c228abd2b3195f67fbeb41
Reviewed-on: https://go-review.googlesource.com/29353
Reviewed-by: David Chase <drchase@google.com>
Unroll s == "ab" to
len(s) == 2 && s[0] == 'a' && s[1] == 'b'
This generates faster and shorter code
by avoiding a runtime call.
Do something similar for !=.
The cutoff length is 6. This was chosen empirically
by examining binary sizes on arm, arm64, 386, and amd64
using the SSA backend.
For all architectures examined, 4, 5, and 6 were
the ideal cutoff, with identical binary sizes.
The distribution of constant string equality sizes
during 'go build -a std' is:
40.81% 622 len 0
14.11% 215 len 4
9.45% 144 len 1
7.81% 119 len 3
7.48% 114 len 5
5.12% 78 len 7
4.13% 63 len 2
3.54% 54 len 8
2.69% 41 len 6
1.18% 18 len 10
0.85% 13 len 9
0.66% 10 len 14
0.59% 9 len 17
0.46% 7 len 11
0.26% 4 len 12
0.20% 3 len 19
0.13% 2 len 13
0.13% 2 len 15
0.13% 2 len 16
0.07% 1 len 20
0.07% 1 len 23
0.07% 1 len 33
0.07% 1 len 36
A cutoff of length 6 covers most of the cases.
Benchmarks on amd64 comparing a string to a constant of length 3:
Cmp/1same-8 4.78ns ± 6% 0.94ns ± 9% -80.26% (p=0.000 n=20+20)
Cmp/1diffbytes-8 6.43ns ± 6% 0.96ns ±11% -85.13% (p=0.000 n=20+20)
Cmp/3same-8 4.71ns ± 5% 1.28ns ± 5% -72.90% (p=0.000 n=20+20)
Cmp/3difffirstbyte-8 6.33ns ± 7% 1.27ns ± 7% -79.90% (p=0.000 n=20+20)
Cmp/3difflastbyte-8 6.34ns ± 8% 1.26ns ± 9% -80.13% (p=0.000 n=20+20)
The change to the prove test preserves the
existing intent of the test. When the string was
short, there was a new "proved in bounds" report
that referred to individual byte comparisons.
Change-Id: I593ac303b0d11f275672090c5c786ea0c6b8da13
Reviewed-on: https://go-review.googlesource.com/26758
Run-TryBot: Josh Bleecher Snyder <josharian@gmail.com>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: Brad Fitzpatrick <bradfitz@golang.org>
staticassign unwraps all CONVNOPs.
However, in the included test, we need the
CONVNOP for everything to typecheck.
Stop unwrapping unnecessarily.
The code we generate for this example is
suboptimal, but that's not new; see #17113.
Fixes#17111.
Change-Id: I29532787a074a6fe19a5cc53271eb9c84bf1b576
Reviewed-on: https://go-review.googlesource.com/29213
Run-TryBot: Josh Bleecher Snyder <josharian@gmail.com>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: Matthew Dempsky <mdempsky@google.com>
Get rid of BlockCheck. Josh goaded me into it, and I went
down a rabbithole making it happen.
NilCheck now panics if the pointer is nil and returns void, as before.
BlockCheck is gone, and NilCheck is no longer a Control value for
any block. It just exists (and deadcode knows not to throw it away).
I rewrote the nilcheckelim pass to handle this case. In particular,
there can now be multiple NilCheck ops per block.
I moved all of the arch-dependent nil check elimination done as
part of ssaGenValue into its own proper pass, so we don't have to
duplicate that code for every architecture.
Making the arch-dependent nil check its own pass means I needed
to add a bunch of flags to the opcode table so I could write
the code without arch-dependent ops everywhere.
Change-Id: I419f891ac9b0de313033ff09115c374163416a9f
Reviewed-on: https://go-review.googlesource.com/29120
Run-TryBot: Keith Randall <khr@golang.org>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: David Chase <drchase@google.com>
The change corrects the values of the largest float32 value (f1) and the
value of the halfway point between f1 and the next, overflow value (f2).
Fixes#17012
Change-Id: Idaf9997b69d61fafbffdb980d751c9857732e14d
Reviewed-on: https://go-review.googlesource.com/29171
Reviewed-by: Robert Griesemer <gri@golang.org>
CL 28978 (6ec993a) accidentally disabled the test (it would only
run if amd64 AND s390x, whereas it should be amd64 OR s390x).
Change-Id: I23c1ad71724ff55f5808d5896b19b62c8ec5af76
Reviewed-on: https://go-review.googlesource.com/28981
Reviewed-by: Brad Fitzpatrick <bradfitz@golang.org>
The new SSA backend modifies the ABI slightly: R0 is now a usable
general purpose register.
Fixes#16677.
Change-Id: I367435ce921e0c7e79e021c80cf8ef5d1d1466cf
Reviewed-on: https://go-review.googlesource.com/28978
Run-TryBot: Michael Munday <munday@ca.ibm.com>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: Keith Randall <khr@golang.org>
Atomic ops on ARM are implemented with kernel calls, so they are
not intrinsified.
Change-Id: I0e7cc2e5526ae1a3d24b4b89be1bd13db071f8ef
Reviewed-on: https://go-review.googlesource.com/28977
Run-TryBot: Cherry Zhang <cherryyz@google.com>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: David Chase <drchase@google.com>
When possible, emit static data rather than
init functions for interface values.
This:
* cuts 32k off cmd/go
* removes several error values from runtime init
* cuts the size of the image/color/palette compiled package from 103k to 34k
* reduces the time to build the package in #15520 from 8s to 1.5s
Fixes#6289Fixes#15528
Change-Id: I317112da17aadb180c958ea328ab380f83e640b4
Reviewed-on: https://go-review.googlesource.com/26668
Run-TryBot: Josh Bleecher Snyder <josharian@gmail.com>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: Matthew Dempsky <mdempsky@google.com>
Redo of CL 28575 with fixed test.
We're in a pre-KeepAlive world for a bit yet, the old tests
were in a client which was in a post-KeepAlive world.
Change-Id: I114fd630339d761ab3306d1d99718d3cb973678d
Reviewed-on: https://go-review.googlesource.com/28582
Run-TryBot: Keith Randall <khr@golang.org>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: Brad Fitzpatrick <bradfitz@golang.org>
Reason for revert: broke the build due to cherrypick;
relies on an unsubmitted parent CL.
Original issue's description:
> cmd/compile: ignore contentEscapes for marking nodes as escaping
>
> We can still stack allocate and VarKill nodes which don't
> escape but their content does.
>
> Fixes#16996
>
> Change-Id: If8aa0fcf2c327b4cb880a3d5af8d213289e6f6bf
> Reviewed-on: https://go-review.googlesource.com/28575
> Run-TryBot: Keith Randall <khr@golang.org>
> TryBot-Result: Gobot Gobot <gobot@golang.org>
> Reviewed-by: David Chase <drchase@google.com>
>
Change-Id: Ie1a325209de14d70af6acb2d78269b7a0450da7a
Reviewed-on: https://go-review.googlesource.com/28578
Reviewed-by: Brad Fitzpatrick <bradfitz@golang.org>
We can still stack allocate and VarKill nodes which don't
escape but their content does.
Fixes#16996
Change-Id: If8aa0fcf2c327b4cb880a3d5af8d213289e6f6bf
Reviewed-on: https://go-review.googlesource.com/28575
Run-TryBot: Keith Randall <khr@golang.org>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: David Chase <drchase@google.com>
Includes test case shown to fail with unpatched compiler.
Fixes#17005.
Change-Id: I49b7b1a3f02736d85846a2588018b73f68d50320
Reviewed-on: https://go-review.googlesource.com/28573
Run-TryBot: David Chase <drchase@google.com>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: Minux Ma <minux@golang.org>
Enabled checks (except for DUFF-ops which aren't implemented yet).
Added ppc64le to relevant test.
Also updated register list to reflect no-longer-reserved-
for-constants status (file was missed in that change).
Updates #16010.
Change-Id: I31b1aac19e14994f760f2ecd02edbeb1f78362e7
Reviewed-on: https://go-review.googlesource.com/28548
Run-TryBot: David Chase <drchase@google.com>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: Cherry Zhang <cherryyz@google.com>
It should alias to Xchg instead of Swap. Found when testing #16985.
Change-Id: If9fd734a1f89b8b2656f421eb31b9d1b0d95a49f
Reviewed-on: https://go-review.googlesource.com/28512
Run-TryBot: Cherry Zhang <cherryyz@google.com>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: Keith Randall <khr@golang.org>
It was fixed earlier in the Go 1.8 cycle.
Add a test.
Fixes#15895
Change-Id: I5834831235d99b9fcf21b435932cdd7ac6dc2c6e
Reviewed-on: https://go-review.googlesource.com/28476
Run-TryBot: Josh Bleecher Snyder <josharian@gmail.com>
Reviewed-by: Brad Fitzpatrick <bradfitz@golang.org>
TryBot-Result: Gobot Gobot <gobot@golang.org>
make(T, n, m) returns a slice of type T with length n and capacity m
where "The size arguments n and m must be of integer type or untyped."
https://tip.golang.org/ref/spec#Making_slices_maps_and_channels
The failure to reject typed non-integer size arguments in make
during compile time was uncovered after https://golang.org/cl/27851
changed the generation of makeslice calls.
Fixes #16940
Updates #16949
Change-Id: Ib1e3576f0e6ad199c9b16b7a50c2db81290c63b4
Reviewed-on: https://go-review.googlesource.com/28301
Reviewed-by: Joe Tsai <thebrokentoaster@gmail.com>
Reviewed-by: Josh Bleecher Snyder <josharian@gmail.com>
Intrinsified atomic op produces <value,memory>. Make sure this
memory is considered in the store chain calculation.
Fixes#16948.
Change-Id: I029f164b123a7e830214297f8373f06ea0bf1e26
Reviewed-on: https://go-review.googlesource.com/28350
Run-TryBot: Cherry Zhang <cherryyz@google.com>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: Keith Randall <khr@golang.org>