Attached is a suggested fix for a long-standing C pre-processor bug. Ref: http://gcc.gnu.org/bugzilla/show_bug.cgi?id=33919 Ref: http://gcc.gnu.org/ml/gcc/2004-10/msg00534.html
The patch implements the approach suggested by Harald van Dijk in the cited bug report. I am not familiar with the subtleties of the C pre-processor, and do not know if there may be some surprises or special cases not covered. The fix does appear to provide the expected result as demonstrated by the included test case. I have a specific question re: this new code. + name = _cpp_get_file_name (pfile->main_file); + if (!name) + name = "<unknown>"; I wasn't sure whether 'name' can have a NULL value, and handled that case as shown above. Would a gcc_assert() be more appropriate, or is it safe to simply assume that the name value is not NULL? Please review. Thanks, - Gary
Index: gcc/testsuite/gcc.dg/pr33919-2.h =================================================================== --- gcc/testsuite/gcc.dg/pr33919-2.h (revision 0) +++ gcc/testsuite/gcc.dg/pr33919-2.h (revision 0) @@ -0,0 +1 @@ +char *nested_inc_base_file = __BASE_FILE__; Index: gcc/testsuite/gcc.dg/pr33919.c =================================================================== --- gcc/testsuite/gcc.dg/pr33919.c (revision 0) +++ gcc/testsuite/gcc.dg/pr33919.c (revision 0) @@ -0,0 +1,20 @@ +/* PR preprocessor/pr33919 */ +/* { dg-do run } */ +/* { dg-options "-I . -include ${srcdir}/gcc.dg/pr33919-0.h" } */ + +#include "pr33919-1.h" + +extern int strcmp (const char *, const char *); +extern void abort(void); + +int +main () +{ + if (strcmp (base_file, __FILE__)) + abort (); + if (strcmp (inc_base_file, __FILE__)) + abort (); + if (strcmp (nested_inc_base_file, __FILE__)) + abort (); + return 0; +} Index: gcc/testsuite/gcc.dg/pr33919-0.h =================================================================== --- gcc/testsuite/gcc.dg/pr33919-0.h (revision 0) +++ gcc/testsuite/gcc.dg/pr33919-0.h (revision 0) @@ -0,0 +1 @@ +char *base_file = __BASE_FILE__; Index: gcc/testsuite/gcc.dg/pr33919-1.h =================================================================== --- gcc/testsuite/gcc.dg/pr33919-1.h (revision 0) +++ gcc/testsuite/gcc.dg/pr33919-1.h (revision 0) @@ -0,0 +1,2 @@ +#include "pr33919-2.h" +char *inc_base_file = __BASE_FILE__; Index: gcc/testsuite/ChangeLog =================================================================== --- gcc/testsuite/ChangeLog (revision 182601) +++ gcc/testsuite/ChangeLog (working copy) @@ -1,3 +1,11 @@ +2011-12-21 Gary Funck <g...@intrepid.com> + + PR preprocessor/pr33919 + * gcc.dg/pr33919.c: New test. + * gcc.dg/pr33919-0.h: New test header file. + * gcc.dg/pr33919-1.h: Ditto. + * gcc.dg/pr33919-2.h: Ditto. + 2011-12-21 Paolo Carlini <paolo.carl...@oracle.com> PR c++/51305 Index: libcpp/macro.c =================================================================== --- libcpp/macro.c (revision 182601) +++ libcpp/macro.c (working copy) @@ -278,10 +278,9 @@ _cpp_builtin_macro_text (cpp_reader *pfi pfile->line_table->highest_line); else { - map = linemap_lookup (pfile->line_table, pfile->line_table->highest_line); - while (! MAIN_FILE_P (map)) - map = INCLUDED_FROM (pfile->line_table, map); - name = ORDINARY_MAP_FILE_NAME (map); + name = _cpp_get_file_name (pfile->main_file); + if (!name) + name = "<unknown>"; } len = strlen (name); buf = _cpp_unaligned_alloc (pfile, len * 2 + 3); Index: libcpp/files.c =================================================================== --- libcpp/files.c (revision 182601) +++ libcpp/files.c (working copy) @@ -1370,6 +1370,13 @@ _cpp_pop_file_buffer (cpp_reader *pfile, } } +/* Return the file name associated with FILE. */ +const char * +_cpp_get_file_name (_cpp_file *file) +{ + return file->name; +} + /* Inteface to file statistics record in _cpp_file structure. */ struct stat * _cpp_get_file_stat (_cpp_file *file) Index: libcpp/ChangeLog =================================================================== --- libcpp/ChangeLog (revision 182601) +++ libcpp/ChangeLog (working copy) @@ -1,3 +1,12 @@ +2011-12-21 Gary Funck <g...@intrepid.com> + + PR preprocessor/pr33919 + * files.c (_cpp_get_file_name): New. Implement file name + access function. + * internal.h (_cpp_get_file_name): New prototype. + * macro.c (_cpp_builtin_macro_text): Call _cpp_get_file_name() + in lieu of traversing INCLUDED_FROM chain. + 2011-12-20 Joseph Myers <jos...@codesourcery.com> * include/cpplib.h (CLK_GNUC1X): Change to CLK_GNUC11. Index: libcpp/internal.h =================================================================== --- libcpp/internal.h (revision 182601) +++ libcpp/internal.h (working copy) @@ -635,6 +635,7 @@ extern void _cpp_cleanup_files (cpp_read extern void _cpp_pop_file_buffer (cpp_reader *, struct _cpp_file *); extern bool _cpp_save_file_entries (cpp_reader *pfile, FILE *f); extern bool _cpp_read_file_entries (cpp_reader *, FILE *); +extern const char *_cpp_get_file_name (_cpp_file *); extern struct stat *_cpp_get_file_stat (_cpp_file *); /* In expr.c */