summaryrefslogtreecommitdiff
path: root/src/cmd/cc/dcl.c
diff options
context:
space:
mode:
authorDaniel Morsing <daniel.morsing@gmail.com>2013-05-22 21:13:30 +0200
committerDaniel Morsing <daniel.morsing@gmail.com>2013-05-22 21:13:30 +0200
commit626ec46c73345dc79a8200fd39f46b63c65be017 (patch)
treede7bd8cc2964239f76ee71edb947dcffbebd49fe /src/cmd/cc/dcl.c
parent86be6ee0e3d3855510b09080f8d347b272230a00 (diff)
downloadgo-626ec46c73345dc79a8200fd39f46b63c65be017.tar.gz
cmd/cc: reject unions containing pointers
If a union contains a pointer, it will mess up the garbage collector, causing memory corruption. R=golang-dev, dave, nightlyone, adg, dvyukov, bradfitz, minux.ma, r, iant CC=golang-dev https://codereview.appspot.com/8469043
Diffstat (limited to 'src/cmd/cc/dcl.c')
-rw-r--r--src/cmd/cc/dcl.c25
1 files changed, 25 insertions, 0 deletions
diff --git a/src/cmd/cc/dcl.c b/src/cmd/cc/dcl.c
index edfc7e75a..090697103 100644
--- a/src/cmd/cc/dcl.c
+++ b/src/cmd/cc/dcl.c
@@ -554,6 +554,28 @@ newlist(Node *l, Node *r)
return new(OLIST, l, r);
}
+static int
+haspointers(Type *t)
+{
+ Type *fld;
+
+ switch(t->etype) {
+ case TSTRUCT:
+ for(fld = t->link; fld != T; fld = fld->down) {
+ if(haspointers(fld))
+ return 1;
+ }
+ return 0;
+ case TARRAY:
+ return haspointers(t->link);
+ case TFUNC:
+ case TIND:
+ return 1;
+ default:
+ return 0;
+ }
+}
+
void
sualign(Type *t)
{
@@ -608,6 +630,9 @@ sualign(Type *t)
diag(Z, "incomplete union element");
l->offset = 0;
l->shift = 0;
+ if((debug['q'] || debug['Q']) && haspointers(l))
+ diag(Z, "precise garbage collector cannot handle unions with pointers");
+
o = align(align(0, l, Ael1, &maxal), l, Ael2, &maxal);
if(o > w)
w = o;