]> git.ipfire.org Git - thirdparty/gcc.git/commitdiff
PR preprocessor/69177 and PR c++/68819: libcpp fallbacks and -Wmisleading-indentation
authordmalcolm <dmalcolm@138bc75d-0d04-0410-961f-82ee72b054a4>
Thu, 14 Jan 2016 19:10:17 +0000 (19:10 +0000)
committerdmalcolm <dmalcolm@138bc75d-0d04-0410-961f-82ee72b054a4>
Thu, 14 Jan 2016 19:10:17 +0000 (19:10 +0000)
gcc/c-family/ChangeLog:
PR c++/68819
* c-indentation.c (get_visual_column): Add location_t param.
Handle the column number being zero by effectively disabling the
warning, with an "inform".
(should_warn_for_misleading_indentation): Add location_t argument
for all uses of get_visual_column.

gcc/testsuite/ChangeLog:
PR c++/68819
PR preprocessor/69177
* gcc.dg/plugin/location-overflow-test-1.c: New test case.
* gcc.dg/plugin/location-overflow-test-2.c: New test case.
* gcc.dg/plugin/location_overflow_plugin.c: New test plugin.
* gcc.dg/plugin/plugin.exp (plugin_test_list): Add the above.

libcpp/ChangeLog:
PR preprocessor/69177
* line-map.c (LINE_MAP_MAX_LOCATION_WITH_PACKED_RANGES): New
constant.
(LINE_MAP_MAX_LOCATION_WITH_COLS): Add note about unit tests
to comment.
(can_be_stored_compactly_p): Reduce threshold from
LINE_MAP_MAX_LOCATION_WITH_COLS to
LINE_MAP_MAX_LOCATION_WITH_PACKED_RANGES.
(get_combined_adhoc_loc): Likewise.
(get_range_from_loc): Likewise.
(linemap_line_start): Ensure that a new ordinary map is created
when transitioning from range-packing being enabled to disabled,
at the LINE_MAP_MAX_LOCATION_WITH_PACKED_RANGES threshold.  Set
range_bits to 0 for new ordinary maps when beyond this limit.
Prevent the "increase the column bits of a freshly created map"
optimization if the range bits has reduced.

git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@232379 138bc75d-0d04-0410-961f-82ee72b054a4

gcc/c-family/ChangeLog
gcc/c-family/c-indentation.c
gcc/testsuite/ChangeLog
gcc/testsuite/gcc.dg/plugin/location-overflow-test-1.c [new file with mode: 0644]
gcc/testsuite/gcc.dg/plugin/location-overflow-test-2.c [new file with mode: 0644]
gcc/testsuite/gcc.dg/plugin/location_overflow_plugin.c [new file with mode: 0644]
gcc/testsuite/gcc.dg/plugin/plugin.exp
libcpp/ChangeLog
libcpp/line-map.c

index d8282d9de470ab2d90f39e1945b88ee5039b5cf2..e3b9654c85b0f64161706d617ade7cf800c21d8d 100644 (file)
@@ -1,3 +1,12 @@
+2016-01-14  David Malcolm  <dmalcolm@redhat.com>
+
+       PR c++/68819
+       * c-indentation.c (get_visual_column): Add location_t param.
+       Handle the column number being zero by effectively disabling the
+       warning, with an "inform".
+       (should_warn_for_misleading_indentation): Add location_t argument
+       for all uses of get_visual_column.
+
 2016-01-10  Patrick Palka  <ppalka@gcc.gnu.org>
 
        PR c++/69029
index cd9637dc3fe04ae3eed8d5464644403e84ea49cd..521f9924fd0b0f3cc1347f92d3cd33b354dcadb2 100644 (file)
@@ -36,10 +36,30 @@ extern cpp_options *cpp_opts;
    on the line.  */
 
 static bool
-get_visual_column (expanded_location exploc,
+get_visual_column (expanded_location exploc, location_t loc,
                   unsigned int *out,
                   unsigned int *first_nws)
 {
+  /* PR c++/68819: if the column number is zero, we presumably
+     had a location_t > LINE_MAP_MAX_LOCATION_WITH_COLS, and so
+     we have no column information.
+     Act as if no conversion was possible, triggering the
+     error-handling path in the caller.  */
+  if (!exploc.column)
+    {
+      static bool issued_note = false;
+      if (!issued_note)
+       {
+         /* Notify the user the first time this happens.  */
+         issued_note = true;
+         inform (loc,
+                 "-Wmisleading-indentation is disabled from this point"
+                 " onwards, since column-tracking was disabled due to"
+                 " the size of the code/headers");
+       }
+      return false;
+    }
+
   int line_len;
   const char *line = location_get_source_line (exploc.file, exploc.line,
                                               &line_len);
@@ -297,7 +317,7 @@ should_warn_for_misleading_indentation (const token_indent_info &guard_tinfo,
          gcc_assert (guard_exploc.line == next_stmt_exploc.line);
          unsigned int guard_vis_column;
          unsigned int guard_line_first_nws;
-         if (!get_visual_column (guard_exploc,
+         if (!get_visual_column (guard_exploc, guard_loc,
                                  &guard_vis_column,
                                  &guard_line_first_nws))
            return false;
@@ -357,14 +377,15 @@ should_warn_for_misleading_indentation (const token_indent_info &guard_tinfo,
         the case for input files containing #line directives, and these
         are often for autogenerated sources (e.g. from .md files), where
         it's not clear that it's meaningful to look at indentation.  */
-      if (!get_visual_column (next_stmt_exploc, &next_stmt_vis_column,
+      if (!get_visual_column (next_stmt_exploc, next_stmt_loc,
+                             &next_stmt_vis_column,
                              &next_stmt_line_first_nws))
        return false;
-      if (!get_visual_column (body_exploc,
+      if (!get_visual_column (body_exploc, body_loc,
                              &body_vis_column,
                              &body_line_first_nws))
        return false;
-      if (!get_visual_column (guard_exploc,
+      if (!get_visual_column (guard_exploc, guard_loc,
                              &guard_vis_column,
                              &guard_line_first_nws))
        return false;
index 3d67923f91c700526eb4e18da9649a5167fa1b21..be42191854545e0718a38b2f09ccf11387021d7b 100644 (file)
@@ -1,3 +1,12 @@
+2016-01-14  David Malcolm  <dmalcolm@redhat.com>
+
+       PR c++/68819
+       PR preprocessor/69177
+       * gcc.dg/plugin/location-overflow-test-1.c: New test case.
+       * gcc.dg/plugin/location-overflow-test-2.c: New test case.
+       * gcc.dg/plugin/location_overflow_plugin.c: New test plugin.
+       * gcc.dg/plugin/plugin.exp (plugin_test_list): Add the above.
+
 2016-01-14  Marek Polacek  <polacek@redhat.com>
 
        PR c/69262
diff --git a/gcc/testsuite/gcc.dg/plugin/location-overflow-test-1.c b/gcc/testsuite/gcc.dg/plugin/location-overflow-test-1.c
new file mode 100644 (file)
index 0000000..7983c03
--- /dev/null
@@ -0,0 +1,28 @@
+/* { dg-options "-Wmisleading-indentation -Wall -fplugin-arg-location_overflow_plugin-value=0x60000001" } */
+
+/* We use location_overflow_plugin.c, which injects the case that location_t
+   values have exceeded LINE_MAP_MAX_LOCATION_WITH_COLS, and hence no column
+   numbers are available.  */
+
+/* Verify that we're in column-less mode.  */
+extern unknown_type test; /* { dg-error "0: unknown type name" } */
+
+/* PR c++/68819: verify that -Wmisleading-indentation is suppressed.  */
+
+int
+fn_1 (int flag)
+{
+  int x = 4, y = 5;
+  if (flag) x = 3; y = 2; /* { dg-message "disabled from this point" } */
+  return x * y;
+}
+
+/* ...and that a "sorry" is only emitted the first time.  */
+
+int
+fn_2 (int flag)
+{
+  int x = 4, y = 5;
+  if (flag) x = 3; y = 2; /* { dg-bogus "sorry" } */
+  return x * y;
+}
diff --git a/gcc/testsuite/gcc.dg/plugin/location-overflow-test-2.c b/gcc/testsuite/gcc.dg/plugin/location-overflow-test-2.c
new file mode 100644 (file)
index 0000000..c8b45b6
--- /dev/null
@@ -0,0 +1,36 @@
+/* { dg-options "-fdiagnostics-show-caret -Wmisleading-indentation -Wall -fplugin-arg-location_overflow_plugin-value=0x50000001" } */
+
+/* We use location_overflow_plugin.c, which injects the case that location_t
+   values have exceeded LINE_MAP_MAX_LOCATION_WITH_PACKED_RANGES, and hence
+   no range-packing should occur.  */
+
+/* Verify that we still have column numbers.  */
+extern unknown_type test; /* { dg-error "8: unknown type name" } */
+
+/* ...and ranges.  */
+/* { dg-begin-multiline-output "" }
+ extern unknown_type test;
+        ^~~~~~~~~~~~
+   { dg-end-multiline-output "" } */
+
+
+/* PR c++/68819: verify that -Wmisleading-indentation is still available.  */
+
+int
+fn_1 (int flag)
+{
+  int foo = 4, bar = 5;
+  if (flag) foo = 3; bar = 2; /* { dg-warning "indented" } */
+  return foo * bar;
+}
+
+/* Verify that we still have ranges, despite the lack of packing.  */
+
+/* { dg-begin-multiline-output "" }
+   if (flag) foo = 3; bar = 2;
+                      ^~~
+   { dg-end-multiline-output "" } */
+/* { dg-begin-multiline-output "" }
+   if (flag) foo = 3; bar = 2;
+   ^~
+   { dg-end-multiline-output "" } */
diff --git a/gcc/testsuite/gcc.dg/plugin/location_overflow_plugin.c b/gcc/testsuite/gcc.dg/plugin/location_overflow_plugin.c
new file mode 100644 (file)
index 0000000..1c140d8
--- /dev/null
@@ -0,0 +1,103 @@
+/* Plugin for testing how gracefully we degrade in the face of very
+   large source files.  */
+
+#include "config.h"
+#include "gcc-plugin.h"
+#include "system.h"
+#include "coretypes.h"
+#include "spellcheck.h"
+#include "diagnostic.h"
+
+int plugin_is_GPL_compatible;
+
+static location_t base_location;
+
+/* Callback handler for the PLUGIN_START_UNIT event; pretend
+   we parsed a very large include file.  */
+
+static void
+on_start_unit (void */*gcc_data*/, void */*user_data*/)
+{
+  /* Act as if we've already parsed a large body of code;
+     so that we can simulate various fallbacks in libcpp:
+
+     0x50000001 > LINE_MAP_MAX_LOCATION_WITH_PACKED_RANGES:
+     this will trigger the creation of line maps with range_bits == 0
+     so that all ranges will be stored in the ad-hoc lookaside.
+
+     0x60000001 > LINE_MAP_MAX_LOCATION_WITH_COLS:
+     this will trigger the creation of line maps with column_bits == 0
+     and hence we will immediately degrade to having locations in which
+     column number is 0. */
+  line_table->highest_location = base_location;
+}
+
+/* We add some extra testing during diagnostics by chaining up
+   to the finalizer.  */
+
+static diagnostic_finalizer_fn original_finalizer = NULL;
+
+static void
+verify_unpacked_ranges  (diagnostic_context *context,
+                        diagnostic_info *diagnostic)
+{
+  /* Verify that the locations are ad-hoc, not packed. */
+  location_t loc = diagnostic_location (diagnostic);
+  gcc_assert (IS_ADHOC_LOC (loc));
+
+  /* We're done testing; chain up to original finalizer.  */
+  gcc_assert (original_finalizer);
+  original_finalizer (context, diagnostic);
+}
+
+static void
+verify_no_columns  (diagnostic_context *context,
+                   diagnostic_info *diagnostic)
+{
+  /* Verify that the locations have no columns. */
+  location_t loc = diagnostic_location (diagnostic);
+  gcc_assert (LOCATION_COLUMN (loc) == 0);
+
+  /* We're done testing; chain up to original finalizer.  */
+  gcc_assert (original_finalizer);
+  original_finalizer (context, diagnostic);
+}
+
+int
+plugin_init (struct plugin_name_args *plugin_info,
+            struct plugin_gcc_version */*version*/)
+{
+  /* Read VALUE from -fplugin-arg-location_overflow_plugin-value=<VALUE>
+     in hexadecimal form into base_location.  */
+  for (int i = 0; i < plugin_info->argc; i++)
+    {
+      if (0 == strcmp (plugin_info->argv[i].key, "value"))
+       base_location = strtol (plugin_info->argv[i].value, NULL, 16);
+    }
+
+  if (!base_location)
+    error_at (UNKNOWN_LOCATION, "missing plugin argument");
+
+  register_callback (plugin_info->base_name,
+                    PLUGIN_START_UNIT,
+                    on_start_unit,
+                    NULL); /* void *user_data */
+
+  /* Hack in additional testing, based on the exact value supplied.  */
+  original_finalizer = diagnostic_finalizer (global_dc);
+  switch (base_location)
+    {
+    case 0x50000001:
+      diagnostic_finalizer (global_dc) = verify_unpacked_ranges;
+      break;
+
+    case 0x60000001:
+      diagnostic_finalizer (global_dc) = verify_no_columns;
+      break;
+
+    default:
+      error_at (UNKNOWN_LOCATION, "unrecognized value for plugin argument");
+    }
+
+  return 0;
+}
index 0dd310e2d406de862da9112a64b6e261ccd22d38..fd1e98e53c4eafb939995de0e1c293e92e4f4c1a 100644 (file)
@@ -71,6 +71,9 @@ set plugin_test_list [list \
     { diagnostic_plugin_show_trees.c \
          diagnostic-test-show-trees-1.c } \
     { levenshtein_plugin.c levenshtein-test-1.c } \
+    { location_overflow_plugin.c \
+         location-overflow-test-1.c \
+         location-overflow-test-2.c } \
 ]
 
 foreach plugin_test $plugin_test_list {
index 7845795b8406aa6d1f7dbbfbc7325b16be111be9..da733b705b0fb29269f2614b3b1d6f1c2682da1a 100644 (file)
@@ -1,3 +1,22 @@
+2016-01-14  David Malcolm  <dmalcolm@redhat.com>
+
+       PR preprocessor/69177
+       * line-map.c (LINE_MAP_MAX_LOCATION_WITH_PACKED_RANGES): New
+       constant.
+       (LINE_MAP_MAX_LOCATION_WITH_COLS): Add note about unit tests
+       to comment.
+       (can_be_stored_compactly_p): Reduce threshold from
+       LINE_MAP_MAX_LOCATION_WITH_COLS to
+       LINE_MAP_MAX_LOCATION_WITH_PACKED_RANGES.
+       (get_combined_adhoc_loc): Likewise.
+       (get_range_from_loc): Likewise.
+       (linemap_line_start): Ensure that a new ordinary map is created
+       when transitioning from range-packing being enabled to disabled,
+       at the LINE_MAP_MAX_LOCATION_WITH_PACKED_RANGES threshold.  Set
+       range_bits to 0 for new ordinary maps when beyond this limit.
+       Prevent the "increase the column bits of a freshly created map"
+       optimization if the range bits has reduced.
+
 2016-01-08  Jakub Jelinek  <jakub@redhat.com>
 
        PR c++/69145
index e5619a9b34d0501dfbf3572a83a16c37d6bb8aca..fcf025956d1579beda34ac10856b4623125fe6e4 100644 (file)
@@ -31,7 +31,16 @@ along with this program; see the file COPYING3.  If not see
    disabled).  */
 const unsigned int LINE_MAP_MAX_COLUMN_NUMBER = (1U << 12);
 
-/* Do not track column numbers if locations get higher than this.  */
+/* Do not pack ranges if locations get higher than this.
+   If you change this, update:
+     gcc.dg/plugin/location_overflow_plugin.c
+     gcc.dg/plugin/location-overflow-test-*.c.  */
+const source_location LINE_MAP_MAX_LOCATION_WITH_PACKED_RANGES = 0x50000000;
+
+/* Do not track column numbers if locations get higher than this.
+   If you change this, update:
+     gcc.dg/plugin/location_overflow_plugin.c
+     gcc.dg/plugin/location-overflow-test-*.c.  */
 const source_location LINE_MAP_MAX_LOCATION_WITH_COLS = 0x60000000;
 
 /* Highest possible source location encoded within an ordinary or
@@ -138,7 +147,7 @@ can_be_stored_compactly_p (struct line_maps *set,
   if (src_range.m_start < RESERVED_LOCATION_COUNT)
     return false;
 
-  if (locus >= LINE_MAP_MAX_LOCATION_WITH_COLS)
+  if (locus >= LINE_MAP_MAX_LOCATION_WITH_PACKED_RANGES)
     return false;
 
   /* All 3 locations must be within ordinary maps, typically, the same
@@ -175,7 +184,7 @@ get_combined_adhoc_loc (struct line_maps *set,
   /* Any ordinary locations ought to be "pure" at this point: no
      compressed ranges.  */
   linemap_assert (locus < RESERVED_LOCATION_COUNT
-                 || locus >= LINE_MAP_MAX_LOCATION_WITH_COLS
+                 || locus >= LINE_MAP_MAX_LOCATION_WITH_PACKED_RANGES
                  || locus >= LINEMAPS_MACRO_LOWEST_LOCATION (set)
                  || pure_location_p (set, locus));
 
@@ -284,7 +293,7 @@ get_range_from_loc (struct line_maps *set,
   /* For ordinary maps, extract packed range.  */
   if (loc >= RESERVED_LOCATION_COUNT
       && loc < LINEMAPS_MACRO_LOWEST_LOCATION (set)
-      && loc <= LINE_MAP_MAX_LOCATION_WITH_COLS)
+      && loc <= LINE_MAP_MAX_LOCATION_WITH_PACKED_RANGES)
     {
       const line_map *map = linemap_lookup (set, loc);
       const line_map_ordinary *ordmap = linemap_check_ordinary (map);
@@ -715,6 +724,8 @@ linemap_line_start (struct line_maps *set, linenum_type to_line,
          && line_delta * map->m_column_and_range_bits > 1000)
       || (max_column_hint >= (1U << effective_column_bits))
       || (max_column_hint <= 80 && effective_column_bits >= 10)
+      || (highest > LINE_MAP_MAX_LOCATION_WITH_PACKED_RANGES
+         && map->m_range_bits > 0)
       || (highest > LINE_MAP_MAX_LOCATION_WITH_COLS
          && (set->max_column_hint || highest >= LINE_MAP_MAX_SOURCE_LOCATION)))
     add_map = true;
@@ -739,7 +750,10 @@ linemap_line_start (struct line_maps *set, linenum_type to_line,
       else
        {
          column_bits = 7;
-         range_bits = set->default_range_bits;
+         if (highest <= LINE_MAP_MAX_LOCATION_WITH_PACKED_RANGES)
+           range_bits = set->default_range_bits;
+         else
+           range_bits = 0;
          while (max_column_hint >= (1U << column_bits))
            column_bits++;
          max_column_hint = 1U << column_bits;
@@ -749,7 +763,8 @@ linemap_line_start (struct line_maps *set, linenum_type to_line,
         single line we can sometimes just increase its column_bits instead. */
       if (line_delta < 0
          || last_line != ORDINARY_MAP_STARTING_LINE_NUMBER (map)
-         || SOURCE_COLUMN (map, highest) >= (1U << column_bits))
+         || SOURCE_COLUMN (map, highest) >= (1U << column_bits)
+         || range_bits < map->m_range_bits)
        map = linemap_check_ordinary
                (const_cast <line_map *>
                  (linemap_add (set, LC_RENAME,