prohibit direct use of sync/atomic (u)int32 functions

Also adds the "// +checkalignedignore" escape hatch for packages to opt out of
checking.

See cl/439349432 for justification (https://github.com/google/gvisor/pull/7376).

PiperOrigin-RevId: 444918125
This commit is contained in:
Kevin Krakauer
2022-04-27 11:25:14 -07:00
committed by gVisor bot
parent 3be95d62ae
commit 7124367b82
3 changed files with 33 additions and 7 deletions
+2
View File
@@ -19,6 +19,8 @@
//
// All read-modify-write operations implemented by this package have
// acquire-release memory ordering (like sync/atomic).
//
// +checkalignedignore
package atomicbitops
// AndUint32 atomically applies bitwise AND operation to *addr with val.
+2
View File
@@ -4,4 +4,6 @@
// license that can be found in the LICENSE file.
// Package sync provides synchronization primitives.
//
// +checkalignedignore
package sync
+29 -7
View File
@@ -12,13 +12,17 @@
// See the License for the specific language governing permissions and
// limitations under the License.
// Package checkaligned ensures that atomic (u)int64 operations happen
// Package checkaligned ensures that atomic (u)int operations happen
// exclusively via the atomicbitops package.
//
// We support a "// +checkalignedignore" escape hatch in the package comment
// that disables checking throughout the package.
package checkaligned
import (
"fmt"
"go/ast"
"strings"
"golang.org/x/tools/go/analysis"
)
@@ -26,14 +30,14 @@ import (
// Analyzer defines the entrypoint.
var Analyzer = &analysis.Analyzer{
Name: "checkaligned",
Doc: "prohibits direct use of 64 bit atomic operations",
Doc: "prohibits direct use of atomic int operations",
Run: run,
}
// blocklist lists prohibited identifiers in the atomic package.
//
// TODO(b/228378998): We should do this for 32 bit values too. Can also further
// genericize this to ban other things we don't like (e.g. os.File).
// TODO(b/228378998): We can further genericize this to ban other things we
// don't like (e.g. os.File).
var blocklist = []string{
"AddInt64",
"AddUint64",
@@ -45,12 +49,30 @@ var blocklist = []string{
"StoreUint64",
"SwapInt64",
"SwapUint64",
"AddInt32",
"AddUint32",
"CompareAndSwapInt32",
"CompareAndSwapUint32",
"LoadInt32",
"LoadUint32",
"StoreInt32",
"StoreUint32",
"SwapInt32",
"SwapUint32",
}
func run(pass *analysis.Pass) (interface{}, error) {
// atomicbitops uses 64 bit values safely.
if pass.Pkg.Name() == "atomicbitops" {
return nil, nil
// Check for the "// +checkalignedignore" escape hatch.
for _, file := range pass.Files {
if file.Doc == nil {
continue
}
for _, comment := range file.Doc.List {
if len(comment.Text) > 2 && strings.HasPrefix(comment.Text[2:], " +checkalignedignore") {
return nil, nil
}
}
}
for _, file := range pass.Files {