GCC Bugzilla – Bug 11810
gcc -pipe -ox.o -c x.c writes erroneous x.o on compile error
Last modified: 2010-05-22 17:57:40 UTC
GCC incorrectly generates an output .o file even if there is a compiler error under the following conditions: -pipe is enabled, -c is enabled, and -o<objname>.o is specified. The output object file is slightly different than an object file generated from a C file without a minor compiler error, for example if the word ERROR is added arbitrarily to the C file. Under these error conditions, some symbols go missing from the output object file. I have verified that the error occurs on gcc 2.95, 3.0.4, 3.2.3, and 3.3.1. >How-To-Repeat: Create a file "foo.c" with the following content, sans angle brackets: >>>> #include <stdio.h> int main(int argc, char** argv) { ERROR printf("Hello World.\n"); return 0; } <<<< Execute the following command with any version of gcc: gcc -pipe -ofoo.o -c foo.c The output is as follows: foo.c: In function main': foo.c:4: error: ERROR' undeclared (first use in this function) foo.c:4: error: (Each undeclared identifier is reported only once foo.c:4: error: for each function it appears in.) foo.c:4: error: syntax error before "printf" However, foo.o is written out. Subsequently, linking it causes an error: gcc test.o The output is: /usr/lib/gcc-lib/i386-linux/3.3.1/../../../crt1.o(.text+0x18): In function _start': : undefined reference to main' collect2: ld returned 1 exit status
*** Bug 10369 has been marked as a duplicate of this bug. ***
I can confirm this on the mainline (20030805). From bug 10369 which is a dup: I've tracked the problem: it is in gcc.c when executing the 'W' spec, it calls add_temporary_file_name or such (don't remember the exact function name, don't have the sources handy). The name that is passed to the function includes the -o switch (e.g. add_temporary_file_name ("-ofile.o")) and on failure the driver tries to delete the file with this name, and naturally fails.
Some more information the driver removes -ofoo.o instead of foo.o.
*** Bug 9470 has been marked as a duplicate of this bug. ***
There are other problems with removing output files. For instance: $ echo 'error!' > x $ gcc -x c x -S x:1: error: parse error before '!' token $ ls x x.s $ rm x.s $ gcc -x c x -save-temps -c x:1: error: parse error before '!' token $ ls x x.i x.s
Similar problems also occur with PCH, see 9470.
Created attachment 6918 [details] patch to fix this problem This patch will fix the above mentioned problem. Detail information about the fix: The gcc spec says, it's ok not to have space between an option and it's arguments for e.g. '-o', '-I' options. In process_command function, when driver finds an option which takes an argument it expects it to be next in the argv list. But in this case, the next argument is -c and we need to separate out the arguments. This is not require in major cases may be because major programs doesn't get compiled with -pipe option where by default driver creates an assembly file only if it finds a syntax free input and then -o gets handled by the assembler. I this case an assembler starts creating the output file as soon as it receives some input due to -pipe option, till compiler finds syntax error. But output file doesn't get removed when there is a syntax error because the driver doesn't know about the output file. Testcase can be as simple as shown below. $ cat x.c int i $ gcc -pipe -ox.o -c x.c
http://gcc.gnu.org/ml/gcc-patches/2004-08/msg00784.html
*** Bug 23269 has been marked as a duplicate of this bug. ***
Patch was reviewed here: <http://gcc.gnu.org/ml/gcc-patches/2005-07/msg01432.html>.
Subject: Bug 11810 Author: nathan Date: Wed Nov 4 15:47:00 2009 New Revision: 153900 URL: http://gcc.gnu.org/viewcvs?root=gcc&view=rev&rev=153900 Log: PR driver/11810 * gcc.c (SWITCHES_NEED_SPACES): Define to "o". * config/alpha/osf.h (SWITCHES_NEED_SPACES): Remove here. * config/mips/iris.h (SWITCHES_NEED_SPACES): Remove here. Modified: trunk/gcc/ChangeLog trunk/gcc/config/alpha/osf.h trunk/gcc/config/mips/iris.h trunk/gcc/gcc.c
Fixed by the indicated commit.