Bug 57653 - [4.8/4.9 Regression] filename information discarded when using -imacros
Summary: [4.8/4.9 Regression] filename information discarded when using -imacros
Status: RESOLVED FIXED
Alias: None
Product: gcc
Classification: Unclassified
Component: c (show other bugs)
Version: 4.8.2
: P2 normal
Target Milestone: 4.8.5
Assignee: Richard Biener
URL: https://gcc.gnu.org/ml/gcc-patches/20...
Keywords:
Depends on:
Blocks:
 
Reported: 2013-06-19 14:16 UTC by Allan McRae
Modified: 2015-02-12 09:49 UTC (History)
4 users (show)

See Also:
Host:
Target:
Build:
Known to work: 4.7.3, 4.8.5, 4.9.3
Known to fail: 4.8.2, 4.8.4, 4.9.0, 4.9.2
Last reconfirmed: 2013-06-23 00:00:00


Attachments
log of gdb session (2.29 KB, text/x-log)
2013-06-23 12:04 UTC, Allan McRae
Details
gdb log when using -include (2.33 KB, text/x-log)
2013-06-25 11:06 UTC, Allan McRae
Details

Note You need to log in before you can comment on or make changes to this bug.
Description Allan McRae 2013-06-19 14:16:05 UTC
When compiling with the "-imacros" flag, the file name information is lost in error messages and backtraces.

e.g.

> gcc-4.8 -imacros i.h test.c 
<command-line>: In function ‘main’:
<command-line>:5:1: error: expected ‘;’ before ‘}’ token

The problem commit is:
http://gcc.gnu.org/git/?p=gcc.git;a=commitdiff;h=6adc88f8
Comment 1 Manuel López-Ibáñez 2013-06-19 21:01:34 UTC
Can you provide a complete testcase? Thanks.
Comment 2 Allan McRae 2013-06-19 21:57:19 UTC
# echo "int main() { return }" > foo.c
# touch foo.h
# gcc -imacros foo.h foo.c 
<command-line>: In function ‘main’:
<command-line>:1:21: error: expected expression before ‘}’ token
Comment 3 Manuel López-Ibáñez 2013-06-19 22:30:44 UTC
(In reply to Allan McRae from comment #2)
> # echo "int main() { return }" > foo.c
> # touch foo.h
> # gcc -imacros foo.h foo.c 
> <command-line>: In function ‘main’:
> <command-line>:1:21: error: expected expression before ‘}’ token

I cannot reproduce this with r198545, so it seems fixed in mainline. Could you test with that?
Comment 4 Manuel López-Ibáñez 2013-06-19 22:32:30 UTC
I mean in GCC 4.9.0 (trunk), (that revision is the latest I have built).
Comment 5 Allan McRae 2013-06-19 22:58:35 UTC
I still get this with r200224

# gcc-4.9 -v
Using built-in specs.
COLLECT_GCC=gcc-4.9
COLLECT_LTO_WRAPPER=/usr/lib/gcc/x86_64-unknown-linux-gnu/4.9.0/lto-wrapper
Target: x86_64-unknown-linux-gnu
Configured with: /build/gcc-git/src/gcc/configure --prefix=/usr --libdir=/usr/lib --libexecdir=/usr/lib --mandir=/usr/share/man --infodir=/usr/share/info --datadir=/usr/share/gcc-4.9 --with-bugurl='http://aur.archlinux.org/packages.php?ID=16045' --enable-languages=c,c++,lto --enable-shared --enable-threads=posix --with-system-zlib --enable-__cxa_atexit --disable-libunwind-exceptions --enable-clocale=gnu --disable-libstdcxx-pch --enable-gnu-unique-object --enable-linker-build-id --enable-cloog-backend=isl --disable-cloog-version-check --enable-lto --enable-gold --enable-ld=default --enable-plugin --with-plugin-ld=ld.gold --with-linker-hash-style=gnu --disable-install-libiberty --disable-multilib --disable-libssp --disable-werror --enable-checking=release --program-suffix=-4.9 --enable-version-specific-runtime-libs
Thread model: posix
gcc version 4.9.0 20130619 (experimental) (GCC)

Built with 

CFLAGS="-march=x86-64 -mtune=generic -O2 -fstack-protector --param=ssp-buffer-size=4"
LDFLAGS="-Wl,-O1,--sort-common,--as-needed,-z,relro"
Comment 6 Allan McRae 2013-06-20 01:46:59 UTC
I have also confirmed this issue on Fedora rawhide.

gcc 4.8.1 20130603 (Red Hat 4.8.1-1)
Comment 7 Manuel López-Ibáñez 2013-06-20 07:51:25 UTC
(In reply to Allan McRae from comment #6)
> I have also confirmed this issue on Fedora rawhide.
> 
> gcc 4.8.1 20130603 (Red Hat 4.8.1-1)

What I would do to investigate this issue is to put a breakpoint in linemap_add and try to figure out what is the difference with and without the -imacro. There must be some difference there.
Comment 8 Allan McRae 2013-06-23 07:17:56 UTC
I really have no idea what I am looking for...  but adding a breakpoint at linemap_add I see (reason, file):

LC_ENTER "foo.c"
LC_RENAME "<command-line>"
LC_ENTER "/usr/include/stdc-predef.h"
LC_LEAVE 0x0
LC_RENAME "foo.c"
<- correct output printed here
LC_LEAVE 0x0

LC_ENTER "foo.c"
LC_RENAME "<command-line>"
LC_ENTER "foo.h"
LC_LEAVE 0x0
LC_ENTER "/usr/include/stdc-predef.h"
LC_RENAME "foo.c"
LC_LEAVE 0x0
<- incorrect output printed here
LC_LEAVE 0x0

So it looks like it is not leaving "/usr/include/stdc-predef.h" at the right time so the wrong thing is being renamed?
Comment 9 Manuel López-Ibáñez 2013-06-23 10:58:01 UTC
(In reply to Allan McRae from comment #8)
> I really have no idea what I am looking for...  but adding a breakpoint at
> linemap_add I see (reason, file):
> 
> LC_ENTER "foo.c"
> LC_RENAME "<command-line>"
> LC_ENTER "/usr/include/stdc-predef.h"
> LC_LEAVE 0x0
> LC_RENAME "foo.c"
> <- correct output printed here
> LC_LEAVE 0x0
> 
> LC_ENTER "foo.c"
> LC_RENAME "<command-line>"
> LC_ENTER "foo.h"
> LC_LEAVE 0x0
> LC_ENTER "/usr/include/stdc-predef.h"
> LC_RENAME "foo.c"
> LC_LEAVE 0x0
> <- incorrect output printed here
> LC_LEAVE 0x0
> 
> So it looks like it is not leaving "/usr/include/stdc-predef.h" at the right
> time so the wrong thing is being renamed?

It seems a probable cause for this bug. Can you track where the return paths differ? 

Does 

LC_ENTER "/usr/include/stdc-predef.h"

happen through the same functions in both cases?

and the LC_LEAVE 0x0 just afterwards?

Perhaps there is a missing LC_LEAVE or perhaps the order between 

 LC_RENAME "foo.c"
 LC_LEAVE 0x0

should be reversed.

Strangely, I still cannot reproduce this:

manuel@gcc10:~$ ~/test1/200330/install/bin/gcc -imacros foo.h foo.c
foo.c: In function ‘main’:
foo.c:1:21: error: expected expression before ‘}’ token
 int main() { return }
                     ^
manuel@gcc10:~$ ~/test1/200330/install/bin/gcc -v
Using built-in specs.
COLLECT_GCC=/home/manuel/test1/200330/install/bin/gcc
COLLECT_LTO_WRAPPER=/home/manuel/test1/200330/install/bin/../libexec/gcc/x86_64-unknown-linux-gnu/4.9.0/lto-wrapper
Target: x86_64-unknown-linux-gnu
Configured with: /home/manuel/test1/src/configure --prefix=/home/manuel/test1/./200330/install --enable-languages=c,c++,objc,fortran,ada,obj-c++
Thread model: posix
gcc version 4.9.0 20130622 (experimental) [trunk revision 195333] (GCC) 

Are you sure you don't have some local arch-linux patches? Have you tried directly downloading the svn version?
Comment 10 Manuel López-Ibáñez 2013-06-23 10:59:15 UTC
Sorry, I didn't intend to confirm it until someone else can reproduce it.
Comment 11 Allan McRae 2013-06-23 12:04:24 UTC
Created attachment 30345 [details]
log of gdb session

Here is the log from my gdb session.

Arch builds with no patches, just a could of small sed lines that should not affect this.  See our build script (plain bash):
https://projects.archlinux.org/svntogit/packages.git/tree/trunk/PKGBUILD?h=packages/gcc

Since it is also in Fedora rawhide, hopefully someone there can confirm.
Comment 12 Manuel López-Ibáñez 2013-06-23 13:49:24 UTC
(In reply to Allan McRae from comment #11)
> Created attachment 30345 [details]
> log of gdb session
> 
> Here is the log from my gdb session.
> 
> Arch builds with no patches, just a could of small sed lines that should not
> affect this.  See our build script (plain bash):
> https://projects.archlinux.org/svntogit/packages.git/tree/trunk/
> PKGBUILD?h=packages/gcc

Does it do a full bootstrap? My gdb session looks more optimized than yours. Perhaps it is a bug in the host compiler?

My version also does not ever execute this:

Breakpoint 1, linemap_add (set=0x7ffff7ff9000, reason=LC_ENTER, sysp=2,
    to_file=0x140e270 "/usr/include/stdc-predef.h", to_line=1)
    at /build/gcc-git/src/gcc/libcpp/line-map.c:291

In fact, I don't have this file.
manuel@gcc10:~$ cat /etc/debian_version 
6.0.6

so the presence of the file may make a difference (unfortunately, I don't have root access to gcc10 to fake the file and test).
Comment 13 Allan McRae 2013-06-23 13:58:53 UTC
The Arch gcc does the full bootstrap.  The debug build I am using was compiled with DEBUG_CFLAGS="-g -fvar-tracking-assignments".

The file "/usr/include/stdc-predef.h" is from glibc (v2.17 on Arch) and is specifically mentioned as being preincluded in http://gcc.gnu.org/gcc-4.8/porting_to.html.  In fact, using -ffreestanding "solves" the issue.
Comment 14 Manuel López-Ibáñez 2013-06-24 08:17:32 UTC
(In reply to Allan McRae from comment #13)
> The file "/usr/include/stdc-predef.h" is from glibc (v2.17 on Arch) and is
> specifically mentioned as being preincluded in
> http://gcc.gnu.org/gcc-4.8/porting_to.html.  In fact, using -ffreestanding
> "solves" the issue.

So when you use -ffreestanding, is stdc-predef.h still included? 

You could put a break in push_command_line_include and check if -include foo.h still includes stdc-predef.h and whether it shows also the problem. If the file is included but there is no bug, then my guess is that the code executed before or after the pre-include stdc-predef.h is missing something for the -imacros case. If it shows the bug, then the code for pre-including stuff must be wrong somehow, perhaps cpp_push_default_include is doing something wrong when compared to cpp_push_include.
Comment 15 Allan McRae 2013-06-25 00:21:26 UTC
with -ffreestanding

LC_ENTER "foo.c"
LC_RENAME "<command-line>"
LC_ENTER "foo.h"
LC_LEAVE 0x0
LC_RENAME "foo.c"
<- correct output printed here
LC_LEAVE 0x0

so std-predef.h is not included.


I tried with -include foo.h and a breakpoint in push_command_line_include...  I just stepped through from that breakpoint and saw cpp_push_default_include being called for both stdc-predef.h and foo.h.  That also gives the correct output.

# gcc-4.9 -include foo.h foo.c
foo.c: In function ‘main’:
foo.c:1:21: error: expected expression before ‘}’ token
 int main() { return }
Comment 16 Manuel López-Ibáñez 2013-06-25 08:30:33 UTC
(In reply to Allan McRae from comment #15)
> 
> I tried with -include foo.h and a breakpoint in push_command_line_include...
> I just stepped through from that breakpoint and saw cpp_push_default_include
> being called for both stdc-predef.h and foo.h.  That also gives the correct
> output.
> 
> # gcc-4.9 -include foo.h foo.c
> foo.c: In function ‘main’:
> foo.c:1:21: error: expected expression before ‘}’ token
>  int main() { return }

What is the trace of LC_ messages produced here? It seems the -imacros code is missing something. Actually, if you could attach the corresponding gdb session like you did earlier, it would be helpful to compare both.
Comment 17 Allan McRae 2013-06-25 11:06:07 UTC
Created attachment 30359 [details]
gdb log when using -include

When using -include instead of -imacros, the trail is:

LC_ENTER   foo.c
LC_RENAME  <command-line>
LC_ENTER   /usr/include/stdc-predef.h
LC_LEAVE   0x0
LC_ENTER   foo.h
LC_LEAVE   0x0
LC_RENAME  foo.c
LC_LEAVE   0x0

gdb log with -include attached.
Comment 18 Manuel López-Ibáñez 2013-06-25 17:53:58 UTC
Thanks!

I think I know the reason why it is failing, but I am not sure about the proper fix. 

For some reason unknown to me, push_commandline_include should not be called while processing -imacros. -imacros tries to achieve this but playing tricks with include_cursor, but that doesn't stop the pre-included files. Calling cpp_push_include (or cpp_push_default_include) seems to mess up everything (again, no idea why!). This code is really a mess but the simple patch below seems to work. Could you test it?


Index: gcc/c-family/c-opts.c
===================================================================
--- gcc/c-family/c-opts.c       (revision 200330)
+++ gcc/c-family/c-opts.c       (working copy)
@@ -1338,10 +1338,14 @@ c_finish_options (void)

 /* Give CPP the next file given by -include, if any.  */
 static void
 push_command_line_include (void)
 {
+  // This can happen if disabled by -imacros for example.
+  if (include_cursor > deferred_count)
+    return;
+
   if (!done_preinclude)
     {
       done_preinclude = true;
       if (flag_hosted && std_inc && !cpp_opts->preprocessed)
        {
Comment 19 Allan McRae 2013-06-26 03:22:59 UTC
That patch works.  With -imacros foo.h:

LC_ENTER  foo.c
LC_RENAME <command-line>
LC_ENTER  foo.h
LC_LEAVE  0x0
LC_ENTER  /usr/include/stdc-predef.h
LC_LEAVE  0x0
LC_RENAME foo.c
<- correct output
LC_LEAVE  0x0

All other combinations of -include/-imacros/-ffreestanding/no foo.h  all are unchanged as expected.
Comment 20 Manuel López-Ibáñez 2013-06-26 08:48:18 UTC
(In reply to Allan McRae from comment #19)
> That patch works.  With -imacros foo.h:
> 
> LC_ENTER  foo.c
> LC_RENAME <command-line>
> LC_ENTER  foo.h
> LC_LEAVE  0x0
> LC_ENTER  /usr/include/stdc-predef.h
> LC_LEAVE  0x0
> LC_RENAME foo.c
> <- correct output
> LC_LEAVE  0x0
> 
> All other combinations of -include/-imacros/-ffreestanding/no foo.h  all are
> unchanged as expected.

Great! I am certainly too busy at the moment to go through all the steps of the contribution process for this. The patch needs to be fully bootstrapped with the latest trunk, an appropriate testcase needs to be created, plus run the full regression testsuite and compare the results with the regression results of the unpatched trunk and check that no new failures appear. Then, it has to be submitted to gcc-patches with a GNU Changelog.

If you are really interested in fixing this, you should just take the lead. Feel free to modify the patch as you need. The patch is anyway too small to require any kind of legal assignment, but if they ask for it, you can always say I wrote it. I have an assignment in place with the FSF.

When submitting to gcc-patches, CC jsm28@gcc.gnu.org. You can also see in the svn log or svn blame who wrote the -imacro code and CC him/her as well. (You can also CC me).
Comment 21 Manuel López-Ibáñez 2013-06-26 08:49:36 UTC
Once you are in trunk, you can ask the release managers to backport it to the GCC 4.8 branch.
Comment 22 Marek Polacek 2014-07-24 09:00:45 UTC
Author: mpolacek
Date: Thu Jul 24 09:00:13 2014
New Revision: 212972

URL: https://gcc.gnu.org/viewcvs?rev=212972&root=gcc&view=rev
Log:
	PR c/57653
	* c-opts.c (c_finish_options): If -imacros is in effect, return.

	* c-c++-common/pr57653.c: New test.
	* c-c++-common/pr57653.h: New file.
	* c-c++-common/pr57653-2.c: New test.
	* c-c++-common/pr57653-2.h: New file.

Added:
    trunk/gcc/testsuite/c-c++-common/pr57653-2.c
    trunk/gcc/testsuite/c-c++-common/pr57653-2.h
    trunk/gcc/testsuite/c-c++-common/pr57653.c
    trunk/gcc/testsuite/c-c++-common/pr57653.h
Modified:
    trunk/gcc/c-family/ChangeLog
    trunk/gcc/c-family/c-opts.c
    trunk/gcc/testsuite/ChangeLog
Comment 23 Richard Biener 2015-02-11 10:23:17 UTC
If 4.7.3 works this is a regression.  Can we get the patch backported to release branches please?
Comment 24 Richard Biener 2015-02-11 10:23:41 UTC
Anyway, I'll do that (tested 4.8 already).
Comment 25 Richard Biener 2015-02-11 12:14:40 UTC
Author: rguenth
Date: Wed Feb 11 12:14:07 2015
New Revision: 220614

URL: https://gcc.gnu.org/viewcvs?rev=220614&root=gcc&view=rev
Log:
2015-02-11  Richard Biener  <rguenther@suse.de>

	Backport from mainline
	2014-07-24  Marek Polacek  <polacek@redhat.com>

	PR c/57653
	* c-opts.c (c_finish_options): If -imacros is in effect, return.

	* c-c++-common/pr57653.c: New test.
	* c-c++-common/pr57653.h: New file.
	* c-c++-common/pr57653-2.c: New test.
	* c-c++-common/pr57653-2.h: New file.

Added:
    branches/gcc-4_9-branch/gcc/testsuite/c-c++-common/pr57653-2.c
    branches/gcc-4_9-branch/gcc/testsuite/c-c++-common/pr57653-2.h
    branches/gcc-4_9-branch/gcc/testsuite/c-c++-common/pr57653.c
    branches/gcc-4_9-branch/gcc/testsuite/c-c++-common/pr57653.h
Modified:
    branches/gcc-4_9-branch/gcc/c-family/ChangeLog
    branches/gcc-4_9-branch/gcc/c-family/c-opts.c
    branches/gcc-4_9-branch/gcc/testsuite/ChangeLog
Comment 26 Richard Biener 2015-02-11 12:15:26 UTC
Author: rguenth
Date: Wed Feb 11 12:14:54 2015
New Revision: 220615

URL: https://gcc.gnu.org/viewcvs?rev=220615&root=gcc&view=rev
Log:
2015-02-11  Richard Biener  <rguenther@suse.de>

	Backport from mainline
	2014-07-24  Marek Polacek  <polacek@redhat.com>

	PR c/57653
	* c-opts.c (c_finish_options): If -imacros is in effect, return.

	* c-c++-common/pr57653.c: New test.
	* c-c++-common/pr57653.h: New file.
	* c-c++-common/pr57653-2.c: New test.
	* c-c++-common/pr57653-2.h: New file.

Added:
    branches/gcc-4_8-branch/gcc/testsuite/c-c++-common/pr57653-2.c
    branches/gcc-4_8-branch/gcc/testsuite/c-c++-common/pr57653-2.h
    branches/gcc-4_8-branch/gcc/testsuite/c-c++-common/pr57653.c
    branches/gcc-4_8-branch/gcc/testsuite/c-c++-common/pr57653.h
Modified:
    branches/gcc-4_8-branch/gcc/c-family/c-opts.c
    branches/gcc-4_8-branch/gcc/testsuite/ChangeLog
Comment 27 Richard Biener 2015-02-11 12:15:43 UTC
Fixed.
Comment 28 Richard Biener 2015-02-12 09:49:27 UTC
Author: rguenth
Date: Thu Feb 12 09:48:56 2015
New Revision: 220642

URL: https://gcc.gnu.org/viewcvs?rev=220642&root=gcc&view=rev
Log:
2015-02-11  Richard Biener  <rguenther@suse.de>

	Backport from mainline
	2014-07-24  Marek Polacek  <polacek@redhat.com>

	PR c/57653
	* c-opts.c (c_finish_options): If -imacros is in effect, return.

Modified:
    branches/gcc-4_8-branch/gcc/c-family/ChangeLog