mirror of
https://github.com/golang/go.git
synced 2025-05-05 23:53:05 +00:00
cmd/compile,go/types: restrict use of unsafe.{Add,Slice} to go1.17 or newer
This CL updates cmd/compile (including types2) and go/types to report errors about using unsafe.Add and unsafe.Slice when language compatibility is set to Go 1.16 or older. Fixes #46525. Change-Id: I1bfe025a672d9f4b929f443064ad1effd38d0363 Reviewed-on: https://go-review.googlesource.com/c/go/+/324369 Run-TryBot: Matthew Dempsky <mdempsky@google.com> Reviewed-by: Robert Findley <rfindley@google.com> Reviewed-by: Robert Griesemer <gri@golang.org> TryBot-Result: Go Bot <gobot@golang.org> Trust: Matthew Dempsky <mdempsky@google.com>
This commit is contained in:
parent
b29b123e07
commit
962d5c997a
@ -981,6 +981,12 @@ func tcRecover(n *ir.CallExpr) ir.Node {
|
|||||||
|
|
||||||
// tcUnsafeAdd typechecks an OUNSAFEADD node.
|
// tcUnsafeAdd typechecks an OUNSAFEADD node.
|
||||||
func tcUnsafeAdd(n *ir.BinaryExpr) *ir.BinaryExpr {
|
func tcUnsafeAdd(n *ir.BinaryExpr) *ir.BinaryExpr {
|
||||||
|
if !types.AllowsGoVersion(curpkg(), 1, 17) {
|
||||||
|
base.ErrorfVers("go1.17", "unsafe.Add")
|
||||||
|
n.SetType(nil)
|
||||||
|
return n
|
||||||
|
}
|
||||||
|
|
||||||
n.X = AssignConv(Expr(n.X), types.Types[types.TUNSAFEPTR], "argument to unsafe.Add")
|
n.X = AssignConv(Expr(n.X), types.Types[types.TUNSAFEPTR], "argument to unsafe.Add")
|
||||||
n.Y = DefaultLit(Expr(n.Y), types.Types[types.TINT])
|
n.Y = DefaultLit(Expr(n.Y), types.Types[types.TINT])
|
||||||
if n.X.Type() == nil || n.Y.Type() == nil {
|
if n.X.Type() == nil || n.Y.Type() == nil {
|
||||||
@ -997,6 +1003,12 @@ func tcUnsafeAdd(n *ir.BinaryExpr) *ir.BinaryExpr {
|
|||||||
|
|
||||||
// tcUnsafeSlice typechecks an OUNSAFESLICE node.
|
// tcUnsafeSlice typechecks an OUNSAFESLICE node.
|
||||||
func tcUnsafeSlice(n *ir.BinaryExpr) *ir.BinaryExpr {
|
func tcUnsafeSlice(n *ir.BinaryExpr) *ir.BinaryExpr {
|
||||||
|
if !types.AllowsGoVersion(curpkg(), 1, 17) {
|
||||||
|
base.ErrorfVers("go1.17", "unsafe.Slice")
|
||||||
|
n.SetType(nil)
|
||||||
|
return n
|
||||||
|
}
|
||||||
|
|
||||||
n.X = Expr(n.X)
|
n.X = Expr(n.X)
|
||||||
n.Y = Expr(n.Y)
|
n.Y = Expr(n.Y)
|
||||||
if n.X.Type() == nil || n.Y.Type() == nil {
|
if n.X.Type() == nil || n.Y.Type() == nil {
|
||||||
|
@ -579,6 +579,11 @@ func (check *Checker) builtin(x *operand, call *syntax.CallExpr, id builtinId) (
|
|||||||
|
|
||||||
case _Add:
|
case _Add:
|
||||||
// unsafe.Add(ptr unsafe.Pointer, len IntegerType) unsafe.Pointer
|
// unsafe.Add(ptr unsafe.Pointer, len IntegerType) unsafe.Pointer
|
||||||
|
if !check.allowVersion(check.pkg, 1, 17) {
|
||||||
|
check.error(call.Fun, "unsafe.Add requires go1.17 or later")
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
check.assignment(x, Typ[UnsafePointer], "argument to unsafe.Add")
|
check.assignment(x, Typ[UnsafePointer], "argument to unsafe.Add")
|
||||||
if x.mode == invalid {
|
if x.mode == invalid {
|
||||||
return
|
return
|
||||||
@ -675,6 +680,11 @@ func (check *Checker) builtin(x *operand, call *syntax.CallExpr, id builtinId) (
|
|||||||
|
|
||||||
case _Slice:
|
case _Slice:
|
||||||
// unsafe.Slice(ptr *T, len IntegerType) []T
|
// unsafe.Slice(ptr *T, len IntegerType) []T
|
||||||
|
if !check.allowVersion(check.pkg, 1, 17) {
|
||||||
|
check.error(call.Fun, "unsafe.Slice requires go1.17 or later")
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
typ := asPointer(x.typ)
|
typ := asPointer(x.typ)
|
||||||
if typ == nil {
|
if typ == nil {
|
||||||
check.errorf(x, invalidArg+"%s is not a pointer", x)
|
check.errorf(x, invalidArg+"%s is not a pointer", x)
|
||||||
|
@ -588,6 +588,11 @@ func (check *Checker) builtin(x *operand, call *ast.CallExpr, id builtinId) (_ b
|
|||||||
|
|
||||||
case _Add:
|
case _Add:
|
||||||
// unsafe.Add(ptr unsafe.Pointer, len IntegerType) unsafe.Pointer
|
// unsafe.Add(ptr unsafe.Pointer, len IntegerType) unsafe.Pointer
|
||||||
|
if !check.allowVersion(check.pkg, 1, 17) {
|
||||||
|
check.errorf(call.Fun, _InvalidUnsafeAdd, "unsafe.Add requires go1.17 or later")
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
check.assignment(x, Typ[UnsafePointer], "argument to unsafe.Add")
|
check.assignment(x, Typ[UnsafePointer], "argument to unsafe.Add")
|
||||||
if x.mode == invalid {
|
if x.mode == invalid {
|
||||||
return
|
return
|
||||||
@ -684,6 +689,11 @@ func (check *Checker) builtin(x *operand, call *ast.CallExpr, id builtinId) (_ b
|
|||||||
|
|
||||||
case _Slice:
|
case _Slice:
|
||||||
// unsafe.Slice(ptr *T, len IntegerType) []T
|
// unsafe.Slice(ptr *T, len IntegerType) []T
|
||||||
|
if !check.allowVersion(check.pkg, 1, 17) {
|
||||||
|
check.errorf(call.Fun, _InvalidUnsafeSlice, "unsafe.Slice requires go1.17 or later")
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
typ := asPointer(x.typ)
|
typ := asPointer(x.typ)
|
||||||
if typ == nil {
|
if typ == nil {
|
||||||
check.invalidArg(x, _InvalidUnsafeSlice, "%s is not a pointer", x)
|
check.invalidArg(x, _InvalidUnsafeSlice, "%s is not a pointer", x)
|
||||||
|
14
test/fixedbugs/issue46525.go
Normal file
14
test/fixedbugs/issue46525.go
Normal file
@ -0,0 +1,14 @@
|
|||||||
|
// errorcheck -lang=go1.16
|
||||||
|
|
||||||
|
// 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 p
|
||||||
|
|
||||||
|
import "unsafe"
|
||||||
|
|
||||||
|
func main() {
|
||||||
|
_ = unsafe.Add(unsafe.Pointer(nil), 0) // ERROR "unsafe.Add requires go1.17 or later"
|
||||||
|
_ = unsafe.Slice(new(byte), 1) // ERROR "unsafe.Slice requires go1.17 or later"
|
||||||
|
}
|
Loading…
x
Reference in New Issue
Block a user