Relay-Version: version B 2.10 5/3/83; site utzoo.UUCP Posting-Version: version B 2.10.1 6/24/83; site umcp-cs.UUCP Path: utzoo!watmath!clyde!burl!ulysses!allegra!mit-eddie!godot!harvard!seismo!umcp-cs!chris From: chris@umcp-cs.UUCP (Chris Torek) Newsgroups: net.bugs.4bsd,net.unix-wizards Subject: Re: (Improvement on) PCC fix for auto incr+struct/union bug Message-ID: <1415@umcp-cs.UUCP> Date: Wed, 28-Nov-84 17:40:51 EST Article-I.D.: umcp-cs.1415 Posted: Wed Nov 28 17:40:51 1984 Date-Received: Fri, 30-Nov-84 07:05:36 EST References: <1311@umcp-cs.UUCP> Organization: U of Maryland, Computer Science Dept., College Park, MD Lines: 67 Xref: godot net.bugs.4bsd:617 net.unix-wizards:3853 I must not have been very clear in my original message. To forestall further mail, and perhaps to light up some of the deep dark interior of PCC 1, I will elaborate further. To refresh memories a bit, the problem is this: we have a UNARY MUL operation in an expression tree, and we might like to share it with an ASG MINUS (predecrement) or INCR (postincrement) operation. The VAX autoincrement or autodecrement addressing modes can be used if and only if the size of the thing being accessed is "correct"; that is, if it matches the size of the increment or decrement. Now, the actual expression tree, as passed to shumul, looks like this: INCR (or ASG MINUS) p->in.op=INCR (or ASG MINUS) / \ / \ p->in.left->in.op=REG p->in.right->in.op=ICON p->in.left->in.type=ty The "reg" is one of the 6 available registers (r11 through r6), i.e., a "register ty *" in C; the in.type here is "ty *". For example, if we have the C declaration "register char *cp", then p->in.left->in.type is INCREF(CHAR), or "pointer to char". The "constant" is an unnamed integer constant, typically 4 (int *), 2 (short *), or 1 (char *). For these simple cases, the original PCC code worked just fine, was correct, and all that good stuff. Problems occurred, however, with structures. Now let's take the nice little picture above and plug in a structure or union access "ptr++->field". It now looks like this: p->in.op=INCR p->in.type=type of "field" / \ / \ p->in.left->in.op=REG p->in.right->in.op=ICON, size of struct or union p->in.left->in.type=ty Look closely at this! Last time, the size of the object being accessed was the size of DECREF(p->in.left->in.type). This time we have DECREF(p->in.left->in.type) being "STRTY" (or UNIONTY) but *we are not accessing the entire structure!!!* All we are going to access is the "field" portion. Now, fortunately, the value in p->in.right->tn.lval (the value of the integer constant) is already the size of the structure that "ptr" points to (I say "fortunate" only because we have no way to compute it by now, but it is obvious that we need it, so it really isn't just serendipitous). Anyway, this value is the value by which we must increment our register. But if we use the VAX autoincrement addressing mode, we will increment it by "sizeof field". Therefore, the autoincrement addressing mode can be used *if and only if "sizeof field" == p->in.right->tn.lval*. This (of course) is where the original bug was. It checked only the size of DECREF(p->in.left->in.op), but this size is irrelevant when accessing structures and unions. Did I state things clearly and precisely enough this time? (I sure hope so....) -- (This line accidently left nonblank.) In-Real-Life: Chris Torek, Univ of MD Comp Sci Dept (301) 454-7690 UUCP: {seismo,allegra,brl-bmd}!umcp-cs!chris CSNet: chris@umcp-cs ARPA: chris@maryland