]> granicus.if.org Git - re2c/commit
Fixed bug #119: "-f with -b/-g generates incorrect dispatch on fill labels".
authorUlya Trofimovich <skvadrik@gmail.com>
Tue, 25 Aug 2015 10:33:29 +0000 (11:33 +0100)
committerUlya Trofimovich <skvadrik@gmail.com>
Tue, 25 Aug 2015 10:33:29 +0000 (11:33 +0100)
commitef3502b09c491ecc6d9d5ddeba3020c0315947d8
treeb6d042a4371b9c5d443c95b7275393c763c6be13
parentf4c0ad80a6b5395ba48ea37cc2c181411179a91d
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.
23 files changed:
re2c/src/codegen/output.cc
re2c/src/codegen/output.h
re2c/test/bug119.bif.c [new file with mode: 0644]
re2c/test/bug119.bif.re [new file with mode: 0644]
re2c/test/bug119.gif.c [new file with mode: 0644]
re2c/test/bug119.gif.re [new file with mode: 0644]
re2c/test/bug119.if.c [new file with mode: 0644]
re2c/test/bug119.if.re [new file with mode: 0644]
re2c/test/bug119_abort.bif.c [new file with mode: 0644]
re2c/test/bug119_abort.bif.re [new file with mode: 0644]
re2c/test/bug119_abort.gif.c [new file with mode: 0644]
re2c/test/bug119_abort.gif.re [new file with mode: 0644]
re2c/test/bug119_abort.if.c [new file with mode: 0644]
re2c/test/bug119_abort.if.re [new file with mode: 0644]
re2c/test/condition_08.cbif.c
re2c/test/condition_09.cbif.c
re2c/test/condition_09.cgif.c
re2c/test/condition_10.cgif.c
re2c/test/condition_12.cgif.c
re2c/test/condition_14.cbif.c
re2c/test/condition_14.cgif.c
re2c/test/push.fb.c
re2c/test/push.fg.c