]> git.ipfire.org Git - thirdparty/gcc.git/commitdiff
libcpp: location comparison within macro [PR100796]
authorJason Merrill <jason@redhat.com>
Mon, 14 Jun 2021 21:37:43 +0000 (17:37 -0400)
committerJason Merrill <jason@redhat.com>
Wed, 16 Jun 2021 15:41:08 +0000 (11:41 -0400)
The patch for 96391 changed linemap_compare_locations to give up on
comparing locations from macro expansions if we don't have column
information.  But in this testcase, the BOILERPLATE macro is multiple lines
long, so we do want to compare locations within the macro.  So this patch
moves the LINE_MAP_MAX_LOCATION_WITH_COLS check inside the block, to use it
for failing gracefully.

PR c++/100796
PR preprocessor/96391

libcpp/ChangeLog:

* line-map.c (linemap_compare_locations): Only use comparison with
LINE_MAP_MAX_LOCATION_WITH_COLS to avoid abort.

gcc/testsuite/ChangeLog:

* g++.dg/plugin/location-overflow-test-pr100796.c: New test.
* g++.dg/plugin/plugin.exp: Run it.

gcc/testsuite/g++.dg/plugin/location-overflow-test-pr100796.c [new file with mode: 0644]
gcc/testsuite/g++.dg/plugin/plugin.exp
libcpp/line-map.c

diff --git a/gcc/testsuite/g++.dg/plugin/location-overflow-test-pr100796.c b/gcc/testsuite/g++.dg/plugin/location-overflow-test-pr100796.c
new file mode 100644 (file)
index 0000000..7fa964c
--- /dev/null
@@ -0,0 +1,25 @@
+// PR c++/100796
+// { dg-additional-options "-Wsuggest-override -fplugin-arg-location_overflow_plugin-value=0x60000001" }
+// Passing LINE_MAP_MAX_LOCATION_WITH_COLS meant we stopped distinguishing between lines in a macro.
+
+#define DO_PRAGMA(text)           _Pragma(#text)
+#define WARNING_PUSH              DO_PRAGMA(GCC diagnostic push)
+#define WARNING_POP               DO_PRAGMA(GCC diagnostic pop)
+#define WARNING_DISABLE(text)     DO_PRAGMA(GCC diagnostic ignored text)
+#define NO_OVERRIDE_WARNING       WARNING_DISABLE("-Wsuggest-override")
+
+#define BOILERPLATE                            \
+  WARNING_PUSH                                 \
+  NO_OVERRIDE_WARNING                          \
+  void f();                                    \
+  WARNING_POP
+
+struct B
+{
+  virtual void f();
+};
+
+struct D: B
+{
+  BOILERPLATE
+};
index 5cd4b4bff902e33f104737abe1f06b479bb12ba7..74e12df207c2afd8dfc2d8b06853df800c38f7aa 100644 (file)
@@ -73,7 +73,8 @@ set plugin_test_list [list \
          ../../gcc.dg/plugin/diagnostic-test-string-literals-3.c \
          ../../gcc.dg/plugin/diagnostic-test-string-literals-4.c } \
     { ../../gcc.dg/plugin/location_overflow_plugin.c \
-         location-overflow-test-pr96391.c } \
+         location-overflow-test-pr96391.c \
+          location-overflow-test-pr100796.c } \
     { show_template_tree_color_plugin.c \
          show-template-tree-color.C \
          show-template-tree-color-labels.C \
index a03d6760a8e62a787bece6059fe9d5d22a59d144..1a6902acdb7ce75f40c37409c22c9c4125bb1e27 100644 (file)
@@ -1421,23 +1421,25 @@ linemap_compare_locations (line_maps *set,
 
   if (l0 == l1
       && pre_virtual_p
-      && post_virtual_p
-      && l0 <= LINE_MAP_MAX_LOCATION_WITH_COLS)
+      && post_virtual_p)
     {
       /* So pre and post represent two tokens that are present in a
         same macro expansion.  Let's see if the token for pre was
         before the token for post in that expansion.  */
-      unsigned i0, i1;
       const struct line_map *map =
        first_map_in_common (set, pre, post, &l0, &l1);
 
       if (map == NULL)
-       /* This should not be possible.  */
-       abort ();
-
-      i0 = l0 - MAP_START_LOCATION (map);
-      i1 = l1 - MAP_START_LOCATION (map);
-      return i1 - i0;
+       /* This should not be possible while we have column information, but if
+          we don't, the tokens could be from separate macro expansions on the
+          same line.  */
+       gcc_assert (l0 > LINE_MAP_MAX_LOCATION_WITH_COLS);
+      else
+       {
+         unsigned i0 = l0 - MAP_START_LOCATION (map);
+         unsigned i1 = l1 - MAP_START_LOCATION (map);
+         return i1 - i0;
+       }
     }
 
   if (IS_ADHOC_LOC (l0))