Skip to content

Commit b89a840

Browse files
cuonglmgopherbot
authored andcommitted
cmd/compile: add clear(x) builtin
To clear map, and zero content of slice. Updates golang#56351 Change-Id: I5f81dfbc465500f5acadaf2c6beb9b5f0d2c4045 Reviewed-on: https://go-review.googlesource.com/c/go/+/453395 Reviewed-by: Cherry Mui <[email protected]> Reviewed-by: Keith Randall <[email protected]> TryBot-Result: Gopher Robot <[email protected]> Reviewed-by: Keith Randall <[email protected]> Run-TryBot: Cuong Manh Le <[email protected]> Auto-Submit: Cuong Manh Le <[email protected]>
1 parent bb4ea80 commit b89a840

File tree

17 files changed

+256
-142
lines changed

17 files changed

+256
-142
lines changed

src/cmd/compile/internal/escape/call.go

+1-1
Original file line numberDiff line numberDiff line change
@@ -179,7 +179,7 @@ func (e *escape) callCommon(ks []hole, call ir.Node, init *ir.Nodes, wrapper *ir
179179
argument(e.discardHole(), &call.Args[i])
180180
}
181181

182-
case ir.OLEN, ir.OCAP, ir.OREAL, ir.OIMAG, ir.OCLOSE:
182+
case ir.OLEN, ir.OCAP, ir.OREAL, ir.OIMAG, ir.OCLOSE, ir.OCLEAR:
183183
call := call.(*ir.UnaryExpr)
184184
argument(e.discardHole(), &call.X)
185185

src/cmd/compile/internal/escape/stmt.go

+1-1
Original file line numberDiff line numberDiff line change
@@ -180,7 +180,7 @@ func (e *escape) stmt(n ir.Node) {
180180
dsts[i] = res.Nname.(*ir.Name)
181181
}
182182
e.assignList(dsts, n.Results, "return", n)
183-
case ir.OCALLFUNC, ir.OCALLMETH, ir.OCALLINTER, ir.OINLCALL, ir.OCLOSE, ir.OCOPY, ir.ODELETE, ir.OPANIC, ir.OPRINT, ir.OPRINTN, ir.ORECOVER:
183+
case ir.OCALLFUNC, ir.OCALLMETH, ir.OCALLINTER, ir.OINLCALL, ir.OCLEAR, ir.OCLOSE, ir.OCOPY, ir.ODELETE, ir.OPANIC, ir.OPRINT, ir.OPRINTN, ir.ORECOVER:
184184
e.call(nil, n)
185185
case ir.OGO, ir.ODEFER:
186186
n := n.(*ir.GoDeferStmt)

src/cmd/compile/internal/ir/expr.go

+1-1
Original file line numberDiff line numberDiff line change
@@ -747,7 +747,7 @@ func (n *UnaryExpr) SetOp(op Op) {
747747
default:
748748
panic(n.no("SetOp " + op.String()))
749749
case OBITNOT, ONEG, ONOT, OPLUS, ORECV,
750-
OALIGNOF, OCAP, OCLOSE, OIMAG, OLEN, ONEW,
750+
OALIGNOF, OCAP, OCLEAR, OCLOSE, OIMAG, OLEN, ONEW,
751751
OOFFSETOF, OPANIC, OREAL, OSIZEOF,
752752
OCHECKNIL, OCFUNC, OIDATA, OITAB, OSPTR,
753753
OUNSAFESTRINGDATA, OUNSAFESLICEDATA:

src/cmd/compile/internal/ir/fmt.go

+3
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,7 @@ var OpNames = []string{
3939
OCALL: "function call", // not actual syntax
4040
OCAP: "cap",
4141
OCASE: "case",
42+
OCLEAR: "clear",
4243
OCLOSE: "close",
4344
OCOMPLEX: "complex",
4445
OBITNOT: "^",
@@ -182,6 +183,7 @@ var OpPrec = []int{
182183
OCALLMETH: 8,
183184
OCALL: 8,
184185
OCAP: 8,
186+
OCLEAR: 8,
185187
OCLOSE: 8,
186188
OCOMPLIT: 8,
187189
OCONVIFACE: 8,
@@ -767,6 +769,7 @@ func exprFmt(n Node, s fmt.State, prec int) {
767769
case OREAL,
768770
OIMAG,
769771
OCAP,
772+
OCLEAR,
770773
OCLOSE,
771774
OLEN,
772775
ONEW,

src/cmd/compile/internal/ir/node.go

+1
Original file line numberDiff line numberDiff line change
@@ -159,6 +159,7 @@ const (
159159
OCALLMETH // X(Args) (direct method call x.Method(args))
160160
OCALLINTER // X(Args) (interface method call x.Method(args))
161161
OCAP // cap(X)
162+
OCLEAR // clear(X)
162163
OCLOSE // close(X)
163164
OCLOSURE // func Type { Func.Closure.Body } (func literal)
164165
OCOMPLIT // Type{List} (composite literal, not yet lowered to specific form)

src/cmd/compile/internal/ir/op_string.go

+124-123
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

src/cmd/compile/internal/typecheck/const.go

+1
Original file line numberDiff line numberDiff line change
@@ -743,6 +743,7 @@ func callOrChan(n ir.Node) bool {
743743
ir.OCALLINTER,
744744
ir.OCALLMETH,
745745
ir.OCAP,
746+
ir.OCLEAR,
746747
ir.OCLOSE,
747748
ir.OCOMPLEX,
748749
ir.OCOPY,

src/cmd/compile/internal/typecheck/func.go

+23-1
Original file line numberDiff line numberDiff line change
@@ -260,7 +260,7 @@ func tcCall(n *ir.CallExpr, top int) ir.Node {
260260
n.SetTypecheck(0) // re-typechecking new op is OK, not a loop
261261
return typecheck(n, top)
262262

263-
case ir.OCAP, ir.OCLOSE, ir.OIMAG, ir.OLEN, ir.OPANIC, ir.OREAL, ir.OUNSAFESTRINGDATA, ir.OUNSAFESLICEDATA:
263+
case ir.OCAP, ir.OCLEAR, ir.OCLOSE, ir.OIMAG, ir.OLEN, ir.OPANIC, ir.OREAL, ir.OUNSAFESTRINGDATA, ir.OUNSAFESLICEDATA:
264264
typecheckargs(n)
265265
fallthrough
266266
case ir.ONEW, ir.OALIGNOF, ir.OOFFSETOF, ir.OSIZEOF:
@@ -441,6 +441,28 @@ func tcAppend(n *ir.CallExpr) ir.Node {
441441
return n
442442
}
443443

444+
// tcClear typechecks an OCLEAR node.
445+
func tcClear(n *ir.UnaryExpr) ir.Node {
446+
n.X = Expr(n.X)
447+
n.X = DefaultLit(n.X, nil)
448+
l := n.X
449+
t := l.Type()
450+
if t == nil {
451+
n.SetType(nil)
452+
return n
453+
}
454+
455+
switch {
456+
case t.IsMap(), t.IsSlice():
457+
default:
458+
base.Errorf("invalid operation: %v (argument must be a map or slice)", n)
459+
n.SetType(nil)
460+
return n
461+
}
462+
463+
return n
464+
}
465+
444466
// tcClose typechecks an OCLOSE node.
445467
func tcClose(n *ir.UnaryExpr) ir.Node {
446468
n.X = Expr(n.X)

src/cmd/compile/internal/typecheck/stmt.go

+1
Original file line numberDiff line numberDiff line change
@@ -273,6 +273,7 @@ func tcGoDefer(n *ir.GoDeferStmt) {
273273
case ir.OCALLINTER,
274274
ir.OCALLMETH,
275275
ir.OCALLFUNC,
276+
ir.OCLEAR,
276277
ir.OCLOSE,
277278
ir.OCOPY,
278279
ir.ODELETE,

src/cmd/compile/internal/typecheck/typecheck.go

+5-1
Original file line numberDiff line numberDiff line change
@@ -336,7 +336,7 @@ func typecheck(n ir.Node, top int) (res ir.Node) {
336336
case ir.OAPPEND:
337337
// Must be used (and not BinaryExpr/UnaryExpr).
338338
isStmt = false
339-
case ir.OCLOSE, ir.ODELETE, ir.OPANIC, ir.OPRINT, ir.OPRINTN:
339+
case ir.OCLEAR, ir.OCLOSE, ir.ODELETE, ir.OPANIC, ir.OPRINT, ir.OPRINTN:
340340
// Must not be used.
341341
isExpr = false
342342
isStmt = true
@@ -621,6 +621,10 @@ func typecheck1(n ir.Node, top int) ir.Node {
621621
n := n.(*ir.BinaryExpr)
622622
return tcComplex(n)
623623

624+
case ir.OCLEAR:
625+
n := n.(*ir.UnaryExpr)
626+
return tcClear(n)
627+
624628
case ir.OCLOSE:
625629
n := n.(*ir.UnaryExpr)
626630
return tcClose(n)

src/cmd/compile/internal/typecheck/universe.go

+1
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,7 @@ var builtinFuncs = [...]struct {
3434
}{
3535
{"append", ir.OAPPEND},
3636
{"cap", ir.OCAP},
37+
{"clear", ir.OCLEAR},
3738
{"close", ir.OCLOSE},
3839
{"complex", ir.OCOMPLEX},
3940
{"copy", ir.OCOPY},

0 commit comments

Comments
 (0)