go/src/cmd/compile/internal/gc/unsafe.go
Matthew Dempsky 3f2cb493e5 cmd/compile: handle unsafe builtins like universal builtins
Reuse the same mechanisms for handling universal builtins like len to
handle unsafe.Sizeof, etc. Allows us to drop package unsafe's export
data, and simplifies some code.

Updates #17508.

Change-Id: I620e0617c24e57e8a2d7cccd0e2de34608779656
Reviewed-on: https://go-review.googlesource.com/31433
Run-TryBot: Matthew Dempsky <mdempsky@google.com>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: Robert Griesemer <gri@golang.org>
2016-10-18 22:34:44 +00:00

74 lines
1.8 KiB
Go

// Copyright 2009 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 gc
// evalunsafe evaluates a package unsafe operation and returns the result.
func evalunsafe(n *Node) int64 {
switch n.Op {
case OALIGNOF, OSIZEOF:
n.Left = typecheck(n.Left, Erv)
n.Left = defaultlit(n.Left, nil)
tr := n.Left.Type
if tr == nil {
yyerror("invalid expression %v", n)
return 0
}
dowidth(tr)
if n.Op == OALIGNOF {
return int64(tr.Align)
}
return tr.Width
case OOFFSETOF:
// must be a selector.
if n.Left.Op != OXDOT {
yyerror("invalid expression %v", n)
return 0
}
// Remember base of selector to find it back after dot insertion.
// Since r->left may be mutated by typechecking, check it explicitly
// first to track it correctly.
n.Left.Left = typecheck(n.Left.Left, Erv)
base := n.Left.Left
n.Left = typecheck(n.Left, Erv)
switch n.Left.Op {
case ODOT, ODOTPTR:
break
case OCALLPART:
yyerror("invalid expression %v: argument is a method value", n)
return 0
default:
yyerror("invalid expression %v", n)
return 0
}
// Sum offsets for dots until we reach base.
var v int64
for r := n.Left; r != base; r = r.Left {
switch r.Op {
case ODOTPTR:
// For Offsetof(s.f), s may itself be a pointer,
// but accessing f must not otherwise involve
// indirection via embedded pointer types.
if r.Left != base {
yyerror("invalid expression %v: selector implies indirection of embedded %v", n, r.Left)
return 0
}
fallthrough
case ODOT:
v += r.Xoffset
default:
Dump("unsafenmagic", n.Left)
Fatalf("impossible %#v node after dot insertion", r.Op)
}
}
return v
}
Fatalf("unexpected op %v", n.Op)
return 0
}