This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

Fix #line with empty file name (PR 39646)


This patch fixes PR 39646, a preprocessor bug where special handling
of "" as meaning "<stdin>" in linemap_add caused #line with an empty
string to set __FILE__ to "<stdin>".

The fix is reasonably local, adding a case LC_RENAME_VERBATIM to avoid
the special "" handling.  In principle I think linemap_add should take
both a filename that would be NULL in the special cases of <stdin>,
<built-in> etc., and an enum that says which special case is being
used in those cases.  That would also allow a proper fix to PR 19753:
<built-in> should be translated in diagnostics but not in .i output,
so there shouldn't just be a single file name field used in all cases,
but a file name field plus an enum that together can be processed to
find the correct name to report in a particular case.  This would
however require figuring out exactly which calls to linemap_add (for
all languages) might presently use the special "" handling and
arranging for them to pass the new argument indicating that stdin is
in use instead.

Bootstrapped with no regressions on x86_64-unknown-linux-gnu.  Applied
to mainline.

libcpp:
2009-04-18  Joseph Myers  <joseph@codesourcery.com>

	PR preprocessor/39646
	* include/line-map.h (enum lc_reason): Add LC_RENAME_VERBATIM.
	* line-map.c (linemap_add): Handle LC_RENAME_VERBATIM.
	* directives.c (do_line, do_linemarker): Use LC_RENAME_VERBATIM in
	place of LC_RENAME.

gcc/testsuite:
2009-04-18  Joseph Myers  <joseph@codesourcery.com>

	PR preprocessor/39646
	* gcc.dg/cpp/line8.c: New test.

Index: gcc/testsuite/gcc.dg/cpp/line8.c
===================================================================
--- gcc/testsuite/gcc.dg/cpp/line8.c	(revision 0)
+++ gcc/testsuite/gcc.dg/cpp/line8.c	(revision 0)
@@ -0,0 +1,10 @@
+/* Test that "" is not specially interpreted as "<stdin>" in a #line
+   directive.  PR 39646.  */
+
+/* { dg-do compile } */
+/* { dg-options "-pedantic-errors" } */
+
+extern int x;
+
+#line 24 ""
+extern char z[sizeof __FILE__ == 1];
Index: libcpp/directives.c
===================================================================
--- libcpp/directives.c	(revision 146316)
+++ libcpp/directives.c	(working copy)
@@ -924,7 +924,7 @@ do_line (cpp_reader *pfile)
     }
 
   skip_rest_of_line (pfile);
-  _cpp_do_file_change (pfile, LC_RENAME, new_file, new_lineno,
+  _cpp_do_file_change (pfile, LC_RENAME_VERBATIM, new_file, new_lineno,
 		       map_sysp);
 }
 
@@ -940,7 +940,7 @@ do_linemarker (cpp_reader *pfile)
   const char *new_file = map->to_file;
   linenum_type new_lineno;
   unsigned int new_sysp = map->sysp;
-  enum lc_reason reason = LC_RENAME;
+  enum lc_reason reason = LC_RENAME_VERBATIM;
   int flag;
   bool wrapped;
 
Index: libcpp/include/line-map.h
===================================================================
--- libcpp/include/line-map.h	(revision 146291)
+++ libcpp/include/line-map.h	(working copy)
@@ -31,8 +31,9 @@ along with this program; see the file CO
    when including a new file, e.g. a #include directive in C.
    LC_LEAVE is when reaching a file's end.  LC_RENAME is when a file
    name or line number changes for neither of the above reasons
-   (e.g. a #line directive in C).  */
-enum lc_reason {LC_ENTER = 0, LC_LEAVE, LC_RENAME};
+   (e.g. a #line directive in C); LC_RENAME_VERBATIM is like LC_RENAME
+   but a filename of "" is not specially interpreted as standard input.  */
+enum lc_reason {LC_ENTER = 0, LC_LEAVE, LC_RENAME, LC_RENAME_VERBATIM};
 
 /* The type of line numbers.  */
 typedef unsigned int linenum_type;
Index: libcpp/line-map.c
===================================================================
--- libcpp/line-map.c	(revision 146291)
+++ libcpp/line-map.c	(working copy)
@@ -109,9 +109,12 @@ linemap_add (struct line_maps *set, enum
 
   map = &set->maps[set->used];
 
-  if (to_file && *to_file == '\0')
+  if (to_file && *to_file == '\0' && reason != LC_RENAME_VERBATIM)
     to_file = "<stdin>";
 
+  if (reason == LC_RENAME_VERBATIM)
+    reason = LC_RENAME;
+
   /* If we don't keep our line maps consistent, we can easily
      segfault.  Don't rely on the client to do it for us.  */
   if (set->depth == 0)

-- 
Joseph S. Myers
joseph@codesourcery.com


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]