diff options
author | dmalcolm <dmalcolm@138bc75d-0d04-0410-961f-82ee72b054a4> | 2016-01-14 19:10:17 +0000 |
---|---|---|
committer | dmalcolm <dmalcolm@138bc75d-0d04-0410-961f-82ee72b054a4> | 2016-01-14 19:10:17 +0000 |
commit | a7ed45837eacff818524fdca94ce0c589aee9374 (patch) | |
tree | 5d6ecf5555c474502a0f17a07628d03e228b3ab7 | |
parent | ca5b12a4daf636c4c33ad670a90f4b16ec7bd089 (diff) | |
download | gcc-a7ed45837eacff818524fdca94ce0c589aee9374.tar.gz |
PR preprocessor/69177 and PR c++/68819: libcpp fallbacks and -Wmisleading-indentation
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
-rw-r--r-- | gcc/c-family/ChangeLog | 9 | ||||
-rw-r--r-- | gcc/c-family/c-indentation.c | 31 | ||||
-rw-r--r-- | gcc/testsuite/ChangeLog | 9 | ||||
-rw-r--r-- | gcc/testsuite/gcc.dg/plugin/location-overflow-test-1.c | 28 | ||||
-rw-r--r-- | gcc/testsuite/gcc.dg/plugin/location-overflow-test-2.c | 36 | ||||
-rw-r--r-- | gcc/testsuite/gcc.dg/plugin/location_overflow_plugin.c | 103 | ||||
-rw-r--r-- | gcc/testsuite/gcc.dg/plugin/plugin.exp | 3 | ||||
-rw-r--r-- | libcpp/ChangeLog | 19 | ||||
-rw-r--r-- | libcpp/line-map.c | 27 |
9 files changed, 254 insertions, 11 deletions
diff --git a/gcc/c-family/ChangeLog b/gcc/c-family/ChangeLog index d8282d9de47..e3b9654c85b 100644 --- a/gcc/c-family/ChangeLog +++ b/gcc/c-family/ChangeLog @@ -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 diff --git a/gcc/c-family/c-indentation.c b/gcc/c-family/c-indentation.c index cd9637dc3fe..521f9924fd0 100644 --- a/gcc/c-family/c-indentation.c +++ b/gcc/c-family/c-indentation.c @@ -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; diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index 3d67923f91c..be421918545 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -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 index 00000000000..7983c035862 --- /dev/null +++ b/gcc/testsuite/gcc.dg/plugin/location-overflow-test-1.c @@ -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 index 00000000000..c8b45b654ba --- /dev/null +++ b/gcc/testsuite/gcc.dg/plugin/location-overflow-test-2.c @@ -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 index 00000000000..1c140d81f51 --- /dev/null +++ b/gcc/testsuite/gcc.dg/plugin/location_overflow_plugin.c @@ -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; +} diff --git a/gcc/testsuite/gcc.dg/plugin/plugin.exp b/gcc/testsuite/gcc.dg/plugin/plugin.exp index 0dd310e2d40..fd1e98e53c4 100644 --- a/gcc/testsuite/gcc.dg/plugin/plugin.exp +++ b/gcc/testsuite/gcc.dg/plugin/plugin.exp @@ -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 { diff --git a/libcpp/ChangeLog b/libcpp/ChangeLog index 7845795b840..da733b705b0 100644 --- a/libcpp/ChangeLog +++ b/libcpp/ChangeLog @@ -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 diff --git a/libcpp/line-map.c b/libcpp/line-map.c index e5619a9b34d..fcf025956d1 100644 --- a/libcpp/line-map.c +++ b/libcpp/line-map.c @@ -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, |