...

Source file src/pkg/cmd/compile/internal/gc/unsafe.go

     1	// Copyright 2009 The Go Authors. All rights reserved.
     2	// Use of this source code is governed by a BSD-style
     3	// license that can be found in the LICENSE file.
     4	
     5	package gc
     6	
     7	// evalunsafe evaluates a package unsafe operation and returns the result.
     8	func evalunsafe(n *Node) int64 {
     9		switch n.Op {
    10		case OALIGNOF, OSIZEOF:
    11			n.Left = typecheck(n.Left, ctxExpr)
    12			n.Left = defaultlit(n.Left, nil)
    13			tr := n.Left.Type
    14			if tr == nil {
    15				return 0
    16			}
    17			dowidth(tr)
    18			if n.Op == OALIGNOF {
    19				return int64(tr.Align)
    20			}
    21			return tr.Width
    22	
    23		case OOFFSETOF:
    24			// must be a selector.
    25			if n.Left.Op != OXDOT {
    26				yyerror("invalid expression %v", n)
    27				return 0
    28			}
    29	
    30			// Remember base of selector to find it back after dot insertion.
    31			// Since r->left may be mutated by typechecking, check it explicitly
    32			// first to track it correctly.
    33			n.Left.Left = typecheck(n.Left.Left, ctxExpr)
    34			base := n.Left.Left
    35	
    36			n.Left = typecheck(n.Left, ctxExpr)
    37			if n.Left.Type == nil {
    38				return 0
    39			}
    40			switch n.Left.Op {
    41			case ODOT, ODOTPTR:
    42				break
    43			case OCALLPART:
    44				yyerror("invalid expression %v: argument is a method value", n)
    45				return 0
    46			default:
    47				yyerror("invalid expression %v", n)
    48				return 0
    49			}
    50	
    51			// Sum offsets for dots until we reach base.
    52			var v int64
    53			for r := n.Left; r != base; r = r.Left {
    54				switch r.Op {
    55				case ODOTPTR:
    56					// For Offsetof(s.f), s may itself be a pointer,
    57					// but accessing f must not otherwise involve
    58					// indirection via embedded pointer types.
    59					if r.Left != base {
    60						yyerror("invalid expression %v: selector implies indirection of embedded %v", n, r.Left)
    61						return 0
    62					}
    63					fallthrough
    64				case ODOT:
    65					v += r.Xoffset
    66				default:
    67					Dump("unsafenmagic", n.Left)
    68					Fatalf("impossible %#v node after dot insertion", r.Op)
    69				}
    70			}
    71			return v
    72		}
    73	
    74		Fatalf("unexpected op %v", n.Op)
    75		return 0
    76	}
    77	

View as plain text