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]

PATCH RFA: Patch for PR preprocessor/13726


This is a patch for PR preprocessor/13726, a 3.4/4.0/4.1 regression in
which gcc -E -C -dI drops comments on #include lines.  (This PR may
have last worked in 2.95.3--it may have failed in all gcc 3.x
releases).

It's pretty straightforward.  I think the only thing worth mentioning
is that I used XDELETEVEC in do_include_common in libcpp/directives.c
because the buffers were allocated using XNEWVEC.  I can use
free((void*) buf) is that is considered proper style for libcpp.

Tested with bootstrap and testsuite run on i686-pc-linux-gnu.

OK for mainline?  OK for 4.0 and 3.4 branches, with appropriate
changes if any, if OK for mainline?

:ADDPATCH preprocessor:

Ian


libcpp/ChangeLog:

2005-09-22  Ian Lance Taylor  <ian@airs.com>

	PR preprocessor/13726
	* directives.c (check_eol_return_comments): New static function.
	(parse_include): Add buf parameter.  Change all callers.
	(do_include_common): If not discard comments, turn on
	save_comments.  Pass collected comments to include callback.
	* include/cpplib.h (struct cpp_callbacks): Add new parameter to
	include callback: cpp_token list.

gcc/ChangeLog:

2005-09-22  Ian Lance Taylor  <ian@airs.com>

	PR preprocessor/13726
	* c-ppoutput.c (cb_include): Add comments parameter, and print out
	any comments passed in.

gcc/testsuite/ChangeLog:

2005-09-22  Ian Lance Taylor  <ian@airs.com>

	PR preprocessor/13726
	* gcc.dg/cpp/cmdlne-dI-C.c: New test.
	* gcc.dg/cpp/cmdlne-dI-C.h: New file.


Index: libcpp/directives.c
===================================================================
RCS file: /cvs/gcc/gcc/libcpp/directives.c,v
retrieving revision 1.17
diff -p -u -r1.17 directives.c
--- libcpp/directives.c	29 Jun 2005 02:34:36 -0000	1.17
+++ libcpp/directives.c	23 Sep 2005 05:18:47 -0000
@@ -95,7 +95,7 @@ static void end_directive (cpp_reader *,
 static void directive_diagnostics (cpp_reader *, const directive *, int);
 static void run_directive (cpp_reader *, int, const char *, size_t);
 static char *glue_header_name (cpp_reader *);
-static const char *parse_include (cpp_reader *, int *);
+static const char *parse_include (cpp_reader *, int *, const cpp_token ***);
 static void push_conditional (cpp_reader *, int, int, const cpp_hashnode *);
 static unsigned int read_flag (cpp_reader *, unsigned int);
 static int strtoul_for_line (const uchar *, unsigned int, unsigned long *);
@@ -220,6 +220,46 @@ check_eol (cpp_reader *pfile)
 	       pfile->directive->name);
 }
 
+/* Ensure there are no stray tokens other than comments at the end of
+   a directive, and gather the comments.  */
+static const cpp_token **
+check_eol_return_comments (cpp_reader *pfile)
+{
+  size_t c;
+  size_t capacity = 8;
+  const cpp_token **buf;
+
+  buf = XNEWVEC (const cpp_token *, capacity);
+  c = 0;
+  if (! SEEN_EOL ())
+    {
+      while (1)
+	{
+	  const cpp_token *tok;
+
+	  tok = _cpp_lex_token (pfile);
+	  if (tok->type == CPP_EOF)
+	    break;
+	  if (tok->type != CPP_COMMENT)
+	    cpp_error (pfile, CPP_DL_PEDWARN,
+		       "extra tokens at end of #%s directive",
+		       pfile->directive->name);
+	  else
+	    {
+	      if (c + 1 >= capacity)
+		{
+		  capacity *= 2;
+		  buf = XRESIZEVEC (const cpp_token *, buf, capacity);
+		}
+	      buf[c] = tok;
+	      ++c;
+	    }
+	}
+    }
+  buf[c] = NULL;
+  return buf;
+}
+
 /* Called when entering a directive, _Pragma or command-line directive.  */
 static void
 start_directive (cpp_reader *pfile)
@@ -624,7 +664,8 @@ glue_header_name (cpp_reader *pfile)
    #pragma dependency.  The string is malloced and the caller should
    free it.  Returns NULL on error.  */
 static const char *
-parse_include (cpp_reader *pfile, int *pangle_brackets)
+parse_include (cpp_reader *pfile, int *pangle_brackets,
+	       const cpp_token ***buf)
 {
   char *fname;
   const cpp_token *header;
@@ -657,7 +698,15 @@ parse_include (cpp_reader *pfile, int *p
       return NULL;
     }
 
-  check_eol (pfile);
+  if (buf == NULL || CPP_OPTION (pfile, discard_comments))
+    check_eol (pfile);
+  else
+    {
+      /* If we are not discarding comments, then gather them while
+	 doing the eol check.  */
+      *buf = check_eol_return_comments (pfile);
+    }
+
   return fname;
 }
 
@@ -667,16 +716,27 @@ do_include_common (cpp_reader *pfile, en
 {
   const char *fname;
   int angle_brackets;
+  const cpp_token **buf = NULL;
+
+  /* Re-enable saving of comments if requested, so that the include
+     callback can dump comments which follow #include.  */
+  pfile->state.save_comments = ! CPP_OPTION (pfile, discard_comments);
 
-  fname = parse_include (pfile, &angle_brackets);
+  fname = parse_include (pfile, &angle_brackets, &buf);
   if (!fname)
-    return;
+    {
+      if (buf)
+	XDELETEVEC (buf);
+      return;
+    }
 
   if (!*fname)
   {
     cpp_error (pfile, CPP_DL_ERROR, "empty filename in #%s",
                pfile->directive->name);
-    free ((void *) fname);
+    XDELETEVEC (fname);
+    if (buf)
+      XDELETEVEC (buf);
     return;
   }
 
@@ -690,12 +750,15 @@ do_include_common (cpp_reader *pfile, en
 
       if (pfile->cb.include)
 	pfile->cb.include (pfile, pfile->directive_line,
-			   pfile->directive->name, fname, angle_brackets);
+			   pfile->directive->name, fname, angle_brackets,
+			   buf);
 
       _cpp_stack_include (pfile, fname, angle_brackets, type);
     }
 
-  free ((void *) fname);
+  XDELETEVEC (fname);
+  if (buf)
+    XDELETEVEC (buf);
 }
 
 static void
@@ -1322,7 +1385,7 @@ do_pragma_dependency (cpp_reader *pfile)
   const char *fname;
   int angle_brackets, ordering;
 
-  fname = parse_include (pfile, &angle_brackets);
+  fname = parse_include (pfile, &angle_brackets, NULL);
   if (!fname)
     return;
 
Index: libcpp/include/cpplib.h
===================================================================
RCS file: /cvs/gcc/gcc/libcpp/include/cpplib.h,v
retrieving revision 1.14
diff -p -u -r1.14 cpplib.h
--- libcpp/include/cpplib.h	20 Sep 2005 20:31:37 -0000	1.14
+++ libcpp/include/cpplib.h	23 Sep 2005 05:18:47 -0000
@@ -459,7 +459,7 @@ struct cpp_callbacks
 
   void (*dir_change) (cpp_reader *, const char *);
   void (*include) (cpp_reader *, unsigned int, const unsigned char *,
-		   const char *, int);
+		   const char *, int, const cpp_token **);
   void (*define) (cpp_reader *, unsigned int, cpp_hashnode *);
   void (*undef) (cpp_reader *, unsigned int, cpp_hashnode *);
   void (*ident) (cpp_reader *, unsigned int, const cpp_string *);
Index: gcc/c-ppoutput.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/c-ppoutput.c,v
retrieving revision 1.25
diff -p -u -r1.25 c-ppoutput.c
--- gcc/c-ppoutput.c	25 Jun 2005 01:59:23 -0000	1.25
+++ gcc/c-ppoutput.c	23 Sep 2005 05:18:47 -0000
@@ -54,7 +54,7 @@ static void cb_line_change (cpp_reader *
 static void cb_define (cpp_reader *, source_location, cpp_hashnode *);
 static void cb_undef (cpp_reader *, source_location, cpp_hashnode *);
 static void cb_include (cpp_reader *, source_location, const unsigned char *,
-			const char *, int);
+			const char *, int, const cpp_token **);
 static void cb_ident (cpp_reader *, source_location, const cpp_string *);
 static void cb_def_pragma (cpp_reader *, source_location);
 static void cb_read_pch (cpp_reader *pfile, const char *name,
@@ -336,13 +336,27 @@ cb_undef (cpp_reader *pfile ATTRIBUTE_UN
 
 static void
 cb_include (cpp_reader *pfile ATTRIBUTE_UNUSED, source_location line,
-	    const unsigned char *dir, const char *header, int angle_brackets)
+	    const unsigned char *dir, const char *header, int angle_brackets,
+	    const cpp_token **comments)
 {
   maybe_print_line (line);
   if (angle_brackets)
-    fprintf (print.outf, "#%s <%s>\n", dir, header);
+    fprintf (print.outf, "#%s <%s>", dir, header);
   else
-    fprintf (print.outf, "#%s \"%s\"\n", dir, header);
+    fprintf (print.outf, "#%s \"%s\"", dir, header);
+
+  if (comments != NULL)
+    {
+      while (*comments != NULL)
+	{
+	  if ((*comments)->flags & PREV_WHITE)
+	    putc (' ', print.outf);
+	  cpp_output_token (*comments, print.outf);
+	  ++comments;
+	}
+    }
+
+  putc ('\n', print.outf);
   print.src_line++;
 }
 
Index: gcc/testsuite/gcc.dg/cpp/cmdlne-dI-C.c
===================================================================
RCS file: gcc/testsuite/gcc.dg/cpp/cmdlne-dI-C.c
diff -N gcc/testsuite/gcc.dg/cpp/cmdlne-dI-C.c
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ gcc/testsuite/gcc.dg/cpp/cmdlne-dI-C.c	23 Sep 2005 05:23:07 -0000
@@ -0,0 +1,11 @@
+/* Copyright (C) 2005 Free Software Foundation, Inc.  */
+/* PR 13726 */
+
+/* { dg-do preprocess } */
+/* { dg-options "-dI -C" } */
+
+#include "cmdlne-dI-C.h" /* #include comment */
+/* comment 2 */
+
+/* { dg-final { scan-file cmdlne-dI-C.i "#include c+omment" } } */
+/* { dg-final { scan-file cmdlne-dI-C.i "header file c+omment" } } */
Index: gcc/testsuite/gcc.dg/cpp/cmdlne-dI-C.h
===================================================================
RCS file: gcc/testsuite/gcc.dg/cpp/cmdlne-dI-C.h
diff -N gcc/testsuite/gcc.dg/cpp/cmdlne-dI-C.h
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ gcc/testsuite/gcc.dg/cpp/cmdlne-dI-C.h	23 Sep 2005 05:23:07 -0000
@@ -0,0 +1 @@
+/* header file comment */


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