Bug 38987 - Including a precompiled header from another header causes invalid assembly to be generated
Summary: Including a precompiled header from another header causes invalid assembly to...
Status: RESOLVED FIXED
Alias: None
Product: gcc
Classification: Unclassified
Component: preprocessor (show other bugs)
Version: 4.2.4
: P3 normal
Target Milestone: 4.5.0
Assignee: Not yet assigned to anyone
URL:
Keywords: ice-on-valid-code, wrong-code
: 39854 40272 64414 (view as bug list)
Depends on:
Blocks:
 
Reported: 2009-01-27 16:26 UTC by Frank Richter
Modified: 2015-01-12 14:18 UTC (History)
6 users (show)

See Also:
Host: x86_64-pc-linux-gnu
Target: x86_64-pc-linux-gnu
Build:
Known to work: 4.5.0
Known to fail: 4.1.2 4.2.4 4.3.3 4.4.0
Last reconfirmed: 2009-02-24 13:06:14


Attachments
Test case for precompiled header inclusion (468 bytes, application/x-gzip)
2009-01-27 16:28 UTC, Frank Richter
Details

Note You need to log in before you can comment on or make changes to this bug.
Description Frank Richter 2009-01-27 16:26:51 UTC
When a header(A) is precompiled and included from another header(B), compiling a source file using B results in invalid assembly. The message from the assembler is "file number X already allocated".
Comment 1 Frank Richter 2009-01-27 16:28:47 UTC
Created attachment 17192 [details]
Test case for precompiled header inclusion

This test case is a simple scenario where a precompiled header is included by another header. Run 'cause-bug.sh' to precompile a header and then attempt to build a source indirectly using that header-
Comment 2 Richard Biener 2009-01-27 17:14:33 UTC
CXX=g++-4.3 ./cause-error.sh 
In file included from <built-in>:0:
<built-in>:0: internal compiler error: Segmentation fault
Please submit a full bug report,
with preprocessed source if appropriate.
See <http://bugs.opensuse.org/> for instructions.

This looks related to https://bugzilla.novell.com/show_bug.cgi?id=432433
and https://bugzilla.novell.com/show_bug.cgi?id=444153

-> PCH is broken wrt location information.
Comment 3 Frank Richter 2009-01-27 17:18:35 UTC
No ICE here (gcc version 4.2.4 (Gentoo 4.2.4 p1.0)), but the underlying cause might be the same.
Comment 4 Michael Matz 2009-01-28 12:22:42 UTC
I'm fairly sure it's the same underlying problem.  The emitted file numbers
(in the .s file for debug info) are in garbage collected memory.  Hence
the directives emitted when the PCH is not yet loaded and those emitted after
it's loaded might use the same file number.  In this case you use -g3, meaning
to emit directives for defined macros.  These are emitted (obviously) as soon
as the include directive is seen.  This will allocate numbers 1 and 2 for
main.cpp and main.h.  Then the PCH file is loaded, overwriting the internally
(in dwarf2out.c:struct dwarf_file_data) stored file numbers, so we start
counting from 2 again (we overwrite only data from after the main file),
which is given to main.cpp again.

Hence the assembler gives the error message.

Later compilers simply segfault already earlier in the process, because
location info is also overwritten but still referenced, as detailed
in the https://bugzilla.novell.com/show_bug.cgi?id=444153 .

Also, as detailed there, it seems to be a fundamental design choice that the
PCH has to be included from the main file, as the PCH machinery uses the
garbage collection engine to actually retrieve the memory state like it
was when precompiling the file.  This obviously can only work if no stale
references exist to then overwritten information and this in turn can only
be ensured when there isn't "too much" information before loading the PCH file
at all.

No idea how easy this would be to fix, from a cursory look at the whole
machinery it looks quite difficult (at least if one wants to really fix
this, and not just work-around the cases that people happen to hit)
Comment 5 Richard Biener 2009-02-24 13:06:13 UTC
This is a preprocessor bug.  We should not use PCHs when it is not the very
first preprocessing directive in the TU that opens it.  Thus, doc/invoke.texi

"
@item
A precompiled header can't be used once the first C token is seen.  You
can have preprocessor directives before a precompiled header; you can
even include a precompiled header from inside another header, so long as
there are no C tokens before the @code{#include}.
"

is very overly optimistic about conditions a PCH is valid.

Tom, do you have an idea where to best restrict the use of PCHs this way?
Comment 6 Frank Richter 2009-02-24 14:50:14 UTC
Arguably, that makes precompiled headers less useful - in scenarios where you have two big libraries with complicated headers you can at most only use PCHs for one of them. Anyhow, that issue is a separate matter.
Comment 7 rguenther@suse.de 2009-02-24 14:52:10 UTC
Subject: Re:  Including a precompiled header from
 another header causes invalid assembly to be generated

On Tue, 24 Feb 2009, frank dot richter at gmail dot com wrote:

> ------- Comment #6 from frank dot richter at gmail dot com  2009-02-24 14:50 -------
> Arguably, that makes precompiled headers less useful - in scenarios where you
> have two big libraries with complicated headers you can at most only use PCHs
> for one of them. Anyhow, that issue is a separate matter.

Using more than one PCH was never possible.

Richard.
Comment 8 Andrew Pinski 2009-04-23 00:11:42 UTC
*** Bug 39854 has been marked as a duplicate of this bug. ***
Comment 9 Richard Biener 2009-09-22 08:37:49 UTC
Subject: Bug 38987

Author: rguenth
Date: Tue Sep 22 08:37:31 2009
New Revision: 151970

URL: http://gcc.gnu.org/viewcvs?root=gcc&view=rev&rev=151970
Log:
2009-09-22  Richard Guenther  <rguenther@suse.de>

	PR pch/38987
	* files.c (pch_open_file): Disallow non-toplevel PCH inclusion.

Modified:
    trunk/libcpp/ChangeLog
    trunk/libcpp/files.c

Comment 10 Richard Biener 2009-09-22 08:38:20 UTC
Fixed.
Comment 11 Richard Biener 2010-12-05 22:20:24 UTC
*** Bug 40272 has been marked as a duplicate of this bug. ***
Comment 12 Richard Biener 2012-03-07 09:55:32 UTC
Author: rguenth
Date: Wed Mar  7 09:55:26 2012
New Revision: 185029

URL: http://gcc.gnu.org/viewcvs?root=gcc&view=rev&rev=185029
Log:
2012-03-07  Richard Guenther  <rguenther@suse.de>

	PR pch/52518
	PR pch/38987
	* doc/invoke.texi (Precompiled Headers): Remove sentence that
	suggests you can include PCHs from inside another header.

Modified:
    trunk/gcc/ChangeLog
    trunk/gcc/doc/invoke.texi
Comment 13 Jakub Jelinek 2015-01-12 14:18:58 UTC
*** Bug 64414 has been marked as a duplicate of this bug. ***