go.tools/ssa: ensure address-deriving operations panic on nil inputs.
&x.f, &x[0], x[i:j], &*x all must panic if x==nil. The first three are already addressed by the semantics of FieldAddr, IndexAddr, Slice; updated docs to reflect this. The final case requires generation of an additional dynamic check. See golang.org/s/go12nil for details. Tested on $GOROOT/test/nilptr2.go (with patch from CL 13108043) Also: remove a TODO where a no-op will do. R=gri, crawshaw CC=golang-dev, rsc https://golang.org/cl/13064044
This commit is contained in:
parent
7072253af5
commit
5cbf2abd36
|
|
@ -438,8 +438,6 @@ func (b *builder) addr(fn *Function, e ast.Expr, escaping bool) lvalue {
|
|||
return &address{addr: fn.emit(v), expr: e}
|
||||
|
||||
case *ast.StarExpr:
|
||||
// TODO(adonovan): fix: implement nil-check if e.X
|
||||
// evaluates to nil, per http://golang.org/s/go12nil.
|
||||
return &address{addr: b.expr(fn, e.X), starPos: e.Star, expr: e}
|
||||
}
|
||||
|
||||
|
|
@ -562,7 +560,14 @@ func (b *builder) expr(fn *Function, e ast.Expr) (result Value) {
|
|||
case *ast.UnaryExpr:
|
||||
switch e.Op {
|
||||
case token.AND: // &X --- potentially escaping.
|
||||
return b.addr(fn, e.X, true).address(fn)
|
||||
addr := b.addr(fn, e.X, true)
|
||||
if _, ok := unparen(e.X).(*ast.StarExpr); ok {
|
||||
// &*p must panic if p is nil (http://golang.org/s/go12nil).
|
||||
// For simplicity, we'll just (suboptimally) rely
|
||||
// on the side effects of a load.
|
||||
addr.load(fn)
|
||||
}
|
||||
return addr.address(fn)
|
||||
case token.ADD:
|
||||
return b.expr(fn, e.X)
|
||||
case token.NOT, token.ARROW, token.SUB, token.XOR: // ! <- - ^
|
||||
|
|
|
|||
|
|
@ -152,7 +152,6 @@ func ext۰runtime۰getgoroot(fn *ssa.Function, args []value) value {
|
|||
}
|
||||
|
||||
func ext۰sync۰runtime_Syncsemcheck(fn *ssa.Function, args []value) value {
|
||||
// TODO(adonovan): do equivalent of calling runtime_Syncsemcheck(size uintptr) here
|
||||
return nil
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -59,6 +59,7 @@ var gorootTestTests = []string{
|
|||
"gc.go",
|
||||
"simassign.go",
|
||||
"iota.go",
|
||||
"nilptr2.go",
|
||||
"goprint.go", // doesn't actually assert anything
|
||||
"utf.go",
|
||||
"method.go",
|
||||
|
|
|
|||
Loading…
Reference in New Issue