Fix ICE in substring locations from macros in header files (PR preprocessor/88257)
authorDavid Malcolm <dmalcolm@redhat.com>
Fri, 30 Nov 2018 15:57:37 +0000 (15:57 +0000)
committerDavid Malcolm <dmalcolm@gcc.gnu.org>
Fri, 30 Nov 2018 15:57:37 +0000 (15:57 +0000)
PR preprocessor/88257 reports an ICE on gcc.dg/format/pr78304.c
when compiled using g++:

void test (const char *msg)
{
  printf ("size: %" PRIu32 "\n", msg);
}

due to mismatching files (and line maps) between
linemap_resolve_location and expand_location_to_spelling_point
when PRIu32 is defined in a system header.

The root cause is that expand_location_to_spelling_point stops
unwinding locations when it reaches a system header, whereas
linemap_resolve_location can resolve into a system header,
which can lead to locations within get_substring_ranges_for_loc
getting out of sync, and using the wrong line map.

This patch fixes the issue by checking that the files are the
same.

gcc/ChangeLog:
PR preprocessor/88257
* input.c (get_substring_ranges_for_loc): Fix indentation.
Bulletproof against getting a different files back from
linemap_resolve_location and expand_location_to_spelling_point.

gcc/testsuite/ChangeLog:
PR preprocessor/88257
* c-c++-common/Wformat-pr88257.c: New test.
* c-c++-common/Wformat-pr88257.h: New test header.
* c-c++-common/empty.h: New test header.

From-SVN: r266671

gcc/ChangeLog
gcc/input.c
gcc/testsuite/ChangeLog
gcc/testsuite/c-c++-common/Wformat-pr88257.c [new file with mode: 0644]
gcc/testsuite/c-c++-common/Wformat-pr88257.h [new file with mode: 0644]
gcc/testsuite/c-c++-common/empty.h [new file with mode: 0644]

index 7597ded..7cda0b4 100644 (file)
@@ -1,3 +1,10 @@
+2018-11-30  David Malcolm  <dmalcolm@redhat.com>
+
+       PR preprocessor/88257
+       * input.c (get_substring_ranges_for_loc): Fix indentation.
+       Bulletproof against getting a different files back from
+       linemap_resolve_location and expand_location_to_spelling_point.
+
 2018-11-30  Alexander Monakov  <amonakov@ispras.ru>
 
        PR gcov-profile/88279
index 6ce9782..be1da2c 100644 (file)
@@ -1471,7 +1471,12 @@ get_substring_ranges_for_loc (cpp_reader *pfile,
         for start vs finish due to line-length jumps.  */
       if (start_ord_map != final_ord_map
          && start_ord_map->to_file != final_ord_map->to_file)
-         return "start and finish are spelled in different ordinary maps";
+       return "start and finish are spelled in different ordinary maps";
+      /* The file from linemap_resolve_location ought to match that from
+        expand_location_to_spelling_point.  */
+      if (start_ord_map->to_file != start.file)
+       return "mismatching file after resolving linemap";
+
       location_t start_loc
        = linemap_position_for_line_and_column (line_table, final_ord_map,
                                                start.line, start.column);
index 4963b1d..fcc7c8c 100644 (file)
@@ -1,3 +1,10 @@
+2018-11-30  David Malcolm  <dmalcolm@redhat.com>
+
+       PR preprocessor/88257
+       * c-c++-common/Wformat-pr88257.c: New test.
+       * c-c++-common/Wformat-pr88257.h: New test header.
+       * c-c++-common/empty.h: New test header.
+
 2018-11-30  Sam Tebbs  <sam.tebbs@arm.com>
 
        * gcc.target/arm/neon-dotprod-restriction.c: New file.
@@ -10,7 +17,6 @@
        PR sanitizer/81715
        * c-c++-common/asan/asan-stack-small.c: New test.
 
->>>>>>> .r266664
 2018-11-30  Richard Biener  <rguenther@suse.de>
 
        * gcc.dg/gimplefe-34.c: New testcase.
diff --git a/gcc/testsuite/c-c++-common/Wformat-pr88257.c b/gcc/testsuite/c-c++-common/Wformat-pr88257.c
new file mode 100644 (file)
index 0000000..59e4db5
--- /dev/null
@@ -0,0 +1,23 @@
+/* { dg-options "-Wformat -fdiagnostics-show-caret" } */
+
+#include "Wformat-pr88257.h"
+
+void test (const char *msg)
+{
+  __builtin_printf ("size: %" PRIu32 "\n", msg); /* { dg-warning "expects argument of type" } */
+  /* { dg-begin-multiline-output "" }
+   __builtin_printf ("size: %" PRIu32 "\n", msg);
+                     ^~~~~~~~~              ~~~
+                                            |
+                                            const char *
+     { dg-end-multiline-output "" { target c } } */
+  /* { dg-begin-multiline-output "" }
+ # define PRIu32  "u"
+     { dg-end-multiline-output "" { target c } } */
+  /* { dg-begin-multiline-output "" }
+   __builtin_printf ("size: %" PRIu32 "\n", msg);
+                     ^~~~~~~~~~~~~~~~~~~~~  ~~~
+                                            |
+                                            const char*
+     { dg-end-multiline-output "" { target c++ } } */
+}
diff --git a/gcc/testsuite/c-c++-common/Wformat-pr88257.h b/gcc/testsuite/c-c++-common/Wformat-pr88257.h
new file mode 100644 (file)
index 0000000..c778e93
--- /dev/null
@@ -0,0 +1,26 @@
+#pragma GCC system_header
+
+/* Whitespace is significant here, due to line numbering.
+   See the comment below.
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+  End of significant whitespace */
+
+#include "empty.h"
+/* The preceding include ensures a line map starts here, with a line
+   number greater than that of the usage site, to try to trigger
+   an assertion failure.  */
+
+# define PRIu32  "u"
diff --git a/gcc/testsuite/c-c++-common/empty.h b/gcc/testsuite/c-c++-common/empty.h
new file mode 100644 (file)
index 0000000..e69de29