diff mbox series

[preprocessor/91639] #includes at EOF

Message ID 8c76f6cb-f3cb-9805-bc97-2d5fdef308a2@acm.org
State New
Headers show
Series [preprocessor/91639] #includes at EOF | expand

Commit Message

Nathan Sidwell Sept. 5, 2019, 11:21 a.m. UTC
This fixes 91639.
#include processing needs to rewind by one line before doing the 
inclusion, so that that happens on the #include line itself.  Except 
that the lexer doesn't increment the lineno on the last \n of a file -- 
because there's no point.

So we had code in the include path to figure out that special case and 
not rewind.  I broke that.

Rather than repair it there, I decided it simpler to make the lexer 
always advance when lexing a #include line.  I did consider not even 
making that conditional, but the unstacking code looked a bit hairy to 
correctly rewind in those cases (or we simply waste linemap space).

This ends up making the include rewinding simpler -- there are still 
cases it shouldn't.

Applying to trunk.

Comments

Martin Jambor Oct. 4, 2019, 2:31 p.m. UTC | #1
Hi,

On Thu, Sep 05 2019, Nathan Sidwell wrote:
> This fixes 91639.
> #include processing needs to rewind by one line before doing the 
> inclusion, so that that happens on the #include line itself.  Except 
> that the lexer doesn't increment the lineno on the last \n of a file -- 
> because there's no point.
>
> So we had code in the include path to figure out that special case and 
> not rewind.  I broke that.
>
> Rather than repair it there, I decided it simpler to make the lexer 
> always advance when lexing a #include line.  I did consider not even 
> making that conditional, but the unstacking code looked a bit hairy to 
> correctly rewind in those cases (or we simply waste linemap space).
>
> This ends up making the include rewinding simpler -- there are still 
> cases it shouldn't.
>
> Applying to trunk.
>
> -- 
> Nathan Sidwell
> 2019-09-05  Nathan Sidwell  <nathan@acm.org>
>
> 	libcpp/
> 	PR preprocessor/91639
> 	* directives.c (do_include_common): Tell lexer we're a #include.
> 	* files.c (_cpp_stack_file): Lexer will have always incremented.
> 	* internal.h (struct cpp_context): Extend in_directive's
> 	semantics.
> 	* lex.c (_cpp_lex_direct): Increment line for final \n when lexing
> 	for an ISO #include.
> 	* line-map.c (linemap_line_start): Remember if we overflowed.
>
> 	gcc/testsuite/
> 	PR preprocessor/91639
> 	* c-c++-common/cpp/pr91639.c: New.
> 	* c-c++-common/cpp/pr91639-one.h: New.
> 	* c-c++-common/cpp/pr91639-two.h: New.

unfortunately, this has caused PR 91991.

Martin

>
> Index: libcpp/directives.c
> ===================================================================
> --- libcpp/directives.c	(revision 275373)
> +++ libcpp/directives.c	(working copy)
> @@ -819,4 +819,8 @@ do_include_common (cpp_reader *pfile, en
>    pfile->state.save_comments = ! CPP_OPTION (pfile, discard_comments);
>  
> +  /* Tell the lexer this is an include directive -- we want it to
> +     increment the line number even if this is the last line of a file.  */
> +  pfile->state.in_directive = 2;
> +
>    fname = parse_include (pfile, &angle_brackets, &buf, &location);
>    if (!fname)
> Index: libcpp/files.c
> ===================================================================
> --- libcpp/files.c	(revision 275373)
> +++ libcpp/files.c	(working copy)
> @@ -939,23 +939,14 @@ _cpp_stack_file (cpp_reader *pfile, _cpp
>    pfile->mi_cmacro = 0;
>  
> -  /* Compensate for the increment in linemap_add that occurs when in
> -     do_file_change.   In the case of a normal #include, we're
> -     currently at the start of the line *following* the #include.  A
> -     separate location_t 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.  In the
> -     case that the #include is the last line in the file,
> -     highest_location still points to the current line, not the start
> -     of the next line, so we do not decrement in this case.  See
> -     plugin/location-overflow-test-pr83173.h for an example.  */
> -  bool decremented = false;
> -  if (file->pchname == NULL && file->err_no == 0 && type < IT_DIRECTIVE_HWM)
> -    {
> -      decremented = (pfile->line_table->highest_line
> -		     == pfile->line_table->highest_location);
> -      if (decremented)
> -	pfile->line_table->highest_location--;
> -    }
> +  /* In the case of a normal #include, we're now at the start of the
> +     line *following* the #include.  A separate location_t for this
> +     location makes no sense, until we do the LC_LEAVE.
> +
> +     This does not apply if we found a PCH file, we're not a regular
> +     include, or we ran out of locations.  */
> +  if (file->pchname == NULL
> +      && type < IT_DIRECTIVE_HWM
> +      && pfile->line_table->highest_location != LINE_MAP_MAX_LOCATION - 1)
> +    pfile->line_table->highest_location--;
>  
>    /* Add line map and do callbacks.  */
> Index: libcpp/internal.h
> ===================================================================
> --- libcpp/internal.h	(revision 275373)
> +++ libcpp/internal.h	(working copy)
> @@ -235,5 +235,6 @@ struct cpp_context
>  struct lexer_state
>  {
> -  /* Nonzero if first token on line is CPP_HASH.  */
> +  /* 1 if we're handling a directive.  2 if it's an include-like
> +     directive.  */
>    unsigned char in_directive;
>  
> Index: libcpp/lex.c
> ===================================================================
> --- libcpp/lex.c	(revision 275373)
> +++ libcpp/lex.c	(working copy)
> @@ -2772,5 +2772,11 @@ _cpp_lex_direct (cpp_reader *pfile)
>  
>      case '\n':
> -      if (buffer->cur < buffer->rlimit)
> +      /* Increment the line, unless this is the last line ...  */
> +      if (buffer->cur < buffer->rlimit
> +	  /* ... or this is a #include, (where _cpp_stack_file needs to
> +	     unwind by one line) ...  */
> +	  || (pfile->state.in_directive > 1
> +	      /* ... except traditional-cpp increments this elsewhere.  */
> +	      && !CPP_OPTION (pfile, traditional)))
>  	CPP_INCREMENT_LINE (pfile, 0);
>        buffer->need_line = true;
> Index: libcpp/line-map.c
> ===================================================================
> --- libcpp/line-map.c	(revision 275373)
> +++ libcpp/line-map.c	(working copy)
> @@ -765,5 +765,9 @@ linemap_line_start (line_maps *set, line
>       macro tokens.  */
>    if (r >= LINE_MAP_MAX_LOCATION)
> -    return 0;
> +    {
> +      /* Remember we overflowed.  */
> +      set->highest_line = set->highest_location = LINE_MAP_MAX_LOCATION - 1;
> +      return 0;
> +    }
>  
>    set->highest_line = r;
> Index: gcc/testsuite/c-c++-common/cpp/pr91639-one.h
> ===================================================================
> --- gcc/testsuite/c-c++-common/cpp/pr91639-one.h	(revision 0)
> +++ gcc/testsuite/c-c++-common/cpp/pr91639-one.h	(working copy)
> @@ -0,0 +1,2 @@
> +one
> +#include "pr91639-two.h"
> Index: gcc/testsuite/c-c++-common/cpp/pr91639-two.h
> ===================================================================
> --- gcc/testsuite/c-c++-common/cpp/pr91639-two.h	(revision 0)
> +++ gcc/testsuite/c-c++-common/cpp/pr91639-two.h	(working copy)
> @@ -0,0 +1 @@
> +two
> Index: gcc/testsuite/c-c++-common/cpp/pr91639.c
> ===================================================================
> --- gcc/testsuite/c-c++-common/cpp/pr91639.c	(revision 0)
> +++ gcc/testsuite/c-c++-common/cpp/pr91639.c	(working copy)
> @@ -0,0 +1,9 @@
> +/* PR91639 Line markers for an end-of-file #include   */
> +/* { dg-do preprocess } */
> +/* { dg-additional-options -Wno-pedantic } */
> +/* { dg-additional-files {pr91639-one.h pr91639-two.h} } */
> +
> +#include "pr91639-one.h"
> +main
> +
> +/* { dg-final { scan-file pr91639.i "# 1 \"\[^\n\"\]*pr91639-one.h\" 1\none\n# 1 \"\[^\n\"\]*pr91639-two.h\" 1\ntwo\n# 3 \"\[^\n\"\]*pr91639-one.h\" 2\n# 7 \"\[^\n\"\]*pr91639.c\" 2\nmain\n" } } */
diff mbox series

Patch

2019-09-05  Nathan Sidwell  <nathan@acm.org>

	libcpp/
	PR preprocessor/91639
	* directives.c (do_include_common): Tell lexer we're a #include.
	* files.c (_cpp_stack_file): Lexer will have always incremented.
	* internal.h (struct cpp_context): Extend in_directive's
	semantics.
	* lex.c (_cpp_lex_direct): Increment line for final \n when lexing
	for an ISO #include.
	* line-map.c (linemap_line_start): Remember if we overflowed.

	gcc/testsuite/
	PR preprocessor/91639
	* c-c++-common/cpp/pr91639.c: New.
	* c-c++-common/cpp/pr91639-one.h: New.
	* c-c++-common/cpp/pr91639-two.h: New.

Index: libcpp/directives.c
===================================================================
--- libcpp/directives.c	(revision 275373)
+++ libcpp/directives.c	(working copy)
@@ -819,4 +819,8 @@  do_include_common (cpp_reader *pfile, en
   pfile->state.save_comments = ! CPP_OPTION (pfile, discard_comments);
 
+  /* Tell the lexer this is an include directive -- we want it to
+     increment the line number even if this is the last line of a file.  */
+  pfile->state.in_directive = 2;
+
   fname = parse_include (pfile, &angle_brackets, &buf, &location);
   if (!fname)
Index: libcpp/files.c
===================================================================
--- libcpp/files.c	(revision 275373)
+++ libcpp/files.c	(working copy)
@@ -939,23 +939,14 @@  _cpp_stack_file (cpp_reader *pfile, _cpp
   pfile->mi_cmacro = 0;
 
-  /* Compensate for the increment in linemap_add that occurs when in
-     do_file_change.   In the case of a normal #include, we're
-     currently at the start of the line *following* the #include.  A
-     separate location_t 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.  In the
-     case that the #include is the last line in the file,
-     highest_location still points to the current line, not the start
-     of the next line, so we do not decrement in this case.  See
-     plugin/location-overflow-test-pr83173.h for an example.  */
-  bool decremented = false;
-  if (file->pchname == NULL && file->err_no == 0 && type < IT_DIRECTIVE_HWM)
-    {
-      decremented = (pfile->line_table->highest_line
-		     == pfile->line_table->highest_location);
-      if (decremented)
-	pfile->line_table->highest_location--;
-    }
+  /* In the case of a normal #include, we're now at the start of the
+     line *following* the #include.  A separate location_t for this
+     location makes no sense, until we do the LC_LEAVE.
+
+     This does not apply if we found a PCH file, we're not a regular
+     include, or we ran out of locations.  */
+  if (file->pchname == NULL
+      && type < IT_DIRECTIVE_HWM
+      && pfile->line_table->highest_location != LINE_MAP_MAX_LOCATION - 1)
+    pfile->line_table->highest_location--;
 
   /* Add line map and do callbacks.  */
Index: libcpp/internal.h
===================================================================
--- libcpp/internal.h	(revision 275373)
+++ libcpp/internal.h	(working copy)
@@ -235,5 +235,6 @@  struct cpp_context
 struct lexer_state
 {
-  /* Nonzero if first token on line is CPP_HASH.  */
+  /* 1 if we're handling a directive.  2 if it's an include-like
+     directive.  */
   unsigned char in_directive;
 
Index: libcpp/lex.c
===================================================================
--- libcpp/lex.c	(revision 275373)
+++ libcpp/lex.c	(working copy)
@@ -2772,5 +2772,11 @@  _cpp_lex_direct (cpp_reader *pfile)
 
     case '\n':
-      if (buffer->cur < buffer->rlimit)
+      /* Increment the line, unless this is the last line ...  */
+      if (buffer->cur < buffer->rlimit
+	  /* ... or this is a #include, (where _cpp_stack_file needs to
+	     unwind by one line) ...  */
+	  || (pfile->state.in_directive > 1
+	      /* ... except traditional-cpp increments this elsewhere.  */
+	      && !CPP_OPTION (pfile, traditional)))
 	CPP_INCREMENT_LINE (pfile, 0);
       buffer->need_line = true;
Index: libcpp/line-map.c
===================================================================
--- libcpp/line-map.c	(revision 275373)
+++ libcpp/line-map.c	(working copy)
@@ -765,5 +765,9 @@  linemap_line_start (line_maps *set, line
      macro tokens.  */
   if (r >= LINE_MAP_MAX_LOCATION)
-    return 0;
+    {
+      /* Remember we overflowed.  */
+      set->highest_line = set->highest_location = LINE_MAP_MAX_LOCATION - 1;
+      return 0;
+    }
 
   set->highest_line = r;
Index: gcc/testsuite/c-c++-common/cpp/pr91639-one.h
===================================================================
--- gcc/testsuite/c-c++-common/cpp/pr91639-one.h	(revision 0)
+++ gcc/testsuite/c-c++-common/cpp/pr91639-one.h	(working copy)
@@ -0,0 +1,2 @@ 
+one
+#include "pr91639-two.h"
Index: gcc/testsuite/c-c++-common/cpp/pr91639-two.h
===================================================================
--- gcc/testsuite/c-c++-common/cpp/pr91639-two.h	(revision 0)
+++ gcc/testsuite/c-c++-common/cpp/pr91639-two.h	(working copy)
@@ -0,0 +1 @@ 
+two
Index: gcc/testsuite/c-c++-common/cpp/pr91639.c
===================================================================
--- gcc/testsuite/c-c++-common/cpp/pr91639.c	(revision 0)
+++ gcc/testsuite/c-c++-common/cpp/pr91639.c	(working copy)
@@ -0,0 +1,9 @@ 
+/* PR91639 Line markers for an end-of-file #include   */
+/* { dg-do preprocess } */
+/* { dg-additional-options -Wno-pedantic } */
+/* { dg-additional-files {pr91639-one.h pr91639-two.h} } */
+
+#include "pr91639-one.h"
+main
+
+/* { dg-final { scan-file pr91639.i "# 1 \"\[^\n\"\]*pr91639-one.h\" 1\none\n# 1 \"\[^\n\"\]*pr91639-two.h\" 1\ntwo\n# 3 \"\[^\n\"\]*pr91639-one.h\" 2\n# 7 \"\[^\n\"\]*pr91639.c\" 2\nmain\n" } } */