}
</pre>
+<h4 id="vet-frame-pointer">New warning for frame pointer</h4>
+
<p><!-- CL 248686, CL 276372 -->
The vet tool now warns about amd64 assembly that clobbers the BP
register (the frame pointer) without saving and restoring it,
// The Go build system will recognize the directives and arrange for the declared variable
// (in the example above, content) to be populated with the matching files from the file system.
//
-// The //go:embed directive accepts multiple space-separated patterns for brevity,
-// but it can also be repeated, to avoid very long lines when there are many patterns.
-// The patterns are interpreted relative to the package directory containing the source file.
-// The path separator is a forward slash, even on Windows systems.
-// To allow for naming files with spaces in their names, patterns can be written
-// as Go double-quoted or back-quoted string literals.
+// The //go:embed directive accepts multiple space-separated patterns for
+// brevity, but it can also be repeated, to avoid very long lines when there are
+// many patterns. The patterns are interpreted relative to the package directory
+// containing the source file. The path separator is a forward slash, even on
+// Windows systems. Patterns may not contain ‘.’ or ‘..’ or empty path elements,
+// nor may they begin or end with a slash. To match everything in the current
+// directory, use ‘*’ instead of ‘.’. To allow for naming files with spaces in
+// their names, patterns can be written as Go double-quoted or back-quoted
+// string literals.
//
// If a pattern names a directory, all files in the subtree rooted at that directory are
// embedded (recursively), except that files with names beginning with ‘.’ or ‘_’
// Matches for empty directories are ignored. After that, each pattern in a //go:embed line
// must match at least one file or non-empty directory.
//
-// Patterns must not contain ‘.’ or ‘..’ path elements nor begin with a leading slash.
-// To match everything in the current directory, use ‘*’ instead of ‘.’.
-//
// If any patterns are invalid or have invalid matches, the build will fail.
//
// Strings and Bytes
// sequences of path elements, like “x/y/z”.
// Path names must not contain a “.” or “..” or empty element,
// except for the special case that the root directory is named “.”.
+// Leading and trailing slashes (like “/x” or “x/”) are not allowed.
//
// Paths are slash-separated on all systems, even Windows.
// Backslashes must not appear in path names.
// then floor(u1/v1) >= floor(u/v)
//
// Moreover, the difference is at most 2 if len(v1) >= len(u/v)
- // We choose s = B-1 since len(v)-B >= B+1 >= len(u/v)
+ // We choose s = B-1 since len(v)-s >= B+1 >= len(u/v)
s := (B - 1)
// Except for the first step, the top bits are always
// a division remainder, so the quotient length is <= n.
// The number of super-buckets (timeHistNumSuperBuckets), on the
// other hand, defines the range. To reserve room for sub-buckets,
// bit timeHistSubBucketBits is the first bit considered for
- // super-buckets, so super-bucket indicies are adjusted accordingly.
+ // super-buckets, so super-bucket indices are adjusted accordingly.
//
// As an example, consider 45 super-buckets with 16 sub-buckets.
//
total = 0
for i, count := range h.Counts {
total += count
- if total > thresh {
+ if total >= thresh {
return h.Buckets[i]
}
}
return e
}
- fd, e := Open("#d/"+itoa(p[1]), O_CLOEXEC)
+ fd, e := Open("#d/"+itoa(p[1]), O_RDWR|O_CLOEXEC)
if e != nil {
Close(p[0])
Close(p[1])
return e
}
- Close(fd)
+ Close(p[1])
+ p[1] = fd
return nil
}
return
}
fentry := formatEntry(entry)
- finfo := formatInfoEntry(info)
- if fentry != finfo {
- t.errorf("%s: mismatch:\n\tentry = %s\n\tfile.Stat() = %s", path, fentry, finfo)
+ fientry := formatInfoEntry(info)
+ // Note: mismatch here is OK for symlink, because Open dereferences symlink.
+ if fentry != fientry && entry.Type()&fs.ModeSymlink == 0 {
+ t.errorf("%s: mismatch:\n\tentry = %s\n\tfile.Stat() = %s", path, fentry, fientry)
}
einfo, err := entry.Info()
t.errorf("%s: entry.Info: %v", path, err)
return
}
- fentry = formatInfo(einfo)
- finfo = formatInfo(info)
- if fentry != finfo {
- t.errorf("%s: mismatch:\n\tentry.Info() = %s\n\tfile.Stat() = %s\n", path, fentry, finfo)
+ finfo := formatInfo(info)
+ if entry.Type()&fs.ModeSymlink != 0 {
+ // For symlink, just check that entry.Info matches entry on common fields.
+ // Open deferences symlink, so info itself may differ.
+ feentry := formatInfoEntry(einfo)
+ if fentry != feentry {
+ t.errorf("%s: mismatch\n\tentry = %s\n\tentry.Info() = %s\n", path, fentry, feentry)
+ }
+ } else {
+ feinfo := formatInfo(einfo)
+ if feinfo != finfo {
+ t.errorf("%s: mismatch:\n\tentry.Info() = %s\n\tfile.Stat() = %s\n", path, feinfo, finfo)
+ }
}
+ // Stat should be the same as Open+Stat, even for symlinks.
info2, err := fs.Stat(t.fsys, path)
if err != nil {
t.errorf("%s: fs.Stat: %v", path, err)
--- /dev/null
+// Copyright 2021 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 fstest
+
+import (
+ "internal/testenv"
+ "os"
+ "path/filepath"
+ "testing"
+)
+
+func TestSymlink(t *testing.T) {
+ testenv.MustHaveSymlink(t)
+
+ tmp := t.TempDir()
+ tmpfs := os.DirFS(tmp)
+
+ if err := os.WriteFile(filepath.Join(tmp, "hello"), []byte("hello, world\n"), 0644); err != nil {
+ t.Fatal(err)
+ }
+
+ if err := os.Symlink(filepath.Join(tmp, "hello"), filepath.Join(tmp, "hello.link")); err != nil {
+ t.Fatal(err)
+ }
+
+ if err := TestFS(tmpfs, "hello", "hello.link"); err != nil {
+ t.Fatal(err)
+ }
+}