mirror of
https://github.com/golang/go.git
synced 2025-12-08 06:10:04 +00:00
Some of the Debug[x] flags are actually boolean too, but not all, so they need to be handled separately. While here, change some obj.Flagstr and obj.Flagint64 calls to directly use flag.StringVar and flag.Int64Var instead. Change-Id: Iccedf6fed4328240ee2257f57fe6d66688f237c4 Reviewed-on: https://go-review.googlesource.com/22052 Reviewed-by: Michael Hudson-Doyle <michael.hudson@canonical.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
|
|
}
|