https://gcc.gnu.org/bugzilla/show_bug.cgi?id=64502

            Bug ID: 64502
           Summary: Incorrect warning about empty translation units when
                    using pre-compiled headers
           Product: gcc
           Version: 4.9.2
            Status: UNCONFIRMED
          Severity: normal
          Priority: P3
         Component: pch
          Assignee: unassigned at gcc dot gnu.org
          Reporter: johnst...@inn-soft.com

Created attachment 34380
  --> https://gcc.gnu.org/bugzilla/attachment.cgi?id=34380&action=edit
GCC intermediate output of MyProgram.c with GCH

When using a pre-compiled header that contains C code, GCC will complain anyway
that the translation unit is empty - even when it is obviously not.  It appears
that the warning does not consider code that is inside the translation unit.

The test case below is rather contrived to create a minimal test case. 
(Obviously, we aren't putting "int main" in the pre-compiled header!)  However,
in the real world, we use GCC to compile the same source code for several
different platforms.  The pre-compiled header always contains code (e.g. some
typedefs used by all platforms), but the C file itself may exclude all code via
"#if PLATFORM..." if it is not applicable to the current platform.

Steps to reproduce:

1.  Create the following two files - Hello.h and MyProgram.c:

// Hello.h:
// NOTE:  In the real world, we wouldn't be putting "int main" in the
// header, of course.  Instead, there might be some typedefs here that
// aren't used, for example.
int main(void) {
    return 0;
}

// ========================================

// MyProgram.c
#include "Hello.h"
// NOTE:  In the real world, we would be excluding platform-specific code
// by using "#ifdef PLATFORM...." around the entire body of code in this
// C file.

2.  Now, compile it:

$ gcc -pedantic Hello.h -save-temps
$ gcc -pedantic MyProgram.c -o MyProgram -save-temps
MyProgram.c:1:0: warning: ISO C forbids an empty translation unit [-Wpedantic]
 #include "Hello.h"
 ^

3.  As illustrated above, GCC is wrongly complaining that the translation unit
is empty.  It is, in fact, not empty - the code is in the pre-compiled
header...

4.  Removing the pre-compiled header silences the warning:

$ rm Hello.h.gch
$ gcc -pedantic MyProgram.c -o MyProgram -save-temps

The problem is reproduced on both Cygwin 32-bit GCC 4.9.2, and on avr-gcc
distributed by Atmel, version 4.7.2.

Output of gcc -v for the Cygwin version:

Using built-in specs.
COLLECT_GCC=gcc
COLLECT_LTO_WRAPPER=/usr/lib/gcc/i686-pc-cygwin/4.9.2/lto-wrapper.exe
Target: i686-pc-cygwin
Configured with:
/cygdrive/i/szsz/tmpp/gcc/gcc-4.9.2-1.i686/src/gcc-4.9.2/configure
--srcdir=/cygdrive/i/szsz/tmpp/gcc/gcc-4.9.2-1.i686/src/gcc-4.9.2 --prefix=/usr
--exec-prefix=/usr --bindir=/usr/bin --sbindir=/usr/sbin
--libexecdir=/usr/libexec --datadir=/usr/share --localstatedir=/var
--sysconfdir=/etc --libdir=/usr/lib --datarootdir=/usr/share
--docdir=/usr/share/doc/gcc --htmldir=/usr/share/doc/gcc/html -C
--build=i686-pc-cygwin --host=i686-pc-cygwin --target=i686-pc-cygwin
--without-libiconv-prefix --without-libintl-prefix --libexecdir=/usr/lib
--enable-shared --enable-shared-libgcc --enable-static
--enable-version-specific-runtime-libs --enable-bootstrap --enable-__cxa_atexit
--with-dwarf2 --with-arch=i686 --with-tune=generic --disable-sjlj-exceptions
--enable-languages=ada,c,c++,fortran,java,lto,objc,obj-c++ --enable-graphite
--enable-threads=posix --enable-libatomic --enable-libgomp --disable-libitm
--enable-libquadmath --enable-libquadmath-support --enable-libssp
--enable-libada --enable-libjava --enable-libgcj-sublibs --disable-java-awt
--disable-symvers --with-ecj-jar=/usr/share/java/ecj.jar --with-gnu-ld
--with-gnu-as --with-cloog-include=/usr/include/cloog-isl
--without-libiconv-prefix --without-libintl-prefix --with-system-zlib
--enable-linker-build-id
Thread model: posix
gcc version 4.9.2 (GCC) 

Attached are intermediate output files saved with "-save-temps" for cases both
with and without pre-compiled headers.  My conclusion is that this warning only
considers the code in "MyProgram.i" and ignores what code might be included via
the proprietary "#pragma GCC pch_preprocess "Hello.h.gch"" that is apparently
an implementation detail of pre-compiled headers.  Obviously, this doesn't
really relate to C99 grammar, which doesn't even consider pre-compiled headers.

One idea for fixing the problem might be a flag saved in the GCH file
indicating whether the file contained any real code, or whether it is empty. 
The warning would only be raised if the C file AND the GCH file are both empty.

Reply via email to