mirror of
https://github.com/golang/go.git
synced 2025-12-08 06:10:04 +00:00
Updates #15462 Semi automatic change with gofmt -r and hand fixups for callers outside internal/gc. All the uses of gc.Oconv outside cmd/compile/internal/gc were for the Oconv(op, 0) form, which is already handled the Op.String method. Replace the use of gc.Oconv(op, 0) with op itself, which will call Op.String via the %v or %s verb. Unexport Oconv. Change-Id: I84da2a2e4381b35f52efce427b2d6a3bccdf2526 Reviewed-on: https://go-review.googlesource.com/22496 Run-TryBot: Dave Cheney <dave@cheney.net> TryBot-Result: Gobot Gobot <gobot@golang.org> Reviewed-by: Josh Bleecher Snyder <josharian@gmail.com>
129 lines
2.5 KiB
Go
129 lines
2.5 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
|
|
|
|
// unsafenmagic rewrites calls to package unsafe's functions into constants.
|
|
func unsafenmagic(nn *Node) *Node {
|
|
fn := nn.Left
|
|
args := nn.List
|
|
|
|
if safemode || fn == nil || fn.Op != ONAME {
|
|
return nil
|
|
}
|
|
s := fn.Sym
|
|
if s == nil {
|
|
return nil
|
|
}
|
|
if s.Pkg != unsafepkg {
|
|
return nil
|
|
}
|
|
|
|
if args.Len() == 0 {
|
|
Yyerror("missing argument for %v", s)
|
|
return nil
|
|
}
|
|
|
|
r := args.First()
|
|
|
|
var v int64
|
|
switch s.Name {
|
|
case "Alignof", "Sizeof":
|
|
r = typecheck(r, Erv)
|
|
r = defaultlit(r, nil)
|
|
tr := r.Type
|
|
if tr == nil {
|
|
goto bad
|
|
}
|
|
dowidth(tr)
|
|
if s.Name == "Alignof" {
|
|
v = int64(tr.Align)
|
|
} else {
|
|
v = tr.Width
|
|
}
|
|
|
|
case "Offsetof":
|
|
// must be a selector.
|
|
if r.Op != OXDOT {
|
|
goto bad
|
|
}
|
|
|
|
// 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.
|
|
r.Left = typecheck(r.Left, Erv)
|
|
base := r.Left
|
|
|
|
r = typecheck(r, Erv)
|
|
switch r.Op {
|
|
case ODOT, ODOTPTR:
|
|
break
|
|
case OCALLPART:
|
|
Yyerror("invalid expression %v: argument is a method value", nn)
|
|
goto ret
|
|
default:
|
|
goto bad
|
|
}
|
|
|
|
// Sum offsets for dots until we reach base.
|
|
for r1 := r; r1 != base; r1 = r1.Left {
|
|
switch r1.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 r1.Left != base {
|
|
Yyerror("invalid expression %v: selector implies indirection of embedded %v", nn, r1.Left)
|
|
goto ret
|
|
}
|
|
fallthrough
|
|
case ODOT:
|
|
v += r1.Xoffset
|
|
default:
|
|
Dump("unsafenmagic", r)
|
|
Fatalf("impossible %v node after dot insertion", oconv(r1.Op, FmtSharp))
|
|
goto bad
|
|
}
|
|
}
|
|
|
|
default:
|
|
return nil
|
|
}
|
|
|
|
if args.Len() > 1 {
|
|
Yyerror("extra arguments for %v", s)
|
|
}
|
|
goto ret
|
|
|
|
bad:
|
|
Yyerror("invalid expression %v", nn)
|
|
|
|
ret:
|
|
// any side effects disappear; ignore init
|
|
var val Val
|
|
val.U = new(Mpint)
|
|
val.U.(*Mpint).SetInt64(v)
|
|
n := Nod(OLITERAL, nil, nil)
|
|
n.Orig = nn
|
|
n.SetVal(val)
|
|
n.Type = Types[TUINTPTR]
|
|
nn.Type = Types[TUINTPTR]
|
|
return n
|
|
}
|
|
|
|
func isunsafebuiltin(n *Node) bool {
|
|
if n == nil || n.Op != ONAME || n.Sym == nil || n.Sym.Pkg != unsafepkg {
|
|
return false
|
|
}
|
|
if n.Sym.Name == "Sizeof" {
|
|
return true
|
|
}
|
|
if n.Sym.Name == "Offsetof" {
|
|
return true
|
|
}
|
|
if n.Sym.Name == "Alignof" {
|
|
return true
|
|
}
|
|
return false
|
|
}
|