[PATCH] PR33919/preprocessor fix __BASE_FILE__ when included from the command line

Gary Funck gary@intrepid.com
Thu Dec 22 05:23:00 GMT 2011


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
-------------- next part --------------
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  <gary@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.carlini@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  <gary@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  <joseph@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 */


More information about the Gcc-patches mailing list