This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
PATCH for preprocessor/14103: [3.4/3.5 Regression] ICEs on "gcc -E-imacros foo.h baz.c"
- From: Per Bothner <per at bothner dot com>
- To: gcc-patches at gcc dot gnu dot org
- Date: Mon, 16 Feb 2004 11:42:49 -0800
- Subject: PATCH for preprocessor/14103: [3.4/3.5 Regression] ICEs on "gcc -E-imacros foo.h baz.c"
The attached patch fixes preprocessor/14103.
Tested on Fedora on mainline.
I haven't tested it on 3.4 but of course I'll
do that before checking it in.
I'll wait a day or two to give people a chance to
object before checking this into mainline and 3.4.
This isn't a minimal patch, because it fixes at
least one other problem: The output from -E would
include a line with a bogus (very high) line number.
This was caused by LAST_SOURCE_LINE_LOCATION (in
pp_file_change) "wrapping around" in the case of
files included from the command line. In that case
subtracting 2 was wrong, but just subtracting 1
is wrong in the normal case. Hence the other changes.
My first patch failed for pch, so I needed a way to
test for pch, and that when I noticed that the pch
field in _cpp_file was misleadingly declared as a
4-value enum when it fact it is only set in one
place as a boolean.
--
--Per Bothner
per@bothner.com http://per.bothner.com/
2004-02-16 Per Bothner <per@bothner.com>
* cpphash.h (struct cpp_buffer): Restore return_at_eof field. This
partly reverts my 2003-10-01 change, because we're back to logically
including <command line> inside the main line.
* cpplex.c (_cpp_get_fresh_line): Check return_at_eof field.
* cppmacro.c (cpp_scan_nooutput): Set return_at_eof of current buffer.
Fixes PR preprocessor/14103.
* cppfiles.c (_cpp_stack_include): When appropriate decrement
line_table's highest_location, fixing LAST_SOURCE_LINE_LOCATION.
(cpp_push_include): Don't need to increment pfile's line field.
* line-map.h (LAST_SOURCE_LINE_LOCATION): Only decrement by 1.
* c-ppoutput.c (print struct): New first_time field.
(init_pp_output): Set print.first_time.
(pp_file_change): Use print.first_time, rather than MAIN_FILE_P,
which is set also for (say) <command line>. Clear print.first_time.
* cppfiles.c (struct _cpp_file): Comment and type for pch field
does not match the code, so fix both.
(should_stack_file): Inline include_pch_p function.
(include_pch_p): Remove pointless function.
* cpphash.h (struct cpp_buffer): Remove unused search_cached field.
Index: c-ppoutput.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/c-ppoutput.c,v
retrieving revision 1.15
diff -u -p -r1.15 c-ppoutput.c
--- c-ppoutput.c 11 Feb 2004 15:29:23 -0000 1.15
+++ c-ppoutput.c 16 Feb 2004 19:29:08 -0000
@@ -36,6 +36,7 @@ static struct
const cpp_token *source; /* Source token for spacing. */
int src_line; /* Line number currently being written. */
unsigned char printed; /* Nonzero if something output at line. */
+ bool first_time; /* pp_file_change hasn't been called yet. */
} print;
/* General output routines. */
@@ -118,6 +119,7 @@ init_pp_output (FILE *out_stream)
print.printed = 0;
print.prev = 0;
print.outf = out_stream;
+ print.first_time = 1;
}
/* Writes out the preprocessed file, handling spacing and paste
@@ -365,12 +367,12 @@ pp_file_change (const struct line_map *m
if (map != NULL)
{
- /* First time? */
- if (MAIN_FILE_P (map))
+ if (print.first_time)
{
/* Avoid printing foo.i when the main file is foo.c. */
if (!cpp_get_options (parse_in)->preprocessed)
print_line (map->start_location, flags);
+ print.first_time = 0;
}
else
{
Index: cppfiles.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/cppfiles.c,v
retrieving revision 1.202
diff -u -p -r1.202 cppfiles.c
--- cppfiles.c 11 Feb 2004 15:29:23 -0000 1.202
+++ cppfiles.c 16 Feb 2004 19:29:08 -0000
@@ -109,11 +109,8 @@ struct _cpp_file
/* If BUFFER above contains the true contents of the file. */
bool buffer_valid;
- /* 0: file not known to be a PCH.
- 1: file is a PCH (on return from find_include_file).
- 2: file is not and never will be a valid precompiled header.
- 3: file is always a valid precompiled header. */
- uchar pch;
+ /* File is a PCH (on return from find_include_file). */
+ bool pch;
};
/* A singly-linked list for all searches for a given file name, with
@@ -180,7 +177,6 @@ static void read_name_map (cpp_dir *dir)
static char *remap_filename (cpp_reader *pfile, _cpp_file *file);
static char *append_file_to_dir (const char *fname, cpp_dir *dir);
static bool validate_pch (cpp_reader *, _cpp_file *file, const char *pchname);
-static bool include_pch_p (_cpp_file *file);
static int pchf_adder (void **slot, void *data);
static int pchf_save_compare (const void *e1, const void *e2);
static int pchf_compare (const void *d_p, const void *e_p);
@@ -577,7 +573,7 @@ should_stack_file (cpp_reader *pfile, _c
return false;
/* Handle PCH files immediately; don't stack them. */
- if (include_pch_p (file))
+ if (file->pch)
{
pfile->cb.read_pch (pfile, file->path, file->fd, file->pchname);
close (file->fd);
@@ -747,13 +743,25 @@ _cpp_stack_include (cpp_reader *pfile, c
enum include_type type)
{
struct cpp_dir *dir;
+ _cpp_file *file;
dir = search_path_head (pfile, fname, angle_brackets, type);
if (!dir)
return false;
- return _cpp_stack_file (pfile, _cpp_find_file (pfile, fname, dir, false),
- type == IT_IMPORT);
+ file = _cpp_find_file (pfile, fname, dir, false);
+
+ /* Compensate for the increment in linemap_add. In the case of a
+ normal #include, we're currently at the start of the line
+ *following* the #include. A separate source_location for this
+ location makes no sense (until we do the LC_LEAVE), and
+ complicates LAST_SOURCE_LINE_LOCATION. This does not apply if we
+ found a PCH file (in which case linemap_add is not called) or we
+ were included from the command-line. */
+ if (! file->pch && file->err_no == 0 && type != IT_CMDLINE)
+ pfile->line_table->highest_location--;
+
+ return _cpp_stack_file (pfile, file, type == IT_IMPORT);
}
/* Could not open FILE. The complication is dependency output. */
@@ -1032,8 +1040,6 @@ _cpp_compare_file_date (cpp_reader *pfil
bool
cpp_push_include (cpp_reader *pfile, const char *fname)
{
- /* Make the command line directive take up a line. */
- pfile->line++;
return _cpp_stack_include (pfile, fname, false, IT_CMDLINE);
}
@@ -1226,13 +1232,6 @@ remap_filename (cpp_reader *pfile, _cpp_
dir = make_cpp_dir (pfile, new_dir, dir->sysp);
fname = p + 1;
}
-}
-
-/* Return true if FILE is usable by PCH. */
-static bool
-include_pch_p (_cpp_file *file)
-{
- return file->pch & 1;
}
/* Returns true if PCHNAME is a valid PCH file for FILE. */
Index: cpphash.h
===================================================================
RCS file: /cvs/gcc/gcc/gcc/cpphash.h,v
retrieving revision 1.210
diff -u -p -r1.210 cpphash.h
--- cpphash.h 12 Feb 2004 02:25:02 -0000 1.210
+++ cpphash.h 16 Feb 2004 19:29:08 -0000
@@ -310,9 +310,10 @@ struct cpp_buffer
buffers. */
unsigned int from_stage3 : 1;
- /* Nonzero means that the directory to start searching for ""
- include files has been calculated and stored in "dir" below. */
- unsigned char search_cached;
+ /* At EOF, a buffer is automatically popped. If RETURN_AT_EOF is
+ true, a CPP_EOF token is then returned. Otherwise, the next
+ token from the enclosing buffer is returned. */
+ unsigned int return_at_eof : 1;
/* One for a system header, two for a C system header file that therefore
needs to be extern "C" protected in C++, and zero otherwise. */
Index: cpplex.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/cpplex.c,v
retrieving revision 1.251
diff -u -p -r1.251 cpplex.c
--- cpplex.c 11 Feb 2004 15:29:24 -0000 1.251
+++ cpplex.c 16 Feb 2004 19:29:09 -0000
@@ -747,6 +747,8 @@ _cpp_lex_token (cpp_reader *pfile)
bool
_cpp_get_fresh_line (cpp_reader *pfile)
{
+ int return_at_eof;
+
/* We can't get a new line until we leave the current directive. */
if (pfile->state.in_directive)
return false;
@@ -779,9 +781,10 @@ _cpp_get_fresh_line (cpp_reader *pfile)
CPP_BUF_COLUMN (buffer, buffer->cur),
"no newline at end of file");
}
-
+
+ return_at_eof = buffer->return_at_eof;
_cpp_pop_buffer (pfile);
- if (pfile->buffer == NULL)
+ if (pfile->buffer == NULL || return_at_eof)
return false;
}
}
Index: cppmacro.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/cppmacro.c,v
retrieving revision 1.144
diff -u -p -r1.144 cppmacro.c
--- cppmacro.c 11 Feb 2004 15:29:28 -0000 1.144
+++ cppmacro.c 16 Feb 2004 19:29:09 -0000
@@ -1138,6 +1138,10 @@ cpp_sys_macro_p (cpp_reader *pfile)
void
cpp_scan_nooutput (cpp_reader *pfile)
{
+ /* Request a CPP_EOF token at the end of this file, rather than
+ transparently continuing with the including file. */
+ pfile->buffer->return_at_eof = true;
+
if (CPP_OPTION (pfile, traditional))
while (_cpp_read_logical_line_trad (pfile))
;
Index: line-map.h
===================================================================
RCS file: /cvs/gcc/gcc/gcc/line-map.h,v
retrieving revision 1.19
diff -u -p -r1.19 line-map.h
--- line-map.h 11 Feb 2004 15:29:30 -0000 1.19
+++ line-map.h 16 Feb 2004 19:29:09 -0000
@@ -147,7 +147,7 @@ extern void linemap_print_containing_fil
#define LAST_SOURCE_LINE(MAP) \
SOURCE_LINE (MAP, LAST_SOURCE_LINE_LOCATION (MAP))
#define LAST_SOURCE_LINE_LOCATION(MAP) \
- ((((MAP)[1].start_location - 2 - (MAP)->start_location) \
+ ((((MAP)[1].start_location - 1 - (MAP)->start_location) \
& ~((1 << (MAP)->column_bits) - 1)) \
+ (MAP)->start_location)