diff options
author | Michael Stapelberg <stapelberg@debian.org> | 2013-05-14 18:39:35 +0200 |
---|---|---|
committer | Michael Stapelberg <michael@stapelberg.de> | 2013-05-14 18:39:35 +0200 |
commit | efcc50dfdc94c82ee0292bf71992ecb7c0123061 (patch) | |
tree | 17dca99d1dc7fc4e9fe49c2cf6a99d337d4c039f /src/cmd/gc/unsafe.c | |
parent | 04b08da9af0c450d645ab7389d1467308cfc2db8 (diff) | |
download | golang-efcc50dfdc94c82ee0292bf71992ecb7c0123061.tar.gz |
Imported Upstream version 1.1upstream/1.1
Diffstat (limited to 'src/cmd/gc/unsafe.c')
-rw-r--r-- | src/cmd/gc/unsafe.c | 42 |
1 files changed, 37 insertions, 5 deletions
diff --git a/src/cmd/gc/unsafe.c b/src/cmd/gc/unsafe.c index 95200ad41..ff08c0eef 100644 --- a/src/cmd/gc/unsafe.c +++ b/src/cmd/gc/unsafe.c @@ -16,10 +16,10 @@ Node* unsafenmagic(Node *nn) { - Node *r, *n; + Node *r, *n, *base, *r1; Sym *s; Type *t, *tr; - long v; + vlong v; Val val; Node *fn; NodeList *args; @@ -49,11 +49,43 @@ unsafenmagic(Node *nn) goto yes; } if(strcmp(s->name, "Offsetof") == 0) { - typecheck(&r, Erv); - if(r->op != ODOT && r->op != ODOTPTR) + // 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. + typecheck(&r->left, Erv); + base = r->left; typecheck(&r, Erv); - v = r->xoffset; + 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; + // add offsets for inserted dots. + 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) { |