This source file includes following definitions.
- unsafenmagic
- isunsafebuiltin
#include <u.h>
#include <libc.h>
#include "go.h"
Node*
unsafenmagic(Node *nn)
{
Node *r, *n, *base, *r1;
Sym *s;
Type *t, *tr;
vlong v;
Val val;
Node *fn;
NodeList *args;
fn = nn->left;
args = nn->list;
if(safemode || fn == N || fn->op != ONAME || (s = fn->sym) == S)
goto no;
if(s->pkg != unsafepkg)
goto no;
if(args == nil) {
yyerror("missing argument for %S", s);
goto no;
}
r = args->n;
if(strcmp(s->name, "Sizeof") == 0) {
typecheck(&r, Erv);
defaultlit(&r, T);
tr = r->type;
if(tr == T)
goto bad;
dowidth(tr);
v = tr->width;
goto yes;
}
if(strcmp(s->name, "Offsetof") == 0) {
if(r->op != OXDOT)
goto bad;
typecheck(&r->left, Erv);
base = r->left;
typecheck(&r, Erv);
switch(r->op) {
case ODOT:
case ODOTPTR:
break;
case OCALLPART:
yyerror("invalid expression %N: argument is a method value", nn);
v = 0;
goto ret;
default:
goto bad;
}
v = 0;
for(r1=r; r1->left!=base; r1=r1->left) {
switch(r1->op) {
case ODOT:
v += r1->xoffset;
break;
case ODOTPTR:
yyerror("invalid expression %N: selector implies indirection of embedded %N", nn, r1->left);
goto ret;
default:
dump("unsafenmagic", r);
fatal("impossible %#O node after dot insertion", r1->op);
goto bad;
}
}
v += r1->xoffset;
goto yes;
}
if(strcmp(s->name, "Alignof") == 0) {
typecheck(&r, Erv);
defaultlit(&r, T);
tr = r->type;
if(tr == T)
goto bad;
t = typ(TSTRUCT);
t->type = typ(TFIELD);
t->type->type = types[TUINT8];
t->type->down = typ(TFIELD);
t->type->down->type = tr;
dowidth(t);
v = t->type->down->width;
goto yes;
}
no:
return N;
bad:
yyerror("invalid expression %N", nn);
v = 0;
goto ret;
yes:
if(args->next != nil)
yyerror("extra arguments for %S", s);
ret:
val.ctype = CTINT;
val.u.xval = mal(sizeof(*n->val.u.xval));
mpmovecfix(val.u.xval, v);
n = nod(OLITERAL, N, N);
n->orig = nn;
n->val = val;
n->type = types[TUINTPTR];
nn->type = types[TUINTPTR];
return n;
}
int
isunsafebuiltin(Node *n)
{
if(n == N || n->op != ONAME || n->sym == S || n->sym->pkg != unsafepkg)
return 0;
if(strcmp(n->sym->name, "Sizeof") == 0)
return 1;
if(strcmp(n->sym->name, "Offsetof") == 0)
return 1;
if(strcmp(n->sym->name, "Alignof") == 0)
return 1;
return 0;
}