-
Notifications
You must be signed in to change notification settings - Fork 7
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
cmd/compile: avoid past-the-end pointer when zeroing
When we optimize append(s, make([]T, n)...), we have to be careful not to pass &s[0] + len(s)*sizeof(T) as the argument to memclr, as that pointer might be past-the-end. This can only happen if n is zero, so just special-case n==0 in the generated code. Fixes golang#67255 Change-Id: Ic680711bb8c38440eba5e759363ef65f5945658b Reviewed-on: https://go-review.googlesource.com/c/go/+/584116 Reviewed-by: Austin Clements <austin@google.com> LUCI-TryBot-Result: Go LUCI <golang-scoped@luci-project-accounts.iam.gserviceaccount.com> Reviewed-by: Cuong Manh Le <cuong.manhle.vn@gmail.com> Reviewed-by: Keith Randall <khr@google.com>
- Loading branch information
Showing
2 changed files
with
59 additions
and
17 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,33 @@ | ||
// run | ||
|
||
// Copyright 2024 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 | ||
|
||
var zero int | ||
|
||
var sink any | ||
|
||
func main() { | ||
var objs [][]*byte | ||
for i := 10; i < 200; i++ { | ||
// The objects we're allocating here are pointer-ful. Some will | ||
// max out their size class, which are the ones we want. | ||
// We also allocate from small to large, so that the object which | ||
// maxes out its size class is the last one allocated in that class. | ||
// This allocation pattern leaves the next object in the class | ||
// unallocated, which we need to reproduce the bug. | ||
objs = append(objs, make([]*byte, i)) | ||
} | ||
sink = objs // force heap allocation | ||
|
||
// Bug will happen as soon as the write barrier turns on. | ||
for range 10000 { | ||
sink = make([]*byte, 1024) | ||
for _, s := range objs { | ||
s = append(s, make([]*byte, zero)...) | ||
} | ||
} | ||
} |