// tcUnsafeAdd typechecks an OUNSAFEADD node.
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.Y = DefaultLit(Expr(n.Y), types.Types[types.TINT])
if n.X.Type() == nil || n.Y.Type() == nil {
// tcUnsafeSlice typechecks an OUNSAFESLICE node.
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.Y = Expr(n.Y)
if n.X.Type() == nil || n.Y.Type() == nil {
case _Add:
// 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")
if x.mode == invalid {
return
case _Slice:
// 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)
if typ == nil {
check.errorf(x, invalidArg+"%s is not a pointer", x)
case _Add:
// 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")
if x.mode == invalid {
return
case _Slice:
// 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)
if typ == nil {
check.invalidArg(x, _InvalidUnsafeSlice, "%s is not a pointer", x)
--- /dev/null
+// 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"
+}