Fixed bug #119: "-f with -b/-g generates incorrect dispatch on fill labels".
Consider the following example 1.re:
/*!re2c
"" {}
*/
With -if, re2c would generate correct dispatch:
$ re2c -if 1.re
/* Generated by re2c 0.14.3 on Tue Aug 25 10:41:45 2015 */
switch (YYGETSTATE()) {
default: goto yy0;
case 0: goto yyFillLabel0;
}
yy0:
YYSETSTATE(0);
yyFillLabel0:
{}
With -bif all positive YYGETSTATE() values will lead to yyFillLabel0,
which is clearly an error: values that are greater than 0 should lead
to yy0:
$ re2c -bif 1.re
/* Generated by re2c 0.14.3 on Tue Aug 25 10:40:32 2015 */
if (YYGETSTATE() < 0) {
goto yy0;
} else {
goto yyFillLabel0;
}
yy0:
YYSETSTATE(0);
yyFillLabel0:
{}
With -gif the error is different: all values greater than 0 now cause
undefined behaviour (access to memory not within array bounds):
$ re2c -gif 1.re
/* Generated by re2c 0.14.3 on Tue Aug 25 10:47:41 2015 */
{
static void *yystable[] = {
&&yyFillLabel0,
};
if (YYGETSTATE() < 0) {
goto yy0;
}
goto *yystable[YYGETSTATE()];
yy0:
YYSETSTATE(0);
yyFillLabel0:
{}
}
The situation gets even more tricky with re2c:state:abort configuration.
Besides, YYGETSTATE() macro is called multiple times with -b and -g,
which is not so good. Additional checks with -g don't help gain performance
either.
Fix: always generate simple switch.