tinycc-devel
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Tinycc-devel] Bug: multiple-inclusion misoptimization


From: Mark Wooding
Subject: [Tinycc-devel] Bug: multiple-inclusion misoptimization
Date: Wed, 06 May 2009 11:19:46 +0100
User-agent: Gnus/5.11 (Gnus v5.11) Emacs/22.3 (gnu/linux)

There's a long-standing bug in TCC's handling of include file multiple-
inclusion guards.

To demonstrate the bug, you need a bunch of files:

  * A header `foo.h':

        #ifndef TOP_FOO_H
        #define TOP_FOO_H

        struct top_foo { int x; };

        #endif

  * A subdirectory `bar'.

  * A header `bar/thing.h':

        #ifndef BAR_THING_H
        #define BAR_THING_H

        #include "foo.h"
        struct bar_thing { struct bar_foo foo; };

        #endif

  * A header `bar/foo.h':

        #ifndef BAR_FOO_H
        #define BAR_FOO_H

        struct bar_foo { int y; };

        #endif

  * And a main program `test.c':

        #include <stdio.h>

        #include "foo.h"
        #include "bar/thing.h"

        struct test {
          struct top_foo a;
          struct bar_thing b;
        } thing;

        int main(void) { printf("%d\n", (int)sizeof thing); return (0); }

Now:

        [crybaby /tmp/mdw/tcc-test]tcc -run test.c
        4

That's odd.  If I compile this with GCC, I get 8, which is what I
expected on i386.

        [crybaby /tmp/mdw/tcc-test]tcc -E test.c
                 [snip <stdio.h> cruft]
        struct top_foo { int x ; } ;
        struct bar_thing { struct bar_foo foo ; } ;
        struct test {
        struct top_foo a ;
        struct bar_thing b ;
        } thing ;
        int main ( void ) { printf ( "%d\n" , ( int ) sizeof thing ) ; return (
        0 ) ; }

And struct bar_foo is nowhere to be found.

There are actually two bugs.  The first is that TCC fails to diagnose
the fact that struct bar_thing contains a member with incomplete type
(6.7.2.1p2), and instead seems merely to make struct bar_thing be empty.

The second is the one I'm actually interested in, and that's that the
'bar/foo.h' isn't being included.  If I #undef TOP_FOO_H in bar/thing.h,
then everything works as I expect.

TCC keeps a table of include files and their guard macros, so that it
can avoid the overhead of scanning files which are repeatedly included
to no effect.  Unfortunately, the table is indexed by the name used in
the #include directive, rather than some unique identifier for the file
(e.g., its absolute pathname).

When I first encountered the bug, I decided that fixing it wasn't easy
and lost interest.  I'm reporting it now so that (a) it becomes more
widely known, and (b) in case anyone can suggest an easy fix. ;-)

-- [mdw]




reply via email to

[Prev in Thread] Current Thread [Next in Thread]