From mboxrd@z Thu Jan 1 00:00:00 1970 From: erik quanstrom Date: Sun, 2 Mar 2014 11:50:28 -0500 To: 9fans@9fans.net Message-ID: MIME-Version: 1.0 Content-Type: text/plain; charset="US-ASCII" Content-Transfer-Encoding: 7bit Subject: [9fans] cpp bug Topicbox-Message-UUID: c0dd3708-ead8-11e9-9d60-3106f5b1d025 david hoskin found a bug in cpp. - is evaluated right to left, so it computes the wrong result. for example # if 0 - 0 + 4 != 4 # error bogus preprocessor # endif errors, because cpp computes this as if it were # if 0 - (0 + 4) != 4 this is because it evaluates right to left, not right to left. it turns out this is because the evalop uses < rather than <= as the pop (loop) condition for the prec stack. thus a + b + c will push to the end then pop from the right. while the according-to-hoyle fix is to change < to <=, this was done on purpose. it allows symbols that need no eval to be omitted. it would be a major rework to change this assumption. so the hack-upon-hack solution might be to just convert - to + UMINUS(thing). this is going to cause trouble if someone is doing fancy arithmetic with division and counting on non-underflow. here is the diff that works on the test cases, and on everything in /sys/src/cmd/ape. is this acceptable? - erik ---- chula; 9diff eval.c /n/sources/plan9/sys/src/cmd/cpp/eval.c:122,127 - eval.c:122,128 op = ops; *op++ = END; for (rand=0, tp = trp->bp+ntok; tp < trp->lp; tp++) { + retry: if(op >= ops + NSTAK) sysfatal("cpp: can't evaluate #if: increase NSTAK"); switch(tp->type) { /n/sources/plan9/sys/src/cmd/cpp/eval.c:161,166 - eval.c:162,173 } continue; } + if(tp->type==MINUS){ + *op++ = UMINUS; + tp->type = PLUS; + goto retry; + } + /* flow through */ /* plain binary */