diff mbox

[committed] substring locations and # line directives (PR preprocessor/78569)

Message ID 1480470549-5942-1-git-send-email-dmalcolm@redhat.com
State New
Headers show

Commit Message

David Malcolm Nov. 30, 2016, 1:49 a.m. UTC
The ICE in PR preprocessor/78569 appears to be due to an attempt to
generate substring locations in a .i file where the underlying .c file
has changed since the .i file was generated.

This can't work, so it seems safest for the on-demand substring
locations to be unavailable for such files, falling back to
"whole string" locations for such cases.

Successfully bootstrapped&regrtested on x86_64-pc-linux-gnu;
adds 6 PASS results to gcc.sum.

Committed to trunk as r242990.

gcc/ChangeLog:
	PR preprocessor/78569
	* input.c (get_substring_ranges_for_loc): Fail gracefully if
	line directives were present.

gcc/testsuite/ChangeLog:
	PR preprocessor/78569
	* gcc.dg/format/pr78569.c: New test case.
---
 gcc/input.c                           | 10 ++++++++++
 gcc/testsuite/gcc.dg/format/pr78569.c | 24 ++++++++++++++++++++++++
 2 files changed, 34 insertions(+)
 create mode 100644 gcc/testsuite/gcc.dg/format/pr78569.c
diff mbox

Patch

diff --git a/gcc/input.c b/gcc/input.c
index 611e18b..1c7228a 100644
--- a/gcc/input.c
+++ b/gcc/input.c
@@ -1331,6 +1331,16 @@  get_substring_ranges_for_loc (cpp_reader *pfile,
   if (cpp_get_options (pfile)->track_macro_expansion != 2)
     return "track_macro_expansion != 2";
 
+  /* If #line or # 44 "file"-style directives are present, then there's
+     no guarantee that the line numbers we have can be used to locate
+     the strings.  For example, we might have a .i file with # directives
+     pointing back to lines within a .c file, but the .c file might
+     have been edited since the .i file was created.
+     In such a case, the safest course is to disable on-demand substring
+     locations.  */
+  if (line_table->seen_line_directive)
+    return "seen line directive";
+
   /* If string concatenation has occurred at STRLOC, get the locations
      of all of the literal tokens making up the compound string.
      Otherwise, just use STRLOC.  */
diff --git a/gcc/testsuite/gcc.dg/format/pr78569.c b/gcc/testsuite/gcc.dg/format/pr78569.c
new file mode 100644
index 0000000..e827087
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/format/pr78569.c
@@ -0,0 +1,24 @@ 
+/* { dg-do compile } */
+/* { dg-options "-Wformat-length" } */
+
+/* A run of blank lines, so that we would fail the assertion in input.c:1388:
+   gcc_assert (line_width >= (start.column - 1 + literal_length));  */
+
+
+
+
+
+void test (void)
+{
+  char tmp[128];
+  /* Point to the run of blank lines, so that the components of the overlong
+     string appear to be present within the run of blank lines.  */
+# 6 "../../../../src/gcc/testsuite/gcc.dg/format/pr78569.c"
+  __builtin_snprintf (tmp, sizeof(tmp),
+		      "The Base Band sends this value as a response to a "
+		      "request for IMSI detach sent over the control "
+		      "channel uplink (see section 7.6.1).");
+
+  /* { dg-warning "output truncated" "" { target *-*-* } 7 } */
+  /* { dg-message "format output" "" { target *-*-* } 6 } */
+}