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
libcpp:
2018-07-18 Bernd Edlinger <bernd.edlinger@hotmail.de>
PR 69558
* macro.c (enter_macro_context): Change the location info for builtin
macros and _Pragma from location of the closing parenthesis to location
of the macro expansion point.
testsuite:
2018-07-18 Bernd Edlinger <bernd.edlinger@hotmail.de>
PR 69558
* c-c++-common/cpp/diagnostic-pragma-2.c: New test.
* c-c++-common/pr69558.c: Remove xfail.
* gcc.dg/cpp/builtin-macro-1.c: Adjust test expectations.
* gcc.dg/pr61817-1.c: Likewise.
* gcc.dg/pr61817-2.c: Likewise.
* g++.dg/plugin/pragma_plugin.c: Warn at expansion_point_location.
From-SVN: r262861
* lex.c (_cpp_lex_direct): Use CPP_DL_NOTE instead of CPP_DL_PEDWARN,
CPP_DL_WARNING or CPP_DL_ERROR for note that diagnostics for C++ style
comments is reported only once per file and guard those calls on the
preceding cpp_error returning true.
* gcc.dg/cpp/pr61854-c90.c (foo): Expect a note, rather than error.
* gcc.dg/cpp/pr61854-c94.c (foo): Likewise.
* gcc.dg/cpp/pr61854-4.c (foo): Likewise.
* gcc.dg/cpp/pr61854-8.c: New test.
From-SVN: r262832
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
gcc/testsuite:
PR preprocessor/84517
* g++.dg/cpp0x/udlit-macros.C: Expect a warning for ""__FILE__.
libcpp:
PR preprocessor/84517
* lex.c (is_macro_not_literal_suffix): New function.
(lex_raw_string, lex_string): Use is_macro_not_literal_suffix to
decide when to issue -Wliteral-suffix warnings.
From-SVN: r258069
PR preprocessor/83708
* macro.c (vaopt_state): Reorder m_last_was_paste before m_state.
(vaopt_state::vaopt_state): Adjust.
(vaopt_state::update_flags): Add BEGIN and END.
(vaopt_state::update): Return them.
(copy_paste_flag): Factor out of replace_args.
(last_token_is): New.
(replace_args): Handle BEGIN and END. Avoid padding there.
(tokens_buff_last_token_ptr): Return NULL if no tokens.
Co-Authored-By: Jakub Jelinek <jakub@redhat.com>
From-SVN: r257696
PR preprocessor/69869
* traditional.c (skip_macro_block_comment): Return bool, true if
the macro block comment is unterminated.
(copy_comment): Use return value from skip_macro_block_comment instead
of always false.
* gcc.dg/cpp/trad/pr69869.c: New test.
From-SVN: r257220
* c-cppbuiltin.c (c_cpp_builtins): Use ggc_strdup for the fp_suffix
argument.
(LAZY_HEX_FP_VALUES_CNT): Define.
(lazy_hex_fp_values): Allow up to LAZY_HEX_FP_VALUES_CNT lazy hex fp
values rather than just 12.
(builtin_define_with_hex_fp_value): Likewise.
* include/cpplib.h (enum cpp_builtin_type): Change BT_LAST_USER from
BT_FIRST_USER + 31 to BT_FIRST_USER + 63.
From-SVN: r257118
This commit adds the -fmacro-prefix-map option that allows remapping of file
names in __FILE__, __BASE_FILE__, and __builtin_FILE(), similar to how
-fdebug-prefix-map allows to do the same for debug information.
Additionally, it adds -ffile-prefix-map which can be used to specify both
mappings with a single option (and, should we need to add more -f*-prefix-map
options in the future, those as well).
libcpp/ChangeLog:
2018-01-18 Boris Kolpackov <boris@codesynthesis.com>
PR other/70268
* include/cpplib.h (cpp_callbacks::remap_filename): New callback.
* libcpp/macro.c (_cpp_builtin_macro_text): Call remap_filename for
__FILE__ and __BASE_FILE__.
gcc/ChangeLog:
2018-01-18 Boris Kolpackov <boris@codesynthesis.com>
PR other/70268
* common.opt: (-ffile-prefix-map): New option.
* opts.c (common_handle_option): Defer it.
* opts-global.c (handle_common_deferred_options): Handle it.
* debug.h (remap_debug_filename, add_debug_prefix_map): Move to...
* file-prefix-map.h: New file.
(remap_debug_filename, add_debug_prefix_map): ...here.
(add_macro_prefix_map, add_file_prefix_map, remap_macro_filename): New.
* final.c (debug_prefix_map, add_debug_prefix_map
remap_debug_filename): Move to...
* file-prefix-map.c: New file.
(file_prefix_map, add_prefix_map, remap_filename) ...here and rename,
generalize, get rid of alloca(), use strrchr() instead of strchr().
(add_macro_prefix_map, add_debug_prefix_map, add_file_prefix_map):
Implement in terms of add_prefix_map().
(remap_macro_filename, remap_debug_filename): Implement in term of
remap_filename().
* Makefile.in (OBJS, PLUGIN_HEADERS): Add new files.
* builtins.c (fold_builtin_FILE): Call remap_macro_filename().
* dbxout.c: Include file-prefix-map.h.
* varasm.c: Likewise.
* vmsdbgout.c: Likewise.
* xcoffout.c: Likewise.
* dwarf2out.c: Likewise plus omit new options from DW_AT_producer.
* doc/cppopts.texi (-fmacro-prefix-map): Document.
* doc/invoke.texi (-ffile-prefix-map): Document.
(-fdebug-prefix-map): Update description.
gcc/c-family/ChangeLog:
2018-01-18 Boris Kolpackov <boris@codesynthesis.com>
PR other/70268
* c-family/c.opt (-fmacro-prefix-map): New option.
* c-family/c-opts.c (c_common_handle_option): Handle it.
* c-family/c-lex.c (init_c_lex): Set remap_filename cpp callback.
* c-family/c-ppoutput.c (init_pp_output): Likewise.
gcc/testsuite/ChangeLog:
2018-01-18 Boris Kolpackov <boris@codesynthesis.com>
PR other/70268
* c-c++-common/ffile-prefix-map.c: New test.
* c-c++-common/fmacro-prefix-map.c: New test.
* c-c++-common/cpp/ffile-prefix-map.c: New test.
* c-c++-common/cpp/fmacro-prefix-map.c: New test.
From-SVN: r256847
libcpp/
* expr.c (interpret_float_suffix): Ignore 'i' in C++14 and up.
(interpret_int_suffix): Likewise.
gcc/cp/
* parser.c (cp_parser_userdef_numeric_literal): Be helpful about
'i' in C++14 and up.
From-SVN: r255335
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
libcpp/ChangeLog:
2017-03-24 Eric Gallager <egall@gwmail.gwu.edu>
PR preprocessor/81794
* macro.c (check_trad_stringification): Have warning be controlled
by -Wtraditional.
gcc/testsuite/ChangeLog:
2017-09-17 Eric Gallager <egall@gwmail.gwu.edu>
PR preprocessor/81794
* gcc.dg/pragma-diag-7.c: Update to include check for
stringification.
From-SVN: r254981
This patch uses the name_hint/deferred_diagnostic to provide
a message in the C++ frontend if a macro is used before it is defined
e.g.:
test.c:6:24: error: expected ';' at end of member declaration
virtual void clone() const OVERRIDE { }
^~~~~
;
test.c:6:30: error: 'OVERRIDE' does not name a type
virtual void clone() const OVERRIDE { }
^~~~~~~~
test.c:6:30: note: the macro 'OVERRIDE' had not yet been defined
test.c:15:0: note: it was later defined here
#define OVERRIDE override
It's possible to do it from the C++ frontend as tokenization happens
up-front (and hence the macro already exists when the above is parsed);
I attempted to do it from the C frontend, but because the C frontend only
tokenizes on-demand during parsing, the macro isn't known about until
later.
gcc/cp/ChangeLog:
PR c++/72786
* name-lookup.c (class macro_use_before_def): New class.
(lookup_name_fuzzy): Detect macro that were used before being
defined, and report them as such.
gcc/ChangeLog:
PR c++/72786
* spellcheck.h (best_match::blithely_get_best_candidate): New
accessor.
gcc/testsuite/ChangeLog:
PR c++/72786
* g++.dg/spellcheck-macro-ordering-2.C: New test case.
* g++.dg/spellcheck-macro-ordering.C: Add dg-message directives
for macro used-before-defined.
libcpp/ChangeLog:
PR c++/72786
* include/cpplib.h (cpp_macro_definition_location): New decl.
* macro.c (cpp_macro_definition): New function.
From-SVN: r254978
This implements __VA_OPT__, a new preprocessor feature added in C++2A.
The paper can be found here:
http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2017/p0306r4.html
gcc/ChangeLog
* doc/cpp.texi (Variadic Macros): Document __VA_OPT__.
gcc/testsuite/ChangeLog
* c-c++-common/cpp/va-opt-pedantic.c: New file.
* c-c++-common/cpp/va-opt.c: New file.
* c-c++-common/cpp/va-opt-error.c: New file.
libcpp/ChangeLog
* pch.c (cpp_read_state): Set n__VA_OPT__.
* macro.c (vaopt_state): New class.
(_cpp_arguments_ok): Check va_opt flag.
(replace_args, create_iso_definition): Use vaopt_state.
* lex.c (lex_identifier_intern): Possibly issue errors for
__VA_OPT__.
(lex_identifier): Likewise.
(maybe_va_opt_error): New function.
* internal.h (struct lexer_state) <va_args_ok>: Update comment.
(struct spec_nodes) <n__VA_OPT__>: New field.
* init.c (struct lang_flags) <va_opt>: New field.
(lang_defaults): Add entries for C++2A. Update all entries for
va_opt.
(cpp_set_lang): Initialize va_opt.
* include/cpplib.h (struct cpp_options) <va_opt>: New field.
* identifiers.c (_cpp_init_hashtable): Initialize n__VA_OPT__.
From-SVN: r254707
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
/libcpp
2017-11-06 Mukesh Kapoor <mukesh.kapoor@oracle.com>
PR c++/80955
* lex.c (lex_string): When checking for a valid macro for the
warning related to -Wliteral-suffix (CPP_W_LITERAL_SUFFIX),
check that the macro name does not start with an underscore
before calling is_macro().
/gcc/testsuite
2017-11-06 Mukesh Kapoor <mukesh.kapoor@oracle.com>
PR c++/80955
* g++.dg/cpp0x/udlit-macros.C: New.
From-SVN: r254443
Adding a fix-it hint currently involves changing e.g.:
error_at (token->location,
"unknown type name %qE; did you mean %qs?",
token->value, hint);
to:
gcc_rich_location richloc (token->location);
richloc.add_fixit_replace (hint);
error_at_rich_loc (&richloc,
"unknown type name %qE; did you mean %qs?",
token->value, hint);
to make the change from taking a location_t to a rich_location *.
This patch renames the "*_at_rich_loc" diagnostic entrypoints to use
the same function names for rich_location * as for location_t,
via overloading, to simplify the above change to just changing from:
error_at (token->location,
"unknown type name %qE; did you mean %qs?",
token->value, hint);
to:
gcc_rich_location richloc (token->location);
richloc.add_fixit_replace (hint);
error_at (&richloc,
"unknown type name %qE; did you mean %qs?",
token->value, hint);
thus saving space (and typing) and usually avoiding the need to reindent
the "error_at" invocation.
With this change, 0 is no longer acceptable as a location_t to these
entrypoints, as e.g.:
../../src/gcc/auto-profile.c:855:37: error: call of overloaded
'inform(int, const char [18])' is ambiguous
inform (0, "Not expected TAG.");
^
In file included from ../../src/gcc/auto-profile.c:35:0:
../../src/gcc/diagnostic-core.h:88:13: note: candidate:
'void inform(location_t, const char*, ...)'
extern void inform (location_t, const char *, ...) ATTRIBUTE_GCC_DIAG(2,3);
^~~~~~
../../src/gcc/diagnostic-core.h:89:13: note: candidate:
'void inform(rich_location*, const char*, ...)'
extern void inform (rich_location *, const char *, ...) ATTRIBUTE_GCC_DIAG(2,3);
^~~~~~
Such locations now need to be spelled out as UNKNOWN_LOCATION,
rather than 0.
I considered making the API take a rich_location & rather than a
rich_location *, but doing so would mean replacing
diagnostic_set_info
and
diagnostic_set_info_translated
with a constructor for diagnostic_info, which was a more invasive
change. Maybe in the future.
gcc/ChangeLog:
* auto-profile.c (autofdo_source_profile::read): Use
UNKNOWN_LOCATION rather than 0.
* diagnostic-core.h (warning_at_rich_loc): Rename to...
(warning_at): ...this overload.
(warning_at_rich_loc_n): Rename to...
(warning_n): ...this overload.
(error_at_rich_loc): Rename to...
(error_at): ...this overload.
(pedwarn_at_rich_loc): Rename to...
(pedwarn): ...this overload.
(permerror_at_rich_loc): Rename to...
(permerror): ...this overload.
(inform_at_rich_loc): Rename to...
(inform): ...this overload.
* diagnostic.c: (diagnostic_n_impl): Delete location_t-based decl.
(diagnostic_n_impl_richloc): Rename to...
(diagnostic_n_impl): ...this rich_location *-based decl.
(inform_at_rich_loc): Rename to...
(inform): ...this, and add an assertion.
(inform_n): Update for removal of location_t-based diagnostic_n_impl.
(warning_at_rich_loc): Rename to...
(warning_at): ...this, and add an assertion.
(warning_at_rich_loc_n): Rename to...
(warning_n): ...this, and add an assertion.
(warning_n): Update location_t-based implementation for removal of
location_t-based diagnostic_n_impl.
(pedwarn_at_rich_loc): Rename to...
(pedwarn): ...this, and add an assertion.
(permerror_at_rich_loc): Rename to...
(permerror): ...this, and add an assertion.
(error_n): Update for removal of location_t-based diagnostic_n_impl.
(error_at_rich_loc): Rename to...
(error_at): ...this, and add an assertion.
* gcc.c (do_spec_1): Use UNKNOWN_LOCATION rather than 0.
(driver::do_spec_on_infiles): Likewise.
* substring-locations.c (format_warning_va): Update for renaming
of inform_at_rich_loc.
gcc/c-family/ChangeLog:
* c-common.c (binary_op_error): Update for renaming of
error_at_rich_loc.
(c_parse_error): Likewise.
* c-warn.c (warn_logical_not_parentheses): Likewise for
renaming of inform_at_rich_loc.
(warn_for_restrict): Likewise for renaming of
warning_at_rich_loc_n.
gcc/c/ChangeLog:
* c-decl.c (implicit_decl_warning): Update for renaming of
pedwarn_at_rich_loc and warning_at_rich_loc.
(implicitly_declare): Likewise for renaming of inform_at_rich_loc.
(undeclared_variable): Likewise for renaming of error_at_rich_loc.
* c-parser.c (c_parser_declaration_or_fndef): Likewise.
(c_parser_struct_or_union_specifier): Likewise for renaming of
pedwarn_at_rich_loc.
(c_parser_parameter_declaration): Likewise for renaming of
error_at_rich_loc.
* c-typeck.c (build_component_ref): Likewise.
(build_unary_op): Likewise for renaming of inform_at_rich_loc.
(pop_init_level): Likewise for renaming of warning_at_rich_loc.
(set_init_label): Likewise for renaming of error_at_rich_loc.
gcc/cp/ChangeLog:
* class.c (explain_non_literal_class): Use UNKNOWN_LOCATION rather
than 0.
* name-lookup.c (suggest_alternatives_for): Update for renaming of
inform_at_rich_loc.
(maybe_suggest_missing_header): Likewise.
(suggest_alternative_in_explicit_scope): Likewise.
* parser.c (cp_parser_diagnose_invalid_type_name): Likewise for
renaming of error_at_rich_loc.
(cp_parser_string_literal): Likewise.
(cp_parser_nested_name_specifier_opt): Likewise.
(cp_parser_cast_expression): Likewise for renaming of
warning_at_rich_loc.
(cp_parser_decl_specifier_seq): Likewise for renaming of
error_at_rich_loc and warning_at_rich_loc.
(cp_parser_elaborated_type_specifier): Likewise for renaming of
pedwarn_at_rich_loc.
(cp_parser_cv_qualifier_seq_opt): Likewise for renaming of
error_at_rich_loc.
(cp_parser_virt_specifier_seq_opt): Likewise.
(cp_parser_class_specifier_1): Likewise.
(cp_parser_class_head): Likewise.
(cp_parser_member_declaration): Likewise for renaming of
pedwarn_at_rich_loc, warning_at_rich_loc, and error_at_rich_loc.
(cp_parser_enclosed_template_argument_list): Likewise for renaming
of error_at_rich_loc.
(set_and_check_decl_spec_loc): Likewise.
* pt.c (listify): Likewise.
* rtti.c (typeid_ok_p): Likewise.
* semantics.c (process_outer_var_ref): Use UNKNOWN_LOCATION rather
than 0.
* typeck.c (access_failure_info::maybe_suggest_accessor): Update
for renaming of inform_at_rich_loc.
(finish_class_member_access_expr): Likewise for renaming of
error_at_rich_loc.
gcc/objc/ChangeLog:
* objc-gnu-runtime-abi-01.c (objc_gnu_runtime_abi_01_init): Use
UNKNOWN_LOCATION rather than 0.
gcc/testsuite/ChangeLog:
* gcc.dg/plugin/diagnostic_plugin_show_trees.c (show_tree): Update
for renaming of error_at_rich_loc and inform_at_rich_loc.
* gcc.dg/plugin/diagnostic_plugin_test_show_locus.c
(test_show_locus): Likewise for renaming of warning_at_rich_loc.
libcpp/ChangeLog:
* directives.c (_cpp_handle_directive): Update for renaming of
cpp_error_at_richloc to cpp_error_at.
* errors.c (cpp_diagnostic_at_richloc): Rename to...
(cpp_diagnostic_at): ...this, dropping the location_t-based
implementation.
(cpp_diagnostic): Update for removal of location_t-based
cpp_diagnostic_at.
(cpp_error_at): Likewise.
(cpp_error_at_richloc): Rename to...
(cpp_error_at): ...this, and update for renaming of
cpp_diagnostic_at_richloc.
* include/cpplib.h (cpp_error_at_richloc): Rename to...
(cpp_error_at): ...this.
From-SVN: r254280
C17, a bug-fix version of the C11 standard with DR resolutions
integrated, will soon go to ballot. This patch adds corresponding
options -std=c17, -std=gnu17 (new default version, replacing
-std=gnu11 as the default), -std=iso9899:2017. As a bug-fix version
of the standard, there is no need for flag_isoc17 or any options for
compatibility warnings; however, there is a new __STDC_VERSION__
value, so new cpplib languages CLK_GNUC17 and CLK_STDC17 are added to
support using that new value with the new options. (If the standard
ends up being published in 2018 and being known as C18, option aliases
can be added. Note however that -std=iso9899:199409 corresponds to a
__STDC_VERSION__ value rather than a publication date.)
(There are a couple of DR resolutions needing implementing in GCC, but
that's independent of the new options.)
(I'd propose to add -std=c2x / -std=gnu2x / -Wc11-c2x-compat for the
next major C standard revision once there are actually C2x drafts
being issued with new features included.)
Bootstrapped with no regressions for x86_64-pc-linux-gnu.
gcc:
* doc/invoke.texi (C Dialect Options): Document -std=c17,
-std=iso9899:2017 and -std=gnu17.
* doc/standards.texi (C Language): Document C17 support.
* doc/cpp.texi (Overview): Mention -std=c17.
(Standard Predefined Macros): Document C11 and C17 values of
__STDC_VERSION__. Do not refer to C99 support as incomplete.
* doc/extend.texi (Inline): Do not list individual options for
standards newer than C99.
* dwarf2out.c (highest_c_language, gen_compile_unit_die): Handle
"GNU C17".
* config/rl78/rl78.c (rl78_option_override): Handle "GNU C17"
language name.
gcc/c-family:
* c.opt (std=c17, std=gnu17, std=iso9899:2017): New options.
* c-opts.c (set_std_c17): New function.
(c_common_init_options): Use gnu17 as default C version.
(c_common_handle_option): Handle -std=c17 and -std=gnu17.
gcc/testsuite:
* gcc.dg/c17-version-1.c, gcc.dg/c17-version-2.c: New tests.
libcpp:
* include/cpplib.h (enum c_lang): Add CLK_GNUC17 and CLK_STDC17.
* init.c (lang_defaults): Add GNUC17 and STDC17 data.
(cpp_init_builtins): Handle C17 value of __STDC_VERSION__.
From-SVN: r254216
* c-common.h (cxx_dialect): Add cxx2a as a dialect.
* opt.c: Add options for -std=c++2a and -std=gnu++2a.
* c-opts.c (set_std_cxx2a): New.
(c_common_handle_option): Set options when -std=c++2a is enabled.
(c_common_post_options): Adjust comments.
(set_std_cxx14, set_std_cxx17): Likewise.
* doc/cpp.texi (__cplusplus): Document value for -std=c++2a
or -std=gnu+2a.
* doc/invoke.texi: Document -std=c++2a and -std=gnu++2a.
* lib/target-supports.exp (check_effective_target_c++17): Return
1 also if check_effective_target_c++2a.
(check_effective_target_c++17_down): New.
(check_effective_target_c++2a_only): New.
(check_effective_target_c++2a): New.
* g++.dg/cpp2a/cplusplus.C: New.
* include/cpplib.h (c_lang): Add CXX2A and GNUCXX2A.
* init.c (lang_defaults): Add rows for CXX2A and GNUCXX2A.
(cpp_init_builtins): Set __cplusplus to 201709L for C++2a.
Co-Authored-By: Jakub Jelinek <jakub@redhat.com>
From-SVN: r252850
gcc/testsuite/ChangeLog:
PR c++/79300
* g++.dg/diagnostic/pr79300.C: New test case.
libcpp/ChangeLog:
PR c++/79300
* line-map.c (linemap_macro_loc_to_def_point): Preserve range
information for macro expansions by delaying resolving ad-hoc
locations until within the loop.
From-SVN: r250058
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
* line-map.c (location_adhoc_data_update): Perform addition in
uintptr_t type rather than char * type. Read *data using
ptrdiff_t type instead of int64_t.
(get_combined_adhoc_loc): Change offset type to ptrdiff_t from
int64_t.
From-SVN: r249446
Attempts to apply a removal or replacement fix-it hint to a source
range that covers multiple lines currently lead to nonsensical
results from the printing code in diagnostic-show-locus.c.
We were already filtering them out in edit-context.c (leading
to -fdiagnostics-generate-patch not generating any output for
the whole TU).
Reject attempts to add such fix-it hints within rich_location,
fixing the diagnostic-show-locus.c issue.
gcc/ChangeLog:
* diagnostic-show-locus.c
(selftest::test_fixit_deletion_affecting_newline): New function.
(selftest::diagnostic_show_locus_c_tests): Call it.
libcpp/ChangeLog:
* include/line-map.h (class rich_location): Document that attempts
to delete or replace a range *affecting* multiple lines will fail.
* line-map.c (rich_location::maybe_add_fixit): Implement this
restriction.
From-SVN: r249403
This patch adds a method:
rich_location::fixits_cannot_be_auto_applied
for ensuring that mutually-incompatible fix-its hints don't
lead to insane output from -fdiagnostics-generate-patch.
Fix-it hints within such rich_location instances are printed
as normal by diagnostic_show_locus, but don't affect the output
of -fdiagnostics-generate-patch.
gcc/ChangeLog:
* diagnostic.c (diagnostic_report_diagnostic): Only add fixits
to the edit_context if they can be auto-applied.
gcc/testsuite/ChangeLog:
* gcc.dg/plugin/diagnostic-test-show-locus-bw.c
(test_mutually_exclusive_suggestions): New test function.
* gcc.dg/plugin/diagnostic-test-show-locus-generate-patch.c
(test_mutually_exclusive_suggestions): New test function.
* gcc.dg/plugin/diagnostic-test-show-locus-parseable-fixits.c
(test_mutually_exclusive_suggestions): New test function.
* gcc.dg/plugin/diagnostic_plugin_test_show_locus.c
(test_show_locus): Add special-case for
"test_mutually_exclusive_suggestions".
libcpp/ChangeLog:
* include/line-map.h
(rich_location::fixits_cannot_be_auto_applied): New method.
(rich_location::fixits_can_be_auto_applied_p): New accessor.
(rich_location::m_fixits_cannot_be_auto_applied): New field.
* line-map.c (rich_location::rich_location): Initialize new field.
From-SVN: r249081
Previously fix-it hints couldn't contain newlines. This is
due to the need to print something user-readable for them
within diagnostic-show-locus, and for handling them within
edit-context for printing diffs and regenerating content.
This patch enables limited support for fix-it hints with newlines,
for suggesting adding new lines.
Such a fix-it hint must have exactly one newline character, at the
end of the content. It must be an insertion at the beginning of
a line (so that e.g. fix-its that split a pre-existing line are
still rejected).
They are printed by diagnostic-show-locus with a '+' in the
left-hand margin, like this:
test.c:42:4: note: suggest adding 'break;' here
+ break;
case 'b':
^~~~~~~~~
and the printer injects "spans" if the insertion location is not
near the primary range of the diagnostic e.g.:
test.c:4:2: note: unrecognized 'putchar'; suggest including '<stdio.h>'
test.c:1:1:
+#include <stdio.h>
test.c:4:2:
putchar (ch);
^~~~~~~
gcc/ChangeLog:
* diagnostic-show-locus.c
(layout::should_print_annotation_line_p): Make private.
(layout::print_annotation_line): Make private.
(layout::annotation_line_showed_range_p): Make private.
(layout::show_ruler): Make private.
(layout::print_source_line): Make private. Pass in line and
line_width, rather than calling location_get_source_line. Drop
returned value.
(layout::print_leading_fixits): New method.
(layout::print_any_fixits): Rename to...
(layout::print_trailing_fixits): ...this, and make private.
Don't print newline fixits.
(diagnostic_show_locus): Move logic for printing one row into...
(layout::print_line): ...this new function. Move the
location_get_source_line call and error-handling from
print_source_line to here. Call print_leading_fixits, and rename
print_any_fixits to print_trailing_fixits.
(selftest::test_fixit_insert_containing_newline): Update now that
newlines are partially supported.
(selftest::test_fixit_insert_containing_newline_2): New test.
(selftest::test_fixit_replace_containing_newline): Update comments.
(selftest::diagnostic_show_locus_c_tests): Call the new test.
* edit-context.c (class added_line): New class.
(class edited_line): Describe newline handling in comment.
(edited_line::actually_edited_p): New method.
(edited_line::print_content): Delete redundant decl.
(edited_line::m_predecessors): New field.
(edited_file::print_content): Call edited_line::print_content.
(edited_file::print_diff): Update to support newlines.
(edited_file::print_diff_hunk): Likewise.
(edited_file::print_run_of_changed_lines): New function.
(edited_file::print_diff_line): Convert to...
(print_diff_line): ...this.
(edited_file::get_effective_line_count): New function.
(edited_line::edited_line): Initialize new field m_predecessors.
(edited_line::~edited_line): Clean up m_predecessors.
(edited_line::apply_fixit): Handle newlines.
(edited_line::get_effective_line_count): New function.
(edited_line::print_content): New function.
(edited_line::print_diff_lines): New function.
(selftest::test_applying_fixits_insert_containing_newline): New
test.
(selftest::test_applying_fixits_replace_containing_newline): New
test.
(selftest::insert_line): New function.
(selftest::test_applying_fixits_multiple_lines): Add example of
inserting a line.
(selftest::edit_context_c_tests): Call the new tests.
gcc/testsuite/ChangeLog:
* gcc.dg/plugin/diagnostic-test-show-locus-bw.c
(test_fixit_insert_newline): New function.
* gcc.dg/plugin/diagnostic-test-show-locus-color.c
(test_fixit_insert_newline): New function.
* gcc.dg/plugin/diagnostic-test-show-locus-generate-patch.c
(test_fixit_insert_newline): New function.
* gcc.dg/plugin/diagnostic-test-show-locus-parseable-fixits.c
(test_fixit_insert_newline): New function.
* gcc.dg/plugin/diagnostic_plugin_test_show_locus.c
(test_show_locus): Handle test_fixit_insert_newline.
libcpp/ChangeLog:
* include/line-map.h (class rich_location): Update description of
newline handling.
(class fixit_hint): Likewise.
(fixit_hint::ends_with_newline_p): New decl.
* line-map.c (rich_location::maybe_add_fixit): Support newlines
in fix-it hints that are insertions of single lines at the start
of a line. Don't consolidate into such fix-it hints.
(fixit_hint::ends_with_newline_p): New method.
From-SVN: r247522
The original implementation of fix-it hints (r230674) had an abstract
base class "fixit_hint" and three subclasses, representing
each of insertions, replacements, and deletions.
Having multiple classes for fix-it hints was a nuisance, as it required
per-class logic everywhere that the hints were handled.
In r239632 I eliminated the deletion subclass in favor of replacement
with the empty string (two subclasses are easier than three).
This patch eliminates the class hierarchy altogether by implementing
insertion in terms of replacement, by representing replacements via
a half-open interval (so that for an insertion, start == next location,
and we're effectively replacing an empty range at the insertion point
with the new string).
This greatly simplifies the code for handling fix-it hints; for example
it allows removal of a parallel class hierarchy of line_event within
edit-context.c.
It also improves consolidation of hints: we can now consolidate
insertions at the same location, affecting a couple of tests
(selftest::test_one_liner_many_fixits and
gcc.dg/Wmissing-braces-fixits.c).
gcc/ChangeLog:
* diagnostic-show-locus.c (layout::get_expanded_location): Rewrite
to use new fixit_hint representation, using the "replace" logic.
(get_line_span_for_fixit_hint): Likewise.
(layout::print_any_fixits): Likewise.
(selftest::test_one_liner_many_fixits): Rename to...
(selftest::test_one_liner_many_fixits_1): ...this, and update
comment and expected output to reflect that the multiple fix-it
hints are now consolidated into one insertion.
(selftest::test_one_liner_many_fixits_2): New test.
(selftest::test_diagnostic_show_locus_one_liner): Update for
above.
(selftest::test_fixit_consolidation): Update for fix-it API
change.
* diagnostic.c (print_parseable_fixits): Likewise.
* edit-context.c (edited_line::m_line_events): Convert from
auto_vec <line_event *> to auto_vec <line_event>.
(class line_event): Convert from abstract base class to a concrete
class, taking over the role of replace_event.
(class insert_event): Delete.
(class replace_event): Rename to class line_event. Convert to
half-open range.
(edit_context::add_fixits): Reimplement.
(edit_context::apply_insert): Delete.
(edit_context::apply_replace): Rename to...
(edit_context::apply_fixit): ...this. Convert to half-open range.
(edited_file::apply_insert): Delete.
(edited_file::apply_replace): Rename to...
(edited_file::apply_fixit): ...this.
(edited_line::~edited_line): Drop deletion of events.
(edited_line::apply_insert): Delete.
(edited_line::apply_replace): Rename to...
(edited_line::apply_fixit): ...this. Convert to half-open range.
Update for change to type of m_line_events.
* edit-context.h (edit_context::apply_insert): Delete.
(edit_context::apply_replace): Rename to...
(edit_context::apply_fixit): ...this.
gcc/testsuite/ChangeLog:
* gcc.dg/Wmissing-braces-fixits.c: Update expected output to
reflect insertion fix-it hints at the same location now being
consolidated.
libcpp/ChangeLog:
* include/line-map.h (source_range::intersects_line_p): Delete.
(rich_location::add_fixit): Delete.
(rich_location::maybe_add_fixit): New method.
(class fixit_hint): Reimplement in terms of...
(class fixit_replace): ...this.
(class fixit_insert): Delete.
* line-map.c (linemap_position_for_loc_and_offset): Drop overzealous
linemap_assert_fails.
(source_range::intersects_line_p): Rename to...
(fixit_hint::affects_line_p): New function.
(rich_location::add_fixit_insert_before): Reimplement in terms of
maybe_add_fixit, moving validation there.
(rich_location::add_fixit_insert_after): Likewise.
(column_before_p): Delete.
(rich_location::add_fixit_replace): Reimplement in terms of
maybe_add_fixit, moving validation there. Convert closed input range
to half-open range.
(rich_location::add_fixit): Delete.
(rich_location::maybe_add_fixit): New function.
(fixit_insert::fixit_insert): Delete.
(fixit_insert::~fixit_insert): Delete.
(fixit_insert::affects_line_p): Delete.
(fixit_insert::maybe_append_replace): Delete.
(fixit_replace::fixit_replace): Rename to...
(fixit_hint::fixit_hint): ...this, rewriting as necessary.
(fixit_replace::~fixit_replace): Delete.
(fixit_replace::affects_line_p): Delete.
(fixit_replace::maybe_append_replace): Rename to...
(fixit_hint::maybe_append): ...this, rewriting as necessary.
From-SVN: r247445
PR c++/77949 identifies an ICE when the C++ frontend attempts to emit a
fix-it hint inserting a missing semicolon at column 4097 of a source file.
This column value exceeds LINE_MAP_MAX_COLUMN_NUMBER and hence isn't
representable using a location_t.
Attempting to do so leads to these problems, which this patch fixes:
(a) when encountering a column number > LINE_MAP_MAX_COLUMN_NUMBER we
create a new linemap with m_column_and_range_bits == 0, but
linemap_position_for_column doesn't check for this, and hence can emit
a bogus location_t value that's calculated relative to the previous
linemap start, but which will be decoded relative to the new linemap,
leading to very large incorrect line values.
(b) when encountering a column number that can't be represented, and
for which the linemap was pre-existing, the code would hit this assertion:
if (linemap_assert_fails (column < (1u << map->m_column_and_range_bits)))
around a bail-out condition. The patch replaces this assertion with a
simple conditional, to stop the ICE when this occurs, and fixes the
bit count (effective column bits, vs column+range bits)
(c) the C++ frontend wasn't checking for failure of
linemap_position_for_loc_and_offset when considering emitting the fix-it
hint. The patch adds a conditional, so that no fix-it hint is emitted
if the location is bogus.
gcc/cp/ChangeLog:
PR c++/77949
* parser.c (cp_parser_class_specifier_1): Only suggest inserting
a missing semicolon if we have a valid insertion location for
the fix-it hint.
gcc/ChangeLog:
PR c++/77949
* input.c (selftest::test_accessing_ordinary_linemaps): Verify
that we correctly handle column numbers greater than
LINE_MAP_MAX_COLUMN_NUMBER.
gcc/testsuite/ChangeLog:
PR c++/77949
* g++.dg/diagnostic/pr77949.C: New test case.
libcpp/ChangeLog:
PR c++/77949
* line-map.c (linemap_position_for_column): When calling
linemap_start_line, detect if a new linemap was created with
0 column bits, and bail out early if this is the case.
(linemap_position_for_loc_and_offset): Replace overzealous
linemap_assert_fails with a simple conditional; use correct
bit count.
From-SVN: r244292
PR c++/72803 describes an issue where a fix-it hint is to be emitted at
column 512 of a 511-column source line, leading to an ICE.
The root cause is a bug in linemap_line_start, when transitioning from
lines >= 512 in width to narrow lines.
The wide line in the reproducer has a line map with:
m_column_and_range_bits = 15, m_range_bits = 5
giving 10 effective bits for representing columns, so that columns <= 1023
can be represented.
When parsing the following line,
linemap_line_start (..., ..., max_column_hint=0);
is called. This leads to the "add_map" logic, due to this condition:
|| (max_column_hint <= 80 && effective_column_bits >= 10)
i.e. the new line is sufficiently narrower than the old one to
potentially use a new linemap (so as to conserve values within the
location_t space).
It then attempts to avoid allocating a new line map. Part of the logic
to determine if we really need a new line map is this condition:
SOURCE_COLUMN (map, highest) >= (1U << column_bits)
The above condition is incorrect: we need to determine if the highest
column we've handed out will fit within the proposed *effective* column
bits, but "column_bits" here is the column plus the range bits, rather
than just the column bits.
Hence in this case linemap_line_start erroneously decides that we don't
need a new line map, and updates the column bits within the existing
line map, so any location_t values we've already handed out within it
that are offset from the start by
>= (1<<new_column_and_range_bits)
effectively change meaning, leading to incorrect line&column information
when decoding them, and various "interesting" ways for the linemap
code to fail.
The fix is to use the effective column bits in the above conditional.
gcc/ChangeLog:
PR c++/72803
* input.c (selftest::test_accessing_ordinary_linemaps): Verify
that the transition from a max line width >= 1<<10 to narrower
lines works correctly.
gcc/testsuite/ChangeLog:
PR c++/72803
* g++.dg/diagnostic/pr72803.C: New test case.
libcpp/ChangeLog:
PR c++/72803
* line-map.c (linemap_line_start): When determining if the highest
column given out so far will fit into a proposed change to the
current map, use the effective number of column bits, rather than
the total number of column + range bits.
From-SVN: r244199
gcc/ChangeLog:
PR preprocessor/78680
PR preprocessor/78811
* input.c (struct selftest::lexer_test): Add field
m_implicitly_expect_EOF.
(selftest::lexer_error_sink): New class.
(selftest::lexer_error_sink::s_singleton): New global.
(selftest::lexer_test::lexer_test): Initialize new field
"m_implicitly_expect_EOF".
(selftest::lexer_test::~lexer_test): Conditionalize the
check for the EOF token on the new field.
(selftest::test_lexer_string_locations_raw_string_unterminated):
New function.
(selftest::input_c_tests): Call the new test.
libcpp/ChangeLog:
PR preprocessor/78680
PR preprocessor/78811
* lex.c (_cpp_lex_direct): Only determine the end-location of
the token and build a range for non-reserved start locations.
Do not do it for EOF tokens.
From-SVN: r243721
Fix for PR preprocessor/78680
PR preprocessor/78680 identifies a crash when attempting to issue
a -Wformat warning, where the format string includes a string token
split across multiple physical source lines via backslash-continued
lines.
The issue is that libcpp is generating bogus range information for
such tokens.
For example, in:
void fn1() {
__builtin_printf("\
%ld.\n\
2\n"); };
the range of the string token is printed as:
__builtin_printf("\
^~
whereas the range ought to be:
__builtin_printf("\
^~
%ld.\n\
~~~~~~~
2\n"); };
~~~~
The root cause is that the line notes expressing the update
of the buffer in lex.c aren't yet updated when the end-point of
the token is computed
3095 tok_range.m_finish
3096 = linemap_position_for_column (pfile->line_table,
3097 CPP_BUF_COLUMN (buffer, buffer->cur));
so that the physical line is still regarded as that of the start
of the token, and, where CPP_BUF_COLUMN uses (BUF)->line_base,
line_base is still the location of the first physical line in the
and hence the column information is too large (as if it were the
offset in the *logical* line).
(the printed range is somewhat misleading; the actual buggy range
extends beyond the "\ in the line, but within diagnostic-show-locus.c
layout::print_annotation_line only prints up to the xbound set by
layout::print_source_line and so truncates most of the buggy range).
The fix is to ensure that line notes are handled before calculating
the end-point of the token range.
This leads to the range for the string token being correctly
computed, as:
__builtin_printf("\
^~
%ld.\n\
~~~~~~~
2\n"); };
~~~~
and this leads to get_substring_ranges_for_loc failing gracefully,
rather than crashing.
gcc/testsuite/ChangeLog:
PR preprocessor/78680
* gcc.dg/format/pr78680.c: New test case.
* gcc.dg/plugin/diagnostic-test-expressions-1.c
(test_multiline_token): New function.
* gcc.dg/plugin/diagnostic-test-string-literals-1.c
(test_backslash_continued_logical_lines): New function.
libcpp/ChangeLog:
PR preprocessor/78680
* lex.c (_cpp_lex_direct): Ensure line notes are processed before
computing the end-point of the token.
From-SVN: r243567
gcc:
2016-11-23 Paolo Bonzini <bonzini@gnu.org>
* system.h (HAVE_DESIGNATED_INITIALIZERS,
HAVE_DESIGNATED_UNION_INITIALIZERS): Do not use
"defined" in macros.
* doc/cpp.texi (Defined): Mention -Wexpansion-to-defined.
* doc/cppopts.texi (Invocation): Document -Wexpansion-to-defined.
* doc/invoke.texi (Warning Options): Document -Wexpansion-to-defined.
gcc/c-family:
2016-11-23 Paolo Bonzini <bonzini@gnu.org>
* c.opt (Wexpansion-to-defined): New.
gcc/testsuite:
2016-11-23 Paolo Bonzini <bonzini@gnu.org>
* gcc.dg/cpp/defined.c: Mark newly introduced warnings and
adjust for warning->pedwarn change.
* gcc.dg/cpp/defined-syshdr.c,
gcc.dg/cpp/defined-Wexpansion-to-defined.c,
gcc.dg/cpp/defined-Wextra-Wno-expansion-to-defined.c,
gcc.dg/cpp/defined-Wextra.c,
gcc.dg/cpp/defined-Wno-expansion-to-defined.c: New testcases.
libcpp:
2016-11-23 Paolo Bonzini <bonzini@gnu.org>
* include/cpplib.h (struct cpp_options): Add new member
warn_expansion_to_defined.
(CPP_W_EXPANSION_TO_DEFINED): New enum member.
* expr.c (parse_defined): Warn for all uses of "defined"
in macros, and tie warning to CPP_W_EXPANSION_TO_DEFINED.
Make it a pedwarning instead of a warning.
* system.h (HAVE_DESIGNATED_INITIALIZERS): Do not use
"defined" in macros.
From-SVN: r242743
Whilst investigating PR preprocessor/78324 I noticed that the
substring location code currently doesn't handle raw strings
correctly, by not skipping the 'R', opening quote, delimiter
and opening parenthesis.
For example, an attempt to underline chars 4-7 with caret at 6 of
this raw string yields this erroneous output:
__emit_string_literal_range (R"foo(0123456789)foo",
~~^~
With the patch, the correct range/caret is printed:
__emit_string_literal_range (R"foo(0123456789)foo",
~~^~
gcc/ChangeLog:
* input.c (selftest::test_lexer_string_locations_long_line): New
function.
(selftest::test_lexer_string_locations_raw_string_multiline): New
function.
(selftest::input_c_tests): Call the new functions, via
for_each_line_table_case.
gcc/testsuite/ChangeLog:
* gcc.dg/plugin/diagnostic-test-string-literals-1.c
(test_raw_string_one_liner): New function.
(test_raw_string_multiline): New function.
libcpp/ChangeLog:
* charset.c (cpp_interpret_string_1): Skip locations from
loc_reader when advancing 'p' when handling raw strings.
From-SVN: r242552
Running "make selftest-valgrind" showed various leaks of the form:
408 bytes in 24 blocks are definitely lost in loss record 572 of 679
at 0x4A0645D: malloc (in /usr/lib64/valgrind/vgpreload_memcheck-amd64-linux.so)
by 0x1B0D057: xmalloc (xmalloc.c:148)
by 0x1ACCAA1: append_file_to_dir(char const*, cpp_dir*) [clone .isra.3] (files.c:1567)
by 0x1ACD56F: _cpp_find_file (files.c:390)
by 0x1ACF8FB: cpp_read_main_file(cpp_reader*, char const*) (init.c:632)
by 0x1AB3D97: selftest::lexer_test::lexer_test(selftest::line_table_case const&, char const*, selftest::lexer_test_options*) (input.c:2014)
by 0x1AB792B: selftest::test_lexer_string_locations_u8(selftest::line_table_case const&) (input.c:2713)
by 0x1ABA22A: selftest::for_each_line_table_case(void (*)(selftest::line_table_case const&)) (input.c:3227)
by 0x1ABA381: selftest::input_c_tests() (input.c:3260)
by 0x1A295F1: selftest::run_tests() (selftest-run-tests.c:62)
by 0xF20DC4: toplev::run_self_tests() (toplev.c:2076)
by 0xF20FCD: toplev::main(int, char**) (toplev.c:2153)
Fix the leak by freeing the file->path in destroy_cpp_file.
However, doing so would lead to a use-after-free in input.c's file cache
since the filenames in this cache are the libcpp file->path buffers.
Hence we need to ensure that any references to the file in the input.c
cache are purged before cleaning up file->path. This is normally done
by the temp_source_file dtor. Hence we need to reorder things to that
the temp_source_file dtor runs before cleaning up the cpp_parser. The
patch does this by introducing a wrapper class around cpp_parser *, so
that the dtor can run after the dtor for temp_source_file.
gcc/ChangeLog:
* input.c (fcache::file_patch): Add comment about lifetime.
(selftest::cpp_reader_ptr): New class.
(selftest::lexer_test): Convert m_parser from cpp_reader *
to a cpp_reader_ptr, and move m_tempfile to after it.
(selftest::lexer_test::lexer_test): Update for above reordering.
(lexer_test::~lexer_test): Move cleanup of m_parser to
cpp_reader_ptr's dtor.
libcpp/ChangeLog:
* files.c (destroy_cpp_file): Free file->path.
From-SVN: r241536
line_maps instances such as the global line_table are
GC-managed, but the htab within location_adhoc_data_map.htab
is not GC-managed.
Previously this was deleted manually by a call to
location_adhoc_data_fini within toplev::main.
However, on adding a call to forcibly_ggc_collect after the
selftests, all of the htabs for the various line_tables
created during the selftests start showing up as leaks
in "make selftest-valgrind", e.g.:
13,536 (1,344 direct, 12,192 indirect) bytes in 12 blocks are definitely lost in loss record 1,065 of 1,086
at 0x4A081D4: calloc (in /usr/lib64/valgrind/vgpreload_memcheck-amd64-linux.so)
by 0x16DB3B0: xcalloc (xmalloc.c:163)
by 0x16D8D34: htab_create_typed_alloc (hashtab.c:358)
by 0x16D8DBD: htab_create_alloc (hashtab.c:286)
by 0x16A2CCC: linemap_init(line_maps*, unsigned int) (line-map.c:353)
by 0x1685605: selftest::line_table_test::line_table_test(selftest::line_table_case const&) (input.c:1624)
by 0x167D09C: selftest::test_applying_fixits_modernize_named_init(selftest::line_table_case const&) (edit-context.c:1430)
by 0x1686827: selftest::for_each_line_table_case(void (*)(selftest::line_table_case const&)) (input.c:3227)
by 0x167F067: selftest::edit_context_c_tests() (edit-context.c:1658)
by 0x1616E67: selftest::run_tests() (selftest-run-tests.c:71)
by 0xC0DB25: toplev::run_self_tests() (toplev.c:2076)
by 0x618EB4: toplev::main(int, char**) (toplev.c:2153)
This patch removes the manual one-time cleanup in favor of
adding a destructor to class line_maps, which cleans up
the non-GC-managed htab.
Doing so improves "make selftest-valgrind" from:
==61118== LEAK SUMMARY:
==61118== definitely lost: 121,248 bytes in 1,515 blocks
==61118== indirectly lost: 974,344 bytes in 959 blocks
==61118== possibly lost: 0 bytes in 0 blocks
==61118== still reachable: 1,332,599 bytes in 3,684 blocks
==61118== suppressed: 0 bytes in 0 blocks
to:
==57182== LEAK SUMMARY:
==57182== definitely lost: 13,840 bytes in 556 blocks
==57182== indirectly lost: 0 bytes in 0 blocks
==57182== possibly lost: 0 bytes in 0 blocks
==57182== still reachable: 1,355,703 bytes in 3,684 blocks
==57182== suppressed: 0 bytes in 0 blocks
gcc/ChangeLog:
* toplev.c (toplev::main): Remove call to
location_adhoc_data_fini.
libcpp/ChangeLog:
* include/line-map.h (line_maps::~line_maps): New dtor.
(location_adhoc_data_fini): Delete decl.
* line-map.c (line_maps::~line_maps): New dtor.
(location_adhoc_data_fini): Delete.
From-SVN: r241533
* common.opt (Wimplicit-fallthrough) Turn into alias to
-Wimplicit-fallthrough=3. Remove EnabledBy.
(Wimplicit-fallthrough=): New option.
* gimplify.c (warn_implicit_fallthrough_r): Use
OPT_Wimplicit_fallthrough_ instead of OPT_Wimplicit_fallthrough.
* doc/invoke.texi (-Wimplicit-fallthrough): Document as alias
to -Wimplicit-fallthrough=3.
(-Wimplicit-fallthrough=): Document.
gcc/c-family/
* c.opt (Wextra): Add as C/C++/ObjC/ObjC++ option.
(Wimplicit-fallthrough=): Enable for these languages by -Wextra.
* c-opts.c (sanitize_cpp_opts): Initialize
cpp_opts->cpp_warn_implicit_fallthrough.
gcc/testsuite/
* c-c++-common/Wimplicit-fallthrough-25.c: New test.
* c-c++-common/Wimplicit-fallthrough-26.c: New test.
* c-c++-common/Wimplicit-fallthrough-27.c: New test.
* c-c++-common/Wimplicit-fallthrough-28.c: New test.
* c-c++-common/Wimplicit-fallthrough-29.c: New test.
* c-c++-common/Wimplicit-fallthrough-30.c: New test.
* c-c++-common/Wimplicit-fallthrough-31.c: New test.
* c-c++-common/Wimplicit-fallthrough-32.c: New test.
* c-c++-common/Wimplicit-fallthrough-33.c: New test.
libcpp/
* include/cpplib.h (struct cpp_options): Add
cpp_warn_implicit_fallthrough.
* init.c (cpp_create_reader): Initialize it to 0.
* lex.c (fallthrough_comment_p): Handle different
cpp_warn_implicit_fallthrough levels. Whitespace fixes.
From-SVN: r241013
* c-lex.c (c_lex_with_flags) <case CPP_COMMENT>: For CPP_COMMENT
token with PREV_FALLTHROUGH, skip all following CPP_PADDING and
CPP_COMMENT tokens and set add_flags to PREV_FALLTHROUGH afterwards.
* doc/invoke.texi (-Wimplicit-fallthrough): Document the accepted
FALLTHRU comment styles.
* lex.c (fallthrough_comment_p): Fix off-by-one size comparison
errors, cleanup.
(_cpp_lex_direct): Allow arbitrary comments in between
fallthrough_comment_p comment and following token.
* c-c++-common/Wimplicit-fallthrough-23.c: New test.
* c-c++-common/Wimplicit-fallthrough-24.c: New test.
From-SVN: r240884
libcpp/ChangeLog:
2016-10-04 Kelvin Nilsen <kelvin@gcc.gnu.org>
PR target/77847
* lex.c (search_line_fast): Add a FALLTHROUGH comment to correct
compiler error in the version of this function that is
conditionally compiled when GCC_VERSION >= 4005 and both
__ALTIVEC__ and __BIG_ENDIAN__ symbols are defined.
From-SVN: r240783
substring_loc::get_location currently fails for the final terminator
character in a STRING_CST from the C frontend, so that format_warning_va
falls back to using the location of the string as a whole.
This patch tweaks things [1] so that we use the final closing quote
as the location of the terminator character, as requested in
PR preprocessor/77672.
[1] specifically, cpp_interpret_string_1.
gcc/ChangeLog:
PR preprocessor/77672
* input.c (selftest::test_lexer_string_locations_simple): Update
test to expect location information of the terminator character
at the location of the final closing quote.
(selftest::test_lexer_string_locations_hex): Likewise.
(selftest::test_lexer_string_locations_oct): Likewise.
(selftest::test_lexer_string_locations_letter_escape_1): Likewise.
(selftest::test_lexer_string_locations_letter_escape_2): Likewise.
(selftest::test_lexer_string_locations_ucn4): Likewise.
(selftest::test_lexer_string_locations_ucn8): Likewise.
(selftest::test_lexer_string_locations_u8): Likewise.
(selftest::test_lexer_string_locations_utf8_source): Likewise.
(selftest::test_lexer_string_locations_concatenation_1): Likewise.
(selftest::test_lexer_string_locations_concatenation_2): Likewise.
(selftest::test_lexer_string_locations_concatenation_3): Likewise.
(selftest::test_lexer_string_locations_macro): Likewise.
(selftest::test_lexer_string_locations_long_line): Likewise.
gcc/testsuite/ChangeLog:
PR preprocessor/77672
* gcc.dg/plugin/diagnostic-test-string-literals-1.c
(test_terminator_location): New function.
libcpp/ChangeLog:
PR preprocessor/77672
* charset.c (cpp_interpret_string_1): Add a source_range for the
NUL-terminator, using the location of the trailing quote of the
final string.
From-SVN: r240434