The various decls relating to rich_location are in
libcpp/include/line-map.h, but they don't relate to line maps.
Split them out to their own header: libcpp/include/rich-location.h
No functional change intended.
gcc/ChangeLog:
* Makefile.in (CPPLIB_H): Add libcpp/include/rich-location.h.
* coretypes.h (class rich_location): New forward decl.
gcc/analyzer/ChangeLog:
* analyzer.h: Include "rich-location.h".
gcc/c-family/ChangeLog:
* c-lex.cc: Include "rich-location.h".
gcc/cp/ChangeLog:
* mapper-client.cc: Include "rich-location.h".
gcc/ChangeLog:
* diagnostic.h: Include "rich-location.h".
* edit-context.h (class fixit_hint): New forward decl.
* gcc-rich-location.h: Include "rich-location.h".
* genmatch.cc: Likewise.
* pretty-print.h: Likewise.
gcc/rust/ChangeLog:
* rust-location.h: Include "rich-location.h".
libcpp/ChangeLog:
* Makefile.in (TAGS_SOURCES): Add "include/rich-location.h".
* include/cpplib.h (class rich_location): New forward decl.
* include/line-map.h (class range_label)
(enum range_display_kind, struct location_range)
(class semi_embedded_vec, class rich_location, class label_text)
(class range_label, class fixit_hint): Move to...
* include/rich-location.h: ...this new file.
* internal.h: Include "rich-location.h".
Signed-off-by: David Malcolm <dmalcolm@redhat.com>
Reduce implicit usage of line_table global, and move source printing to
within diagnostic_context.
gcc/ChangeLog:
* diagnostic-show-locus.cc (layout::m_line_table): New field.
(compatible_locations_p): Convert to...
(layout::compatible_locations_p): ...this, replacing uses of
line_table global with m_line_table.
(layout::layout): Convert "richloc" param from a pointer to a
const reference. Initialize m_line_table member.
(layout::maybe_add_location_range): Replace uses of line_table
global with m_line_table. Pass the latter to
linemap_client_expand_location_to_spelling_point.
(layout::print_leading_fixits): Pass m_line_table to
affects_line_p.
(layout::print_trailing_fixits): Likewise.
(gcc_rich_location::add_location_if_nearby): Update for change
to layout ctor params.
(diagnostic_show_locus): Convert to...
(diagnostic_context::maybe_show_locus): ...this, converting
richloc param from a pointer to a const reference. Make "loc"
const. Split out printing part of function to...
(diagnostic_context::show_locus): ...this.
(selftest::test_offset_impl): Update for change to layout ctor
params.
(selftest::test_layout_x_offset_display_utf8): Likewise.
(selftest::test_layout_x_offset_display_tab): Likewise.
(selftest::test_tab_expansion): Likewise.
* diagnostic.h (diagnostic_context::maybe_show_locus): New decl.
(diagnostic_context::show_locus): New decl.
(diagnostic_show_locus): Convert from a decl to an inline function.
* gdbinit.in (break-on-diagnostic): Update from a breakpoint
on diagnostic_show_locus to one on
diagnostic_context::maybe_show_locus.
* genmatch.cc (linemap_client_expand_location_to_spelling_point):
Add "set" param and use it in place of line_table global.
* input.cc (expand_location_1): Likewise.
(expand_location): Update for new param of expand_location_1.
(expand_location_to_spelling_point): Likewise.
(linemap_client_expand_location_to_spelling_point): Add "set"
param and use it in place of line_table global.
* tree-diagnostic-path.cc (event_range::print): Pass line_table
for new param of linemap_client_expand_location_to_spelling_point.
libcpp/ChangeLog:
* include/line-map.h (rich_location::get_expanded_location): Make
const.
(rich_location::get_line_table): New accessor.
(rich_location::m_line_table): Make the pointer be const.
(rich_location::m_have_expanded_location): Make mutable.
(rich_location::m_expanded_location): Likewise.
(fixit_hint::affects_line_p): Add const line_maps * param.
(linemap_client_expand_location_to_spelling_point): Likewise.
* line-map.cc (rich_location::get_expanded_location): Make const.
Pass m_line_table to
linemap_client_expand_location_to_spelling_point.
(rich_location::maybe_add_fixit): Likewise.
(fixit_hint::affects_line_p): Add set param and pass to
linemap_client_expand_location_to_spelling_point.
Signed-off-by: David Malcolm <dmalcolm@redhat.com>
This patch eliminates the function "MACRO_MAP_EXPANSION_POINT_LOCATION"
(which hasn't been a macro since r6-739-g0501dbd932a7e9) in favor of
a new line_map_macro::get_expansion_point_location accessor.
No functional change intended.
gcc/c-family/ChangeLog:
* c-warn.cc (warn_for_multistatement_macros): Update for removal
of MACRO_MAP_EXPANSION_POINT_LOCATION.
gcc/cp/ChangeLog:
* module.cc (ordinary_loc_of): Update for removal of
MACRO_MAP_EXPANSION_POINT_LOCATION.
(module_state::note_location): Update for renaming of field.
(module_state::write_macro_maps): Likewise.
gcc/ChangeLog:
* input.cc (dump_location_info): Update for removal of
MACRO_MAP_EXPANSION_POINT_LOCATION.
* tree-diagnostic.cc (maybe_unwind_expanded_macro_loc):
Likewise.
libcpp/ChangeLog:
* include/line-map.h
(line_map_macro::get_expansion_point_location): New accessor.
(line_map_macro::expansion): Rename field to...
(line_map_macro::mexpansion): Rename field to...
(MACRO_MAP_EXPANSION_POINT_LOCATION): Delete this function.
* line-map.cc (linemap_enter_macro): Update for renaming of field.
(linemap_macro_map_loc_to_exp_point): Update for removal of
MACRO_MAP_EXPANSION_POINT_LOCATION.
Signed-off-by: David Malcolm <dmalcolm@redhat.com>
It's simpler to use field access than to go through these inline
functions that look as if they are macros.
No functional change intended.
libcpp/ChangeLog:
* include/line-map.h (maps_info_ordinary::cache): Rename to...
(maps_info_ordinary::m_cache): ...this.
(maps_info_macro::cache): Rename to...
(maps_info_macro::m_cache): ...this.
(LINEMAPS_CACHE): Delete.
(LINEMAPS_ORDINARY_CACHE): Delete.
(LINEMAPS_MACRO_CACHE): Delete.
* init.cc (read_original_filename): Update for adding "m_" prefix.
* line-map.cc (linemap_add): Eliminate LINEMAPS_ORDINARY_CACHE in
favor of a simple field access.
(linemap_enter_macro): Likewise for LINEMAPS_MACRO_CACHE.
(linemap_ordinary_map_lookup): Likewise for
LINEMAPS_ORDINARY_CACHE, twice.
(linemap_lookup_macro_index): Likewise for LINEMAPS_MACRO_CACHE.
Signed-off-by: David Malcolm <dmalcolm@redhat.com>
This patch eliminates the function "COMBINE_LOCATION_DATA" (which hasn't
been a macro since r6-739-g0501dbd932a7e9) and the function
"get_combined_adhoc_loc" in favor of a new
line_maps::get_or_create_combined_loc member function.
No functional change intended.
gcc/cp/ChangeLog:
* module.cc (module_state::read_location): Update for renaming of
get_combined_adhoc_loc.
gcc/ChangeLog:
* genmatch.cc (main): Update for "m_" prefix of some fields of
line_maps.
* input.cc (make_location): Update for removal of
COMBINE_LOCATION_DATA.
(dump_line_table_statistics): Update for "m_" prefix of some
fields of line_maps.
(location_with_discriminator): Update for removal of
COMBINE_LOCATION_DATA.
(line_table_test::line_table_test): Update for "m_" prefix of some
fields of line_maps.
* toplev.cc (general_init): Likewise.
* tree.cc (set_block): Update for removal of
COMBINE_LOCATION_DATA.
(set_source_range): Likewise.
libcpp/ChangeLog:
* include/line-map.h (line_maps::reallocator): Rename to...
(line_maps::m_reallocator): ...this.
(line_maps::round_alloc_size): Rename to...
(line_maps::m_round_alloc_size): ...this.
(line_maps::location_adhoc_data_map): Rename to...
(line_maps::m_location_adhoc_data_map): ...this.
(line_maps::num_optimized_ranges): Rename to...
(line_maps::m_num_optimized_ranges): ..this.
(line_maps::num_unoptimized_ranges): Rename to...
(line_maps::m_num_unoptimized_ranges): ...this.
(get_combined_adhoc_loc): Delete decl.
(COMBINE_LOCATION_DATA): Delete.
* lex.cc (get_location_for_byte_range_in_cur_line): Update for
removal of COMBINE_LOCATION_DATA.
(warn_about_normalization): Likewise.
(_cpp_lex_direct): Likewise.
* line-map.cc (line_maps::~line_maps): Update for "m_" prefix of
some fields of line_maps.
(rebuild_location_adhoc_htab): Likewise.
(can_be_stored_compactly_p): Convert to...
(line_maps::can_be_stored_compactly_p): ...this private member
function.
(get_combined_adhoc_loc): Convert to...
(line_maps::get_or_create_combined_loc): ...this public member
function.
(line_maps::make_location): Update for removal of
COMBINE_LOCATION_DATA.
(get_data_from_adhoc_loc): Update for "m_" prefix of some fields
of line_maps.
(get_discriminator_from_adhoc_loc): Likewise.
(get_location_from_adhoc_loc): Likewise.
(get_range_from_adhoc_loc): Convert to...
(line_maps::get_range_from_adhoc_loc): ...this private member
function.
(line_maps::get_range_from_loc): Update for conversion of
get_range_from_adhoc_loc to a member function.
(linemap_init): Update for "m_" prefix of some fields of
line_maps.
(line_map_new_raw): Likewise.
(linemap_enter_macro): Likewise.
(linemap_get_statistics): Likewise.
Signed-off-by: David Malcolm <dmalcolm@redhat.com>
This is the first in a series of patches to enable discriminator support
in AutoFDO.
This patch switches to tracking discriminators per statement/instruction
instead of per basic block. Tracking per basic block was problematic since
not all statements in a basic block needed a discriminator and, also, later
optimizations could move statements between basic blocks making correlation
during AutoFDO compilation unreliable. Tracking per statement also allows
us to assign different discriminators to multiple function calls in the same
basic block. A subsequent patch will add that support.
The idea of this patch is based on commit 4c311d95cf6d9519c3c20f641cc77af7df491fdf
by Dehao Chen in vendors/google/heads/gcc-4_8 but uses a slightly different
approach. In Dehao's work special (normally unused) location ids and side tables
were used to keep track of locations with discriminators. Things have changed
since then and I don't think we have unused location ids anymore. Instead,
I made discriminators a part of ad-hoc locations.
The difference from Dehao's work also includes support for discriminator
reading/writing in lto streaming and in modules.
Tested on x86_64-pc-linux-gnu.
gcc/ChangeLog:
* basic-block.h: Remove discriminator from basic blocks.
* cfghooks.cc (split_block_1): Remove discriminator from basic blocks.
* final.cc (final_start_function_1): Switch from per-bb to per statement
discriminator.
(final_scan_insn_1): Don't keep track of basic block discriminators.
(compute_discriminator): Switch from basic block discriminators to
instruction discriminators.
(insn_discriminator): New function to return instruction discriminator.
(notice_source_line): Use insn_discriminator.
* gimple-pretty-print.cc (dump_gimple_bb_header): Remove dumping of
basic block discriminators.
* gimple-streamer-in.cc (input_bb): Remove reading of basic block
discriminators.
* gimple-streamer-out.cc (output_bb): Remove writing of basic block
discriminators.
* input.cc (make_location): Pass 0 discriminator to COMBINE_LOCATION_DATA.
(location_with_discriminator): New function to combine locus with
a discriminator.
(has_discriminator): New function to check if a location has a discriminator.
(get_discriminator_from_loc): New function to get the discriminator
from a location.
* input.h: Declarations of new functions.
* lto-streamer-in.cc (cmp_loc): Use discriminators in location comparison.
(apply_location_cache): Keep track of current discriminator.
(input_location_and_block): Read discriminator from stream.
* lto-streamer-out.cc (clear_line_info): Set current discriminator to
UINT_MAX.
(lto_output_location_1): Write discriminator to stream.
* lto-streamer.h: Add discriminator to cached_location.
Add current_discr to lto_location_cache.
Add current_discr to output_block.
* print-rtl.cc (print_rtx_operand_code_i): Print discriminator.
* rtl.h: Add extern declaration of insn_discriminator.
* tree-cfg.cc (assign_discriminator): New function to assign a unique
discriminator value to all statements in a basic block that have the given
line number.
(assign_discriminators): Assign discriminators to statement locations.
* tree-pretty-print.cc (dump_location): Dump discriminators.
* tree.cc (set_block): Preserve discriminator when setting block.
(set_source_range): Preserve discriminator when setting source range.
gcc/cp/ChangeLog:
* module.cc (write_location): Write discriminator.
(read_location): Read discriminator.
libcpp/ChangeLog:
* include/line-map.h: Add discriminator to location_adhoc_data.
(get_combined_adhoc_loc): Add discriminator parameter.
(get_discriminator_from_adhoc_loc): Add external declaration.
(get_discriminator_from_loc): Add external declaration.
(COMBINE_LOCATION_DATA): Add discriminator parameter.
* lex.cc (get_location_for_byte_range_in_cur_line) Pass 0 discriminator
in a call to COMBINE_LOCATION_DATA.
(warn_about_normalization): Pass 0 discriminator in a call to
COMBINE_LOCATION_DATA.
(_cpp_lex_direct): Pass 0 discriminator in a call to
COMBINE_LOCATION_DATA.
* line-map.cc (location_adhoc_data_hash): Use discriminator compute
location_adhoc_data hash.
(location_adhoc_data_eq): Use discriminator when comparing
location_adhoc_data.
(can_be_stored_compactly_p): Check discriminator to determine
compact storage.
(get_combined_adhoc_loc): Add discriminator parameter.
(get_discriminator_from_adhoc_loc): New function to get the discriminator
from an ad-hoc location.
(get_discriminator_from_loc): New function to get the discriminator
from a location.
gcc/testsuite/ChangeLog:
* c-c++-common/ubsan/pr85213.c: Pass -gno-statement-frontiers.
This adjusts the API of label_text so that the data members are private
and cannot be modified by callers. Add accessors for them instead, and
make the accessors const-correct. Also rename moved_from () to the more
idiomatic release (). Also remove the unused take_or_copy () member
function which has confusing ownership semantics.
gcc/analyzer/ChangeLog:
* call-info.cc (call_info::print): Adjust to new label_text API.
* checker-path.cc (checker_event::dump): Likewise.
(region_creation_event::get_desc): Likewise.
(state_change_event::get_desc): Likewise.
(superedge_event::should_filter_p): Likewise.
(start_cfg_edge_event::get_desc): Likewise.
(call_event::get_desc): Likewise.
(return_event::get_desc): Likewise.
(warning_event::get_desc): Likewise.
(checker_path::dump): Likewise.
(checker_path::debug): Likewise.
* diagnostic-manager.cc (diagnostic_manager::prune_for_sm_diagnostic):
Likewise.
(diagnostic_manager::prune_interproc_events): Likewise.
* engine.cc (feasibility_state::maybe_update_for_edge):
Likewise.
* program-state.cc (sm_state_map::to_json): Likewise.
* region-model-impl-calls.cc (region_model::impl_call_analyzer_describe): Likewise.
(region_model::impl_call_analyzer_dump_capacity): Likewise.
* region.cc (region::to_json): Likewise.
* sm-malloc.cc (inform_nonnull_attribute): Likewise.
* store.cc (binding_map::to_json): Likewise.
(store::to_json): Likewise.
* supergraph.cc (superedge::dump): Likewise.
* svalue.cc (svalue::to_json): Likewise.
gcc/c-family/ChangeLog:
* c-format.cc (class range_label_for_format_type_mismatch):
Adjust to new label_text API.
gcc/ChangeLog:
* diagnostic-format-json.cc (json_from_location_range): Adjust
to new label_text API.
* diagnostic-format-sarif.cc (sarif_builder::make_location_object):
Likewise.
* diagnostic-show-locus.cc (struct pod_label_text): Likewise.
(layout::print_any_labels): Likewise.
* tree-diagnostic-path.cc (class path_label): Likewise.
(struct event_range): Likewise.
(default_tree_diagnostic_path_printer): Likewise.
(default_tree_make_json_for_path): Likewise.
libcpp/ChangeLog:
* include/line-map.h (label_text::take_or_copy): Remove.
(label_text::moved_from): Rename to release.
(label_text::m_buffer, label_text::m_owned): Make private.
(label_text::get, label_text::is_owned): New accessors.
std::move in a return statement can prevent the NRVO:
<https://developers.redhat.com/blog/2019/04/12/understanding-when-not-to-stdmove-in-c>
PR106272 reports that we have two such cases in class label_text's
member functions. We have -Wpessimizing-move that's supposed to detect
problematic std::move uses, but in this case it didn't trigger. I've filed
PR106276 to track that.
PR preprocessor/106272
libcpp/ChangeLog:
* include/line-map.h (class label_text): Don't std::move in a return
statement.
libcpp's class label_text stores a char * for a string and a flag saying
whether it owns the buffer. I added this class before we could use
C++11, and so to avoid lots of copying it required an explicit call
to label_text::maybe_free to potentially free the buffer.
Now that we can use C++11, this patch removes label_text::maybe_free in
favor of doing the cleanup in the destructor, and using C++ move
semantics to avoid any copying. This allows lots of messy cleanup code
to be eliminated in favor of implicit destruction (mostly in the
analyzer).
No functional change intended.
gcc/analyzer/ChangeLog:
* call-info.cc (call_info::print): Update for removal of
label_text::maybe_free in favor of automatic memory management.
* checker-path.cc (checker_event::dump): Likewise.
(checker_event::prepare_for_emission): Likewise.
(state_change_event::get_desc): Likewise.
(superedge_event::should_filter_p): Likewise.
(start_cfg_edge_event::get_desc): Likewise.
(warning_event::get_desc): Likewise.
(checker_path::dump): Likewise.
(checker_path::debug): Likewise.
* diagnostic-manager.cc
(diagnostic_manager::prune_for_sm_diagnostic): Likewise.
(diagnostic_manager::prune_interproc_events): Likewise.
* program-state.cc (sm_state_map::to_json): Likewise.
* region.cc (region::to_json): Likewise.
* sm-malloc.cc (inform_nonnull_attribute): Likewise.
* store.cc (binding_map::to_json): Likewise.
(store::to_json): Likewise.
* svalue.cc (svalue::to_json): Likewise.
gcc/c-family/ChangeLog:
* c-format.cc (range_label_for_format_type_mismatch::get_text):
Update for removal of label_text::maybe_free in favor of automatic
memory management.
gcc/ChangeLog:
* diagnostic-format-json.cc (json_from_location_range): Update for
removal of label_text::maybe_free in favor of automatic memory
management.
* diagnostic-format-sarif.cc
(sarif_builder::make_location_object): Likewise.
* diagnostic-show-locus.cc (struct pod_label_text): New.
(class line_label): Convert m_text from label_text to pod_label_text.
(layout::print_any_labels): Move "text" to the line_label.
* tree-diagnostic-path.cc (path_label::get_text): Update for
removal of label_text::maybe_free in favor of automatic memory
management.
(event_range::print): Likewise.
(default_tree_diagnostic_path_printer): Likewise.
(default_tree_make_json_for_path): Likewise.
libcpp/ChangeLog:
* include/line-map.h: Include <utility>.
(class label_text): Delete maybe_free method in favor of a
destructor. Add move ctor and assignment operator. Add deletion
of the copy ctor and copy-assignment operator. Rename field
m_caller_owned to m_owned. Add std::move where necessary; add
moved_from member function.
Signed-off-by: David Malcolm <dmalcolm@redhat.com>
So, if we want to make PCH work for PIEs, I'd say we can:
1) add a new GTY option, say callback, which would act like
skip for non-PCH and for PCH would make us skip it but
remember for address bias translation
2) drop the skip for tree_translation_unit_decl::language
3) change get_unnamed_section to have const char * as
last argument instead of const void *, change
unnamed_section::data also to const char * and update
everything related to that
4) maybe add a host hook whether it is ok to support binaries
changing addresses (the only thing I'm worried is if
some host that uses function descriptors allocates them
dynamically instead of having them somewhere in the
executable)
5) maybe add a gengtype warning if it sees in GTY tracked
structure a function pointer without that new callback
option
Here is 1), 2), 3) implemented.
Note, on stdc++.h.gch/O2g.gch there are just those 10 relocations without
the second patch, with it a few more, but nothing huge. And for non-PIEs
there isn't really any extra work on the load side except freading two scalar
values and fseek.
2021-12-03 Jakub Jelinek <jakub@redhat.com>
PR pch/71934
gcc/
* ggc.h (gt_pch_note_callback): Declare.
* gengtype.h (enum typekind): Add TYPE_CALLBACK.
(callback_type): Declare.
* gengtype.c (dbgprint_count_type_at): Handle TYPE_CALLBACK.
(callback_type): New variable.
(process_gc_options): Add CALLBACK argument, handle callback
option.
(set_gc_used_type): Adjust process_gc_options caller, if callback,
set type to &callback_type.
(output_mangled_typename): Handle TYPE_CALLBACK.
(walk_type): Likewise. Handle callback option.
(write_types_process_field): Handle TYPE_CALLBACK.
(write_types_local_user_process_field): Likewise.
(write_types_local_process_field): Likewise.
(write_root): Likewise.
(dump_typekind): Likewise.
(dump_type): Likewise.
* gengtype-state.c (type_lineloc): Handle TYPE_CALLBACK.
(state_writer::write_state_callback_type): New method.
(state_writer::write_state_type): Handle TYPE_CALLBACK.
(read_state_callback_type): New function.
(read_state_type): Handle TYPE_CALLBACK.
* ggc-common.c (callback_vec): New variable.
(gt_pch_note_callback): New function.
(gt_pch_save): Stream out gt_pch_save function address and relocation
table.
(gt_pch_restore): Stream in saved gt_pch_save function address and
relocation table and apply relocations if needed.
* doc/gty.texi (callback): Document new GTY option.
* varasm.c (get_unnamed_section): Change callback argument's type and
last argument's type from const void * to const char *.
(output_section_asm_op): Change argument's type from const void *
to const char *, remove unnecessary cast.
* tree-core.h (struct tree_translation_unit_decl): Drop GTY((skip))
from language member.
* output.h (unnamed_section_callback): Change argument type from
const void * to const char *.
(struct unnamed_section): Use GTY((callback)) instead of GTY((skip))
for callback member. Change data member type from const void *
to const char *.
(struct noswitch_section): Use GTY((callback)) instead of GTY((skip))
for callback member.
(get_unnamed_section): Change callback argument's type and
last argument's type from const void * to const char *.
(output_section_asm_op): Change argument's type from const void *
to const char *.
* config/avr/avr.c (avr_output_progmem_section_asm_op): Likewise.
Remove unneeded cast.
* config/darwin.c (output_objc_section_asm_op): Change argument's type
from const void * to const char *.
* config/pa/pa.c (som_output_text_section_asm_op): Likewise.
(som_output_comdat_data_section_asm_op): Likewise.
* config/rs6000/rs6000.c (rs6000_elf_output_toc_section_asm_op):
Likewise.
(rs6000_xcoff_output_readonly_section_asm_op): Likewise. Instead
of dereferencing directive hardcode variable names and decide based on
whether directive is NULL or not.
(rs6000_xcoff_output_readwrite_section_asm_op): Change argument's type
from const void * to const char *.
(rs6000_xcoff_output_tls_section_asm_op): Likewise. Instead
of dereferencing directive hardcode variable names and decide based on
whether directive is NULL or not.
(rs6000_xcoff_output_toc_section_asm_op): Change argument's type
from const void * to const char *.
(rs6000_xcoff_asm_init_sections): Adjust get_unnamed_section callers.
gcc/c-family/
* c-pch.c (struct c_pch_validity): Remove pch_init member.
(pch_init): Don't initialize v.pch_init.
(c_common_valid_pch): Don't warn and punt if .text addresses change.
libcpp/
* include/line-map.h (class line_maps): Add GTY((callback)) to
reallocator and round_alloc_size members.
This patch adds support to GCC's diagnostic subsystem for escaping certain
bytes and Unicode characters when quoting source code.
Specifically, this patch adds a new flag rich_location::m_escape_on_output
which is a hint from a diagnostic that non-ASCII bytes in the pertinent
lines of the user's source code should be escaped when printed.
The patch sets this for the following diagnostics:
- when complaining about stray bytes in the program (when these
are non-printable)
- when complaining about "null character(s) ignored");
- for -Wnormalized= (and generate source ranges for such warnings)
The escaping is controlled by a new option:
-fdiagnostics-escape-format=[unicode|bytes]
For example, consider a diagnostic involing a source line containing the
string "before" followed by the Unicode character U+03C0 ("GREEK SMALL
LETTER PI", with UTF-8 encoding 0xCF 0x80) followed by the byte 0xBF
(a stray UTF-8 trailing byte), followed by the string "after", where the
diagnostic highlights the U+03C0 character.
By default, this line will be printed verbatim to the user when
reporting a diagnostic at it, as:
beforeπXafter
^
(using X for the stray byte to avoid putting invalid UTF-8 in this
commit message)
If the diagnostic sets the "escape" flag, it will be printed as:
before<U+03C0><BF>after
^~~~~~~~
with -fdiagnostics-escape-format=unicode (the default), or as:
before<CF><80><BF>after
^~~~~~~~
if the user supplies -fdiagnostics-escape-format=bytes.
This only affects how the source is printed; it does not affect
how column numbers that are printed (as per -fdiagnostics-column-unit=
and -fdiagnostics-column-origin=).
gcc/c-family/ChangeLog:
* c-lex.c (c_lex_with_flags): When complaining about non-printable
CPP_OTHER tokens, set the "escape on output" flag.
gcc/ChangeLog:
* common.opt (fdiagnostics-escape-format=): New.
(diagnostics_escape_format): New enum.
(DIAGNOSTICS_ESCAPE_FORMAT_UNICODE): New enum value.
(DIAGNOSTICS_ESCAPE_FORMAT_BYTES): Likewise.
* diagnostic-format-json.cc (json_end_diagnostic): Add
"escape-source" attribute.
* diagnostic-show-locus.c
(exploc_with_display_col::exploc_with_display_col): Replace
"tabstop" param with a cpp_char_column_policy and add an "aspect"
param. Use these to compute m_display_col accordingly.
(struct char_display_policy): New struct.
(layout::m_policy): New field.
(layout::m_escape_on_output): New field.
(def_policy): New function.
(make_range): Update for changes to exploc_with_display_col ctor.
(default_print_decoded_ch): New.
(width_per_escaped_byte): New.
(escape_as_bytes_width): New.
(escape_as_bytes_print): New.
(escape_as_unicode_width): New.
(escape_as_unicode_print): New.
(make_policy): New.
(layout::layout): Initialize new fields. Update m_exploc ctor
call for above change to ctor.
(layout::maybe_add_location_range): Update for changes to
exploc_with_display_col ctor.
(layout::calculate_x_offset_display): Update for change to
cpp_display_width.
(layout::print_source_line): Pass policy
to cpp_display_width_computation. Capture cpp_decoded_char when
calling process_next_codepoint. Move printing of source code to
m_policy.m_print_cb.
(line_label::line_label): Pass in policy rather than context.
(layout::print_any_labels): Update for change to line_label ctor.
(get_affected_range): Pass in policy rather than context, updating
calls to location_compute_display_column accordingly.
(get_printed_columns): Likewise, also for cpp_display_width.
(correction::correction): Pass in policy rather than tabstop.
(correction::compute_display_cols): Pass m_policy rather than
m_tabstop to cpp_display_width.
(correction::m_tabstop): Replace with...
(correction::m_policy): ...this.
(line_corrections::line_corrections): Pass in policy rather than
context.
(line_corrections::m_context): Replace with...
(line_corrections::m_policy): ...this.
(line_corrections::add_hint): Update to use m_policy rather than
m_context.
(line_corrections::add_hint): Likewise.
(layout::print_trailing_fixits): Likewise.
(selftest::test_display_widths): New.
(selftest::test_layout_x_offset_display_utf8): Update to use
policy rather than tabstop.
(selftest::test_one_liner_labels_utf8): Add test of escaping
source lines.
(selftest::test_diagnostic_show_locus_one_liner_utf8): Update to
use policy rather than tabstop.
(selftest::test_overlapped_fixit_printing): Likewise.
(selftest::test_overlapped_fixit_printing_utf8): Likewise.
(selftest::test_overlapped_fixit_printing_2): Likewise.
(selftest::test_tab_expansion): Likewise.
(selftest::test_escaping_bytes_1): New.
(selftest::test_escaping_bytes_2): New.
(selftest::diagnostic_show_locus_c_tests): Call the new tests.
* diagnostic.c (diagnostic_initialize): Initialize
context->escape_format.
(convert_column_unit): Update to use default character width policy.
(selftest::test_diagnostic_get_location_text): Likewise.
* diagnostic.h (enum diagnostics_escape_format): New enum.
(diagnostic_context::escape_format): New field.
* doc/invoke.texi (-fdiagnostics-escape-format=): New option.
(-fdiagnostics-format=): Add "escape-source" attribute to examples
of JSON output, and document it.
* input.c (location_compute_display_column): Pass in "policy"
rather than "tabstop", passing to
cpp_byte_column_to_display_column.
(selftest::test_cpp_utf8): Update to use cpp_char_column_policy.
* input.h (class cpp_char_column_policy): New forward decl.
(location_compute_display_column): Pass in "policy" rather than
"tabstop".
* opts.c (common_handle_option): Handle
OPT_fdiagnostics_escape_format_.
* selftest.c (temp_source_file::temp_source_file): New ctor
overload taking a size_t.
* selftest.h (temp_source_file::temp_source_file): Likewise.
gcc/testsuite/ChangeLog:
* c-c++-common/diagnostic-format-json-1.c: Add regexp to consume
"escape-source" attribute.
* c-c++-common/diagnostic-format-json-2.c: Likewise.
* c-c++-common/diagnostic-format-json-3.c: Likewise.
* c-c++-common/diagnostic-format-json-4.c: Likewise, twice.
* c-c++-common/diagnostic-format-json-5.c: Likewise.
* gcc.dg/cpp/warn-normalized-4-bytes.c: New test.
* gcc.dg/cpp/warn-normalized-4-unicode.c: New test.
* gcc.dg/encoding-issues-bytes.c: New test.
* gcc.dg/encoding-issues-unicode.c: New test.
* gfortran.dg/diagnostic-format-json-1.F90: Add regexp to consume
"escape-source" attribute.
* gfortran.dg/diagnostic-format-json-2.F90: Likewise.
* gfortran.dg/diagnostic-format-json-3.F90: Likewise.
libcpp/ChangeLog:
* charset.c (convert_escape): Use encoding_rich_location when
complaining about nonprintable unknown escape sequences.
(cpp_display_width_computation::::cpp_display_width_computation):
Pass in policy rather than tabstop.
(cpp_display_width_computation::process_next_codepoint): Add "out"
param and populate *out if non-NULL.
(cpp_display_width_computation::advance_display_cols): Pass NULL
to process_next_codepoint.
(cpp_byte_column_to_display_column): Pass in policy rather than
tabstop. Pass NULL to process_next_codepoint.
(cpp_display_column_to_byte_column): Pass in policy rather than
tabstop.
* errors.c (cpp_diagnostic_get_current_location): New function,
splitting out the logic from...
(cpp_diagnostic): ...here.
(cpp_warning_at): New function.
(cpp_pedwarning_at): New function.
* include/cpplib.h (cpp_warning_at): New decl for rich_location.
(cpp_pedwarning_at): Likewise.
(struct cpp_decoded_char): New.
(struct cpp_char_column_policy): New.
(cpp_display_width_computation::cpp_display_width_computation):
Replace "tabstop" param with "policy".
(cpp_display_width_computation::process_next_codepoint): Add "out"
param.
(cpp_display_width_computation::m_tabstop): Replace with...
(cpp_display_width_computation::m_policy): ...this.
(cpp_byte_column_to_display_column): Replace "tabstop" param with
"policy".
(cpp_display_width): Likewise.
(cpp_display_column_to_byte_column): Likewise.
* include/line-map.h (rich_location::escape_on_output_p): New.
(rich_location::set_escape_on_output): New.
(rich_location::m_escape_on_output): New.
* internal.h (cpp_diagnostic_get_current_location): New decl.
(class encoding_rich_location): New.
* lex.c (skip_whitespace): Use encoding_rich_location when
complaining about null characters.
(warn_about_normalization): Generate a source range when
complaining about improperly normalized tokens, rather than just a
point, and use encoding_rich_location so that the source code
is escaped on printing.
* line-map.c (rich_location::rich_location): Initialize
m_escape_on_output.
Signed-off-by: David Malcolm <dmalcolm@redhat.com>
The problem is that the new IS_MACRO_LOC macro:
inline bool
IS_MACRO_LOC (location_t loc)
{
return !IS_ORDINARY_LOC (loc) && !IS_ADHOC_LOC (loc);
}
is not fully correct since the position of the macro lines is not fixed:
/* Returns the lowest location [of a token resulting from macro
expansion] encoded in this line table. */
inline location_t
LINEMAPS_MACRO_LOWEST_LOCATION (const line_maps *set)
{
return LINEMAPS_MACRO_USED (set)
? MAP_START_LOCATION (LINEMAPS_LAST_MACRO_MAP (set))
: MAX_LOCATION_T + 1;
}
In Ada, LINEMAPS_MACRO_USED is false so LINEMAPS_MACRO_LOWEST_LOCATION is
MAX_LOCATION_T + 1, but IS_MACRO_LOC nevertheless returns true for anything
in the range [LINE_MAP_MAX_LOCATION; MAX_LOCATION_T], thus yielding an ICE
in linemap_macro_map_lookup for very large files.
libcpp/
* include/line-map.h (IS_MACRO_LOC): Delete.
* line-map.c (linemap_location_from_macro_expansion_p): Test
LINEMAPS_MACRO_LOWEST_LOCATION of the linemap.
gcc/cp/
* module.cc (ordinary_loc_of): Test LINEMAPS_MACRO_LOWEST_LOCATION
of the linemap.
(module_state::write_location): Likewise.
This fixes some issues with macro maps. We were incorrectly
calculating the number of macro expansions in a location span, and I
had a workaround that partially covered that up. Further, while macro
location spans are monotonic, that is not true of ordinary location
spans. Thus we need to insert an indirection array when binary
searching the latter. (We load ordinary locations before loading
imports, but macro locations afterwards. We make sure an import
location is de-macrofied, if needed.)
PR c++/98718
gcc/cp/
* module.cc (ool): New indirection vector.
(loc_spans::maybe_propagate): Location is not optional.
(loc_spans::open): Likewise. Assert monotonically advancing.
(module_for_ordinary_loc): Use ool indirection vector.
(module_state::write_prepare_maps): Do not count empty macro
expansions. Elide empty spans.
(module_state::write_macro_maps): Skip empty expansions.
(ool_cmp): New qsort comparator.
(module_state::write): Create and destroy ool vector.
(name_pending_imports): Fix dump push/pop.
(preprocess_module): Likewise. Add more dumping.
(preprocessed_module): Likewise.
libcpp/
* include/line-map.h
* line-map.c
gcc/testsuite/
* g++.dg/modules/pr98718_a.C: New.
* g++.dg/modules/pr98718_b.C: New.
This patch adds LC_MODULE as a map kind, used to indicate a c++
module. Unlike a regular source file, it only contains a single
location, and the source locations in that module are represented by
ordinary locations whose 'included_from' location is the module.
It also exposes some entry points that modules will use to create
blocks of line maps.
In the original posting, I'd missed the deletion of the
linemap_enter_macro from internal.h. That's included here.
libcpp/
* include/line-map.h (enum lc_reason): Add LC_MODULE.
(MAP_MODULE_P): New.
(line_map_new_raw): Declare.
(linemap_enter_macro): Move declaration from internal.h
(linemap_module_loc, linemap_module_reparent)
(linemap_module_restore): Declare.
(linemap_lookup_macro_indec): Declare.
* internal.h (linemap_enter_macro): Moved to line-map.h.
* line-map.c (linemap_new_raw): New, broken out of ...
(new_linemap): ... here. Call it.
(LAST_SOURCE_LINE_LOCATION): New.
(liemap_module_loc, linemap_module_reparent)
(linemap_module_restore): New.
(linemap_lookup_macro_index): New, broken out of ...
(linemap_macro_map_lookup): ... here. Call it.
(linemap_dump): Add module dump.
Currently the -Wmisleading-indentation warning doesn't do any analysis
when the guarded statement or the statement after it is produced by a
macro. This means we warn for:
if (flag)
foo ();
bar ();
but not for:
#define BAR bar
if (flag)
foo ();
BAR ();
This patch extends the -Wmisleading-indentation implementation to
support analyzing such statements and their tokens. This is done in the
"natural" way by resolving the location of each of the three tokens to
the token's macro expansion point. (Additionally, if the tokens all
resolve to the same macro expansion point then we instead use their
locations within the macro definition.) When these resolved locations
are all different, then we can proceed with applying the warning
heuristics to them as if no macros were involved.
gcc/c-family/ChangeLog:
PR c/80076
* c-indentation.c (should_warn_for_misleading_indentation): Move
declarations of local variables closer to their first use.
Handle virtual token locations by resolving them to their
respective macro expansion points. If all three tokens are
produced from the same macro expansion, then instead use their
loci within the macro definition.
gcc/objc/ChangeLog:
PR c/80076
* objc-gnu-runtime-abi-01.c
(gnu_runtime_abi_01_get_class_super_ref): Reduce indentation of
misleadingly indented return statements.
* objc-next-runtime-abi-01.c
(next_runtime_abi_01_get_class_super_ref): Likewise.
gcc/ChangeLog:
PR c/80076
* gensupport.c (alter_attrs_for_subst_insn) <case SET_ATTR>:
Reduce indentation of misleadingly indented code fragment.
* lra-constraints.c (multi_block_pseudo_p): Likewise.
* sel-sched-ir.c (merge_fences): Likewise.
libcpp/ChangeLog:
PR c/80076
* include/line-map.h (first_map_in_common): Declare.
* line-map.c (first_map_in_common): Remove static.
gcc/testsuite/ChangeLog:
PR c/80076
* c-c++-common/Wmisleading-indentation-5.c: New test.
This fixes a bunch of poorly formatted decls, marks some getters as
PURE, deletes some C-relevant bool hackery, and finally uses a
passed-in location rather than deducing a closely-related but not
necessarily the same location.
* include/cpplib.h (cpp_get_otions, cpp_get_callbacks)
(cpp_get_deps): Mark as PURE.
* include/line-map.h (get_combined_adhoc_loc)
(get_location_from_adhoc_loc, get_pure_location): Reformat decls.
* internal.h (struct lexer_state): Clarify comment.
* system.h: Remove now-unneeded bool hackery.
* files.c (_cpp_find_file): Store LOC not highest_location.
This patch adds support for associating a "diagnostic_path" with a
diagnostic: a sequence of events predicted by the compiler that leads to
the problem occurring, with their locations in the user's source,
text descriptions, and stack information (for handling interprocedural
paths).
For example, the following (hypothetical) error has a 3-event
intraprocedural path:
test.c: In function 'demo':
test.c:29:5: error: passing NULL as argument 1 to 'PyList_Append' which
requires a non-NULL parameter
29 | PyList_Append(list, item);
| ^~~~~~~~~~~~~~~~~~~~~~~~~
'demo': events 1-3
|
| 25 | list = PyList_New(0);
| | ^~~~~~~~~~~~~
| | |
| | (1) when 'PyList_New' fails, returning NULL
| 26 |
| 27 | for (i = 0; i < count; i++) {
| | ~~~
| | |
| | (2) when 'i < count'
| 28 | item = PyLong_FromLong(random());
| 29 | PyList_Append(list, item);
| | ~~~~~~~~~~~~~~~~~~~~~~~~~
| | |
| | (3) when calling 'PyList_Append', passing NULL from (1) as argument 1
|
The patch adds a new "%@" format code for printing event IDs, so that
in the above, the description of event (3) mentions event (1), showing
the user where the bogus NULL value comes from (the event IDs are
colorized to draw the user's attention to them).
There is a separation between data vs presentation: the above shows how
the diagnostic-printing code has consolidated the path into a single run
of events, since all the events are near each other and within the same
function; more complicated examples (such as interprocedural paths)
might be printed as multiple runs of events.
Examples of how interprocedural paths are printed can be seen in the
test suite (which uses a plugin to exercise the code without relying
on specific warnings using this functionality).
Other output formats include
- JSON,
- printing each event as a separate "note", and
- to not emit paths.
gcc/ChangeLog:
* Makefile.in (OBJS): Add tree-diagnostic-path.o.
* common.opt (fdiagnostics-path-format=): New option.
(diagnostic_path_format): New enum.
(fdiagnostics-show-path-depths): New option.
* coretypes.h (diagnostic_event_id_t): New forward decl.
* diagnostic-color.c (color_dict): Add "path".
* diagnostic-event-id.h: New file.
* diagnostic-format-json.cc (json_from_expanded_location): Make
non-static.
(json_end_diagnostic): Call context->make_json_for_path if it
exists and the diagnostic has a path.
(diagnostic_output_format_init): Clear context->print_path.
* diagnostic-path.h: New file.
* diagnostic-show-locus.c (colorizer::set_range): Special-case
when printing a run of events in a diagnostic_path so that they
all get the same color.
(layout::m_diagnostic_path_p): New field.
(layout::layout): Initialize it.
(layout::print_any_labels): Don't colorize the label text for an
event in a diagnostic_path.
(gcc_rich_location::add_location_if_nearby): Add
"restrict_to_current_line_spans" and "label" params. Pass the
former to layout.maybe_add_location_range; pass the latter
when calling add_range.
* diagnostic.c: Include "diagnostic-path.h".
(diagnostic_initialize): Initialize context->path_format and
context->show_path_depths.
(diagnostic_show_any_path): New function.
(diagnostic_path::interprocedural_p): New function.
(diagnostic_report_diagnostic): Call diagnostic_show_any_path.
(simple_diagnostic_path::num_events): New function.
(simple_diagnostic_path::get_event): New function.
(simple_diagnostic_path::add_event): New function.
(simple_diagnostic_event::simple_diagnostic_event): New ctor.
(simple_diagnostic_event::~simple_diagnostic_event): New dtor.
(debug): New overload taking a diagnostic_path *.
* diagnostic.def (DK_DIAGNOSTIC_PATH): New.
* diagnostic.h (enum diagnostic_path_format): New enum.
(json::value): New forward decl.
(diagnostic_context::path_format): New field.
(diagnostic_context::show_path_depths): New field.
(diagnostic_context::print_path): New callback field.
(diagnostic_context::make_json_for_path): New callback field.
(diagnostic_show_any_path): New decl.
(json_from_expanded_location): New decl.
* doc/invoke.texi (-fdiagnostics-path-format=): New option.
(-fdiagnostics-show-path-depths): New option.
(-fdiagnostics-color): Add "path" to description of default
GCC_COLORS; describe it.
(-fdiagnostics-format=json): Document how diagnostic paths are
represented in the JSON output format.
* gcc-rich-location.h (gcc_rich_location::add_location_if_nearby):
Add optional params "restrict_to_current_line_spans" and "label".
* opts.c (common_handle_option): Handle
OPT_fdiagnostics_path_format_ and
OPT_fdiagnostics_show_path_depths.
* pretty-print.c: Include "diagnostic-event-id.h".
(pp_format): Implement "%@" format code for printing
diagnostic_event_id_t *.
(selftest::test_pp_format): Add tests for "%@".
* selftest-run-tests.c (selftest::run_tests): Call
selftest::tree_diagnostic_path_cc_tests.
* selftest.h (selftest::tree_diagnostic_path_cc_tests): New decl.
* toplev.c (general_init): Initialize global_dc->path_format and
global_dc->show_path_depths.
* tree-diagnostic-path.cc: New file.
* tree-diagnostic.c (maybe_unwind_expanded_macro_loc): Make
non-static. Drop "diagnostic" param in favor of storing the
original value of "where" and re-using it.
(virt_loc_aware_diagnostic_finalizer): Update for dropped param of
maybe_unwind_expanded_macro_loc.
(tree_diagnostics_defaults): Initialize context->print_path and
context->make_json_for_path.
* tree-diagnostic.h (default_tree_diagnostic_path_printer): New
decl.
(default_tree_make_json_for_path): New decl.
(maybe_unwind_expanded_macro_loc): New decl.
gcc/c-family/ChangeLog:
* c-format.c (local_event_ptr_node): New.
(PP_FORMAT_CHAR_TABLE): Add entry for "%@".
(init_dynamic_diag_info): Initialize local_event_ptr_node.
* c-format.h (T_EVENT_PTR): New define.
gcc/testsuite/ChangeLog:
* gcc.dg/format/gcc_diag-10.c (diagnostic_event_id_t): New
typedef.
(test_diag): Add coverage of "%@".
* gcc.dg/plugin/diagnostic-path-format-default.c: New test.
* gcc.dg/plugin/diagnostic-path-format-inline-events-1.c: New test.
* gcc.dg/plugin/diagnostic-path-format-inline-events-2.c: New test.
* gcc.dg/plugin/diagnostic-path-format-inline-events-3.c: New test.
* gcc.dg/plugin/diagnostic-path-format-none.c: New test.
* gcc.dg/plugin/diagnostic-test-paths-1.c: New test.
* gcc.dg/plugin/diagnostic-test-paths-2.c: New test.
* gcc.dg/plugin/diagnostic-test-paths-3.c: New test.
* gcc.dg/plugin/diagnostic-test-paths-4.c: New test.
* gcc.dg/plugin/diagnostic_plugin_test_paths.c: New.
* gcc.dg/plugin/plugin.exp: Add the new plugin and test cases.
libcpp/ChangeLog:
* include/line-map.h (class diagnostic_path): New forward decl.
(rich_location::get_path): New accessor.
(rich_location::set_path): New function.
(rich_location::m_path): New field.
* line-map.c (rich_location::rich_location): Initialize m_path.
From-SVN: r280142
libcpp's label_text class wraps a text buffer, along with a flag to
determine if it "owns" the buffer.
The existing ctor exposed this directly, but I found it difficult
to remember the sense of flag, so this patch hides the ctor, in
favor of static member functions "borrow" and "take", to make
the effect on ownership explicit in the name.
gcc/c-family/ChangeLog:
* c-format.c (range_label_for_format_type_mismatch::get_text):
Replace label_text ctor called with true with label_text::take.
gcc/c/ChangeLog:
* c-objc-common.c (range_label_for_type_mismatch::get_text):
Replace label_text ctor calls.
gcc/cp/ChangeLog:
* error.c (range_label_for_type_mismatch::get_text): Replace
label_text ctor calls with label_text::borrow.
gcc/ChangeLog:
* gcc-rich-location.c
(maybe_range_label_for_tree_type_mismatch::get_text): Replace
label_text ctor call with label_text::borrow.
* gcc-rich-location.h (text_range_label::get_text): Replace
label_text ctor called with false with label_text::borrow.
libcpp/ChangeLog:
* include/line-map.h (label_text::label_text): Make private.
(label_text::borrow): New.
(label_text::take): New.
(label_text::take_or_copy): New.
From-SVN: r279153
https://gcc.gnu.org/ml/gcc-patches/2019-10/msg01080.html
looking up a line map takes a non-constant line_maps object, which is confusing.
This makes the caching fields mutable, so permits a constant object, as one might expect for a lookup.
* include/line-map.h (struct maps_info_ordinary): Make cache
mutable.
(struct maps_info_macro): Likewise.
(LINEMAPS_CACHE): Remove non-ref accessor. Constify ref accessor.
(LINEMAPS_ORDINARY_CACHE, LINEMAPS_MACRO_CACHE): Likewise.
(LINEMAPS_ORDINARY_MAP_AT, LINEMAPS_MACRO_MAP_AT): Use
LINEMAPS_USED and LINEMAPS_MAP_AT.
(linemap_lookup): Constify line_map arg.
linemap.c (linemap_ordinary_map_lookup, linemap_macro_map_lookup):
Constify line_map arg.
From-SVN: r276994
PR c/89410 reports various issues with #line directives with very
large numbers; one of them is an ICE inside diagnostic-show-locus.c
when emitting a diagnostic at line 0xffffffff.
The issue is that the arithmetic in layout::calculate_line_spans to
determine if two line spans are sufficiently close to consolidate
was using the unsigned 32-bit linenum_type, which was overflowing
when comparing the line for the expanded location with those of
the location range (all on line 0xffffffff), leading to it
erroneously adding two spans for the same line, leading to an
assertion failure.
This patch fixes the ICE by generalizing the use of long long in
line-map.h's comparison function for linenum_type into a new
linenum_arith_t typedef, and using it here.
Doing so uncovered a second problem: the loop to print the lines
within the line_span for this case is infinite: looping from
0xfffffff upwards, overflowing to 0, and then never becoming
greater than 0xfffffff. The patch fixes this by using linenum_arith_t
there also.
gcc/ChangeLog:
PR c/89410
* diagnostic-show-locus.c (layout::calculate_line_spans): Use
linenum_arith_t when determining if two adjacent line spans are
close enough to merge.
(diagnostic_show_locus): Use linenum_arith_t when iterating over
lines within each line_span.
gcc/testsuite/ChangeLog:
PR c/89410
* gcc.dg/pr89410-1.c: New test.
* gcc.dg/pr89410-2.c: New test.
libcpp/ChangeLog:
PR c/89410
* include/line-map.h (linenum_arith_t): New typedef.
(compare): Use it.
From-SVN: r269050
https://gcc.gnu.org/ml/gcc-patches/2018-10/msg00623.html
* include/line-map.h (LINEMAPS_MACRO_LOWEST_LOCATION): Fix
off-by-one error.
* line-map.c (linemap_enter_macro): Use RAII. Clear all of the
macro_locations.
From-SVN: r265037
This patch updates the pure virtual function range_label::get_text
(and its implementations) so that the index of the range is passed
in, allowing for one label instance to be shared by multiple ranges.
gcc/c-family/ChangeLog:
* c-format.c (range_label_for_format_type_mismatch::get_text):
Update for new param.
gcc/c/ChangeLog:
* c-objc-common.c (range_label_for_type_mismatch::get_text):
Update for new param.
* c-typeck.c (maybe_range_label_for_tree_type_mismatch::get_text):
Likewise.
gcc/cp/ChangeLog:
* error.c (range_label_for_type_mismatch::get_text): Update for
new param.
gcc/ChangeLog:
* diagnostic-show-locus.c (class layout_range): Add field
"m_original_idx".
(layout_range::layout_range): Add "original_idx" param and use it
to initialize new field.
(make_range): Use 0 for original_idx.
(layout::layout): Pass in index to calls to
maybe_add_location_range.
(layout::maybe_add_location_range): Add param "original_idx" and
pass it on to layout_range.
(layout::print_any_labels): Pass on range->m_original_idx to
get_text call.
(gcc_rich_location::add_location_if_nearby): Use 0 for
original_idx.
* gcc-rich-location.h (text_range_label::get_text): Update for new
param.
(range_label_for_type_mismatch::get_text): Likewise.
libcpp/ChangeLog:
* include/line-map.h (range_label::get_text): Add param
"range_idx".
From-SVN: r264376
This patch tweaks maybe_add_include_fixit so that if we're emitting a note
about adding the header file, the note's primary location will be replaced
by that of the fix-it hint, to avoid repeating a location we've already
emitted (or one close to it).
For example, this simplifies:
../x86_64-pc-linux-gnu/libstdc++-v3/include/vector:87:27: error: msg 1
87 | using vector = std::vector<_Tp, polymorphic_allocator<_Tp>>;
| ^~~~~~
../x86_64-pc-linux-gnu/libstdc++-v3/include/vector:87:22: note: msg 2
73 | # include <debug/vector>
+++ |+#include <vector>
74 | #endif
....
87 | using vector = std::vector<_Tp, polymorphic_allocator<_Tp>>;
| ^~~
to:
../x86_64-pc-linux-gnu/libstdc++-v3/include/vector:87:27: error: msg 1
87 | using vector = std::vector<_Tp, polymorphic_allocator<_Tp>>;
| ^~~~~~
../x86_64-pc-linux-gnu/libstdc++-v3/include/vector:74:1: note: msg 2
73 | # include <debug/vector>
+++ |+#include <vector>
74 | #endif
eliminating the repetition of line 87 in the note.
Doing so requires converting show_caret_p to a tri-state, to avoid
meaninglessly printing a caret for the first column in the next line
(and colorizing it):
../x86_64-pc-linux-gnu/libstdc++-v3/include/vector:74:1: note: msg 2
73 | # include <debug/vector>
+++ |+#include <vector>
74 | #endif
| ^
gcc/c-family/ChangeLog:
PR 87091
* c-common.c (c_cpp_error): Update for conversion of show_caret_p
to a tri-state.
(maybe_suggest_missing_token_insertion): Likewise.
(maybe_add_include_fixit): Add param "override_location". If set,
and source-printing is enabled, then override the rich_location's
primary location with that of the insertion point for the fix-it
hint, marking it with SHOW_LINES_WITHOUT_RANGE.
* c-common.h (extern void maybe_add_include_fixit): Add bool
param.
* c-format.c (selftest::test_type_mismatch_range_labels): Update
for conversion of show_caret_p to a tri-state.
* c-warn.c (warn_for_restrict): Likewise.
* known-headers.cc
(suggest_missing_header::~suggest_missing_header): Update call to
maybe_add_include_fixit to suggest overriding the location, as it
is for a note.
gcc/c/ChangeLog:
PR 87091
* c-decl.c (implicitly_declare): Update call to
maybe_add_include_fixit to suggest overriding the location, as it
is for a note.
* c-objc-common.c (c_tree_printer): Update for conversion of
show_caret_p to a tri-state.
gcc/cp/ChangeLog:
PR 87091
* decl.c (grokdeclarator): Update for conversion of show_caret_p
to a tri-state.
* error.c (cp_printer): Likewise.
* name-lookup.c (maybe_suggest_missing_std_header): Update call to
maybe_add_include_fixit to suggest overriding the location, as it
is for a note.
* parser.c (cp_parser_string_literal): Update for conversion of
show_caret_p to a tri-state.
(cp_parser_elaborated_type_specifier): Likewise.
(set_and_check_decl_spec_loc): Likewise.
* pt.c (listify): Update call to maybe_add_include_fixit to not
override the location, as it is for an error.
* rtti.c (typeid_ok_p): Likewise.
gcc/ChangeLog:
PR 87091
* diagnostic-show-locus.c (class layout_range): Update for
conversion of show_caret_p to a tri-state.
(layout_range::layout_range): Likewise.
(make_range): Likewise.
(layout::maybe_add_location_range): Likewise.
(layout::should_print_annotation_line_p): Don't show annotation
lines for ranges that are SHOW_LINES_WITHOUT_RANGE.
(layout::get_state_at_point): Update for conversion of
show_caret_p to a tri-state. Bail out early for
SHOW_LINES_WITHOUT_RANGE, so that such ranges don't affect
underlining or source colorization.
(gcc_rich_location::add_location_if_nearby): Update for conversion
of show_caret_p to a tri-state.
(selftest::test_one_liner_multiple_carets_and_ranges): Likewise.
(selftest::test_one_liner_fixit_replace_equal_secondary_range):
Likewise.
(selftest::test_one_liner_labels): Likewise.
* gcc-rich-location.c (gcc_rich_location::add_expr): Update for
conversion of show_caret_p to a tri-state.
* pretty-print.c (text_info::set_location): Likewise.
* pretty-print.h (text_info::set_location): Likewise.
* substring-locations.c (format_warning_n_va): Likewise.
* tree-diagnostic.c (default_tree_printer): Likewise.
* tree-pretty-print.c (newline_and_indent): Likewise.
gcc/fortran/ChangeLog:
PR 87091
* error.c (gfc_format_decoder): Update for conversion of
show_caret_p to a tri-state.
gcc/testsuite/ChangeLog:
PR 87091
* gcc.dg/empty.h: New file.
* gcc.dg/fixits-pr84852-1.c: Update for move of fix-it hint to
top of file and removal of redundant second printing of warning
location.
* gcc.dg/fixits-pr84852-2.c: Likewise.
* gcc.dg/missing-header-fixit-3.c: Likewise.
* gcc.dg/missing-header-fixit-4.c: New test.
* gcc.dg/plugin/diagnostic_plugin_test_show_locus.c: Update for
conversion of show_caret_p to a tri-state.
libcpp/ChangeLog:
PR 87091
* include/line-map.h (enum range_display_kind): New enum.
(struct location_range): Replace field "m_show_caret_p" with
"m_range_display_kind", converting from bool to the new enum.
(class rich_location): Add example of line insertion fix-it hint.
(rich_location::add_range): Convert param "show_caret_p" from bool
to enum range_display_kind and rename to "range_display_kind",
giving it a default of SHOW_RANGE_WITHOUT_CARET.
(rich_location::set_range): Likewise, albeit without a default.
* line-map.c (rich_location::rich_location): Update for conversion
of show_caret_p to tri-state enum.
(rich_location::add_range): Likewise.
(rich_location::set_range): Likewise.
From-SVN: r263885
This patch adds the ability to label source ranges within a rich_location,
to be printed by diagnostic_show_locus.
For example:
pr69554-1.c:11:18: error: invalid operands to binary + (have 'const char *' and 'const char *')
11 | return (p + 1) + (q + 1);
| ~~~~~~~ ^ ~~~~~~~
| | |
| | const char *
| const char *
The patch implements labels for various type mismatch errors in the C and
C++ frontends, and in -Wformat. I implemented it wherever accurate location
information was guaranteed (there are other places that could benefit, but
we need better location information in those places).
The labels can be disabled via -fno-diagnostics-show-labels.
Similarly:
param-type-mismatch.C: In function 'int test_1(int, int, float)':
param-type-mismatch.C:11:27: error: invalid conversion from 'int' to 'const char*' [-fpermissive]
11 | return callee_1 (first, second, third);
| ^~~~~~
| |
| int
param-type-mismatch.C:7:43: note: initializing argument 2 of 'int callee_1(int, const char*, float)'
7 | extern int callee_1 (int one, const char *two, float three);
| ~~~~~~~~~~~~^~~
where the first "error" describing the bad argument gets a label
describing the type inline (since it's non-obvious from "second").
The "note" describing the type of the param of the callee *doesn't*
get a label, since that information is explicit there in the
source ("const char *two").
The idea is that in any diagnostic where two aspects of the source aren't
in sync it ought to be easier for the user if we directly show them the
mismatching aspects inline (e.g. types).
As well as type mismatch errors, perhaps labels could also be used for
buffer overflow warnings, for describing the capacity of the destination
buffer vs the size of what's being written:
sprintf (buf, "filename: %s\n", file);
^~~ ~~~~~~~~~~~^~~
| |
capacity: 32 10 + strlen(file) + 2
or somesuch. Another idea might be for macro expansion warnings:
warning: repeated side effects in macro expansion...
x = MIN (p++, q++);
~~~~^~~~~~~~~~
note: ...expanded here as
#define MIN(X,Y) (X<Y?X:Y)
^~~ ~ ~ ~ ~ ~ ~
| | | | | |
| | | | | q++
| | | | p++
| | | q++
| q++ p++
p++
The patch removes some logic from multiline.exp which special-cased
lines ending with a '|' character (thus complicating testing of this
patch). I believe that this was a vestige from experiments I did to
support strippng dg directives from the output; it was present in the
earliest version of multiline.exp I posted:
"[RFC, stage1] Richer source location information for gcc 6 (location ranges etc)"
https://gcc.gnu.org/ml/gcc-patches/2015-03/msg00837.html
and I believe was neved used.
gcc/c-family/ChangeLog:
* c-format.c: Include "selftest-diagnostic.h" and
"gcc-rich-location.h".
(format_warning_at_char): Pass NULL for new label params of
format_warning_va.
(class indirection_suffix): New class.
(class range_label_for_format_type_mismatch): New class.
(format_type_warning): Move logic for generating "*" suffix to
class indirection_suffix. Create "fmt_label" and "param_label"
to show their types, and pass them to the
format_warning_at_substring calls.
(selftest::test_type_mismatch_range_labels): New test.
(selftest::c_format_c_tests): Call it.
gcc/c/ChangeLog:
* c-objc-common.c: Include "gcc-rich-location.h".
(c_tree_printer): Move implemenation of '%T' to...
(print_type): ...this new function.
(range_label_for_type_mismatch::get_text): New function.
* c-typeck.c (convert_for_assignment): Add type labels to the rhs
range for the various ic_argpass cases.
(class maybe_range_label_for_tree_type_mismatch): New class.
(build_binary_op): Use it when calling binary_op_error.
gcc/cp/ChangeLog:
* call.c: Include "gcc-rich-location.h".
(convert_like_real): Add range label for "invalid conversion"
diagnostic.
(perform_implicit_conversion_flags): Add type label to the
"could not convert" error.
* error.c: Include "gcc-rich-location.h".
(range_label_for_type_mismatch::get_text): New function.
* typeck.c (convert_for_assignment): Add type label to
the "cannot convert" error if a location is available.
gcc/ChangeLog:
* common.opt (fdiagnostics-show-labels): New option.
* diagnostic-show-locus.c (class layout_range): Add field
"m_label".
(class layout): Add field "m_show_labels_p".
(layout_range::layout_range): Add param "label" and use it to
initialize m_label.
(make_range): Pass in NULL for new "label" param of layout_range's
ctor.
(layout::layout): Initialize m_show_labels_p.
(layout::maybe_add_location_range): Pass in loc_range->m_label
when constructing layout_range instances.
(struct line_label): New struct.
(layout::print_any_labels): New member function.
(layout::print_line): Call it if label-printing is enabled.
(selftest::test_one_liner_labels): New test.
(selftest::test_diagnostic_show_locus_one_liner): Call it.
* diagnostic.c (diagnostic_initialize): Initialize
context->show_labels_p.
* diagnostic.h (struct diagnostic_context): Add field
"show_labels_p".
* doc/invoke.texi (Diagnostic Message Formatting Options): Add
-fno-diagnostics-show-labels.
* dwarf2out.c (gen_producer_string): Add
OPT_fdiagnostics_show_labels to the ignored options.
* gcc-rich-location.c (gcc_rich_location::add_expr): Add "label"
param.
(gcc_rich_location::maybe_add_expr): Likewise.
* gcc-rich-location.h (gcc_rich_location::gcc_rich_location): Add
label" param, defaulting to NULL.
(gcc_rich_location::add_expr): Add "label" param.
(gcc_rich_location::maybe_add_expr): Likewise.
(class text_range_label): New class.
(class range_label_for_type_mismatch): New class.
* gimple-ssa-sprintf.c (fmtwarn): Pass NULL for new label params
of format_warning_va.
(fmtwarn_n): Likewise for new params of format_warning_n_va.
* lto-wrapper.c (merge_and_complain): Add
OPT_fdiagnostics_show_labels to the "pick one setting" options.
(append_compiler_options): Likewise to the dropped options.
(append_diag_options): Likewise to the passed-on options.
* opts.c (common_handle_option): Handle the new option.
* selftest-diagnostic.c
(test_diagnostic_context::test_diagnostic_context): Enable
show_labels_p.
* substring-locations.c: Include "gcc-rich-location.h".
(format_warning_n_va): Add "fmt_label" and "param_label" params
and use them as appropriate.
(format_warning_va): Add "fmt_label" and "param_label" params,
passing them on to format_warning_n_va.
(format_warning_at_substring): Likewise.
(format_warning_at_substring_n): Likewise.
* substring-locations.h (format_warning_va): Add "fmt_label" and
"param_label" params.
(format_warning_n_va): Likewise.
(format_warning_at_substring): Likewise.
(format_warning_at_substring_n): Likewise.
* toplev.c (general_init): Initialize global_dc->show_labels_p.
gcc/testsuite/ChangeLog:
* g++.dg/diagnostic/aka3.C: New test.
* g++.dg/diagnostic/param-type-mismatch-2.C: Update expected
output to show range labels.
* g++.dg/diagnostic/param-type-mismatch.C: Likewise.
* g++.dg/plugin/plugin.exp (plugin_test_list): Add...
* g++.dg/plugin/show-template-tree-color-labels.C: New test.
* gcc.dg/bad-binary-ops.c: Update expected output to show range
labels. Add an "aka" example.
* gcc.dg/cpp/pr66415-1.c: Update expected output to show range
labels.
* gcc.dg/format/diagnostic-ranges.c: Likewise.
* gcc.dg/format/pr72858.c: Likewise.
* gcc.dg/format/pr78498.c: Likewise.
* gcc.dg/param-type-mismatch.c: Add "-Wpointer-sign" to options.
Update expected output to show range labels. Add examples of
-Wincompatible-pointer-types and -Wpointer-sign for parameters.
* gcc.dg/plugin/diagnostic-test-show-locus-bw-line-numbers.c:
Update expected output to show range labels.
* gcc.dg/plugin/diagnostic-test-show-locus-bw.c: Likewise.
(test_very_wide_line): Adjust so that label is at left-clipping
boundary.
(test_very_wide_line_2): New test.
* gcc.dg/plugin/diagnostic-test-show-locus-color-line-numbers.c:
Update expected output to show range labels.
* gcc.dg/plugin/diagnostic-test-show-locus-color.c: Likewise.
* gcc.dg/plugin/diagnostic-test-show-locus-no-labels.c: New test.
* gcc.dg/plugin/diagnostic_plugin_show_trees.c (show_tree): Update
for new param to gcc_rich_location::add_expr.
* gcc.dg/plugin/diagnostic_plugin_test_show_locus.c (add_range):
Add "label" param.
(test_show_locus): Add examples of labels to various tests. Tweak
the "very wide_line" test case and duplicate it, to cover the
boundary values for clipping of labels against the left-margin.
* gcc.dg/plugin/plugin.exp (plugin_test_list): Add
diagnostic-test-show-locus-no-labels.c.
* gcc.dg/pr69554-1.c: Update expected output to show range labels.
Update line numbers of dg-locus directives.
* gcc.dg/pr69627.c: Update expected output to show range labels.
* lib/multiline.exp (proc _build_multiline_regex): Remove
special-case handling of lines with trailing '|'.
libcpp/ChangeLog:
* include/line-map.h (struct location_range): Add "m_label" field.
(class rich_location): Add description of labels to leading
comment.
(rich_location::rich_location): Add "label" param, defaulting to
NULL.
(rich_location::add_range): Likewise.
(struct label_text): New struct.
(class range_label): New abstract base class.
* line-map.c (rich_location::rich_location): Add "label" param;
use it.
(rich_location::add_range): Likewise.
From-SVN: r263564
PR c/84852 reports an ICE inside diagnostic_show_locus when printing
a diagnostic for a source file with a #line >= 2^31:
#line 7777777777
int foo (void) { return strlen(""); }
where we're attempting to print a fix-it hint at the top of the file
and underline the "strlen" (two "line spans").
The
#line 7777777777
won't fix within the 32-bit linenum_type, and is truncated from
0x1cf977871
to
0xcf977871
i.e. 3482810481 in decimal.
Such a #line is reported by -pedantic and -pedantic-errors, but we
shouldn't ICE.
The ICE is an assertion failure within layout::calculate_line_spans,
where the line spans have not been properly sorted.
The layout_ranges are stored as int, rather than linenum_type,
giving line -812156815 for the error, and line 1 for the fix-it hint.
However, line_span uses linenum_type rather than int.
line_span::comparator compares these values as int, and hence
decides that (linenum_type)3482810481 aka (int)-812156815 is less
than line 1.
This leads to this assertion failing in layout::calculate_line_spans:
1105 gcc_assert (next->m_first_line >= current->m_first_line);
since it isn't the case that 1 >= 3482810481.
The underlying problem is the mix of types for storing line numbers:
in parts of libcpp and diagnostic-show-locus.c we use linenum_type;
in other places (including libcpp's expanded_location) we use int.
I looked at using linenum_type throughout, but doing so turned into
a large patch, so this patch fixes the ICE in a less invasive way
by merely using linenum_type more consistently just within
diagnostic-show-locus.c, and fixing line_span::comparator to properly
handle line numbers (and line number differences) >= 2^31, by using
a new helper function for linenum_type differences, computing the
difference using long long, and using the sign of the difference
(as the difference might not fit in the "int" return type imposed
by qsort).
gcc/ChangeLog:
PR c/84852
* diagnostic-show-locus.c (class layout_point): Convert m_line
from int to linenum_type.
(line_span::comparator): Use linenum "compare" function when
comparing line numbers.
(test_line_span): New function.
(layout_range::contains_point): Convert param "row" from int to
linenum_type.
(layout_range::intersects_line_p): Likewise.
(layout::will_show_line_p): Likewise.
(layout::print_source_line): Likewise.
(layout::should_print_annotation_line_p): Likewise.
(layout::print_annotation_line): Likewise.
(layout::print_leading_fixits): Likewise.
(layout::annotation_line_showed_range_p): Likewise.
(struct line_corrections): Likewise for field m_row.
(line_corrections::line_corrections): Likewise for param "row".
(layout::print_trailing_fixits): Likewise.
(layout::get_state_at_point): Likewise.
(layout::get_x_bound_for_row): Likewise.
(layout::print_line): Likewise.
(diagnostic_show_locus): Likewise for locals "last_line" and
"row".
(selftest::diagnostic_show_locus_c_tests): Call test_line_span.
* input.c (selftest::test_linenum_comparisons): New function.
(selftest::input_c_tests): Call it.
* selftest.c (selftest::test_assertions): Test ASSERT_GT,
ASSERT_GT_AT, ASSERT_LT, and ASSERT_LT_AT.
* selftest.h (ASSERT_GT): New macro.
(ASSERT_GT_AT): New macro.
(ASSERT_LT): New macro.
(ASSERT_LT_AT): New macro.
gcc/testsuite/ChangeLog:
PR c/84852
* gcc.dg/fixits-pr84852-1.c: New test.
* gcc.dg/fixits-pr84852-2.c: New test.
libcpp/ChangeLog:
* include/line-map.h (compare): New function on linenum_type.
From-SVN: r258526
PR c/82050 reports a failed assertion deep within diagnostic_show_locus's
code for printing fix-it hints.
The root cause is a fix-it hint suggesting a textual replacement,
where the affected column numbers straddle the LINE_MAP_MAX_COLUMN_NUMBER
boundary, so that the start of the range has a column number, but the
end of the range doesn't.
The fix is to verify that the column numbers are sane when adding fix-it
hints to a rich_location, rejecting fix-it hints where they are not.
libcpp/ChangeLog:
PR c/82050
* include/line-map.h (LINE_MAP_MAX_COLUMN_NUMBER): Move here.
* line-map.c (LINE_MAP_MAX_COLUMN_NUMBER): ...from here.
(rich_location::maybe_add_fixit): Reject fix-it hints in which
the start column exceeds the next column.
From-SVN: r255214
The description of our 1-based column-numbering convention was in
a non-obvious place withn line-map.h; this patch moves it to the top
of that header.
libcpp/ChangeLog:
* include/line-map.h (linenum_type): Move this typedef and the
comment describing column numbering to near the top of the file.
From-SVN: r254703
gcc/ChangeLog:
PR c++/79300
* diagnostic-show-locus.c (layout::layout): Use start and finish
spelling location for the start and finish of each range.
* genmatch.c (linemap_client_expand_location_to_spelling_point):
Add unused aspect param.
* input.c (expand_location_1): Add "aspect" param, and use it
to access the correct part of the location.
(expand_location): Pass LOCATION_ASPECT_CARET to new param of
expand_location_1.
(expand_location_to_spelling_point): Likewise.
(linemap_client_expand_location_to_spelling_point): Add "aspect"
param, and pass it to expand_location_1.
gcc/testsuite/ChangeLog:
PR c++/79300
* c-c++-common/Wmisleading-indentation-3.c (fn_14): Update
expected underlining within macro expansion.
* c-c++-common/pr70264.c: Likewise.
* g++.dg/plugin/diagnostic-test-expressions-1.C
(test_within_macro_1): New test.
(test_within_macro_2): Likewise.
(test_within_macro_3): Likewise.
(test_within_macro_4): Likewise.
* gcc.dg/format/diagnostic-ranges.c (test_macro_3): Update
expected underlining within macro expansion.
(test_macro_4): Likewise.
* gcc.dg/plugin/diagnostic-test-expressions-1.c
(test_within_macro_1): New test.
(test_within_macro_2): Likewise.
(test_within_macro_3): Likewise.
(test_within_macro_4): Likewise.
* gcc.dg/spellcheck-fields-2.c (test_macro): Update expected
underlining within macro expansion.
libcpp/ChangeLog:
PR c++/79300
* include/line-map.h (enum location_aspect): New enum.
(linemap_client_expand_location_to_spelling_point): Add
enum location_aspect param.
* line-map.c (rich_location::get_expanded_location): Update for
new param of linemap_client_expand_location_to_spelling_point.
(rich_location::maybe_add_fixit): Likewise.
(fixit_hint::affects_line_p): Likewise.
From-SVN: r250022