Mercurial > hg > CbC > CbC_gcc
diff gcc/substring-locations.c @ 131:84e7813d76e9
gcc-8.2
author | mir3636 |
---|---|
date | Thu, 25 Oct 2018 07:37:49 +0900 |
parents | 04ced10e8804 |
children | 1830386684a0 |
line wrap: on
line diff
--- a/gcc/substring-locations.c Fri Oct 27 22:46:09 2017 +0900 +++ b/gcc/substring-locations.c Thu Oct 25 07:37:49 2018 +0900 @@ -1,5 +1,5 @@ /* Source locations within string literals. - Copyright (C) 2016-2017 Free Software Foundation, Inc. + Copyright (C) 2016-2018 Free Software Foundation, Inc. This file is part of GCC. @@ -20,16 +20,18 @@ #include "config.h" #include "system.h" #include "coretypes.h" +#include "intl.h" #include "diagnostic.h" #include "cpplib.h" #include "tree.h" #include "langhooks.h" #include "substring-locations.h" +#include "gcc-rich-location.h" -/* Emit a warning governed by option OPT, using GMSGID as the format - string and AP as its arguments. +/* format_string_diagnostic_t's ctor, giving information for use by + the emit_warning* member functions, as follows: - Attempt to obtain precise location information within a string + They attempt to obtain precise location information within a string literal from FMT_LOC. Case 1: if substring location is available, and is within the range of @@ -45,7 +47,7 @@ Case 2: if the substring location is available, but is not within the range of the format string, the primary location is that of the - format string, and an note is emitted showing the substring location. + format string, and a note is emitted showing the substring location. For example: test.c:90:10: warning: problem with '%i' here [-Wformat=] @@ -86,6 +88,27 @@ printf(fmt, msg); ^~~ ~~~ + If non-NULL, then FMT_LABEL will be used to label the location within the + string for cases 1 and 2; if non-NULL, then PARAM_LABEL will be used to label + the parameter. For example with case 1: + + test.c:90:16: warning: '%s' here but arg 2 has 'long' type [-Wformat=] + printf ("foo %s bar", long_i + long_j); + ~^ ~~~~~~~~~~~~~~~ + | + int + + and with case 2: + + test.c:90:10: warning: problem with '%i' here [-Wformat=] + printf("hello " INT_FMT " world", msg); + ^~~~~~~~~~~~~~~~~~~~~~~~~ + test.c:19: note: format string is defined here + #define INT_FMT "%i" + ~^ + | + int + If CORRECTED_SUBSTRING is non-NULL, use it for cases 1 and 2 to provide a fix-it hint, suggesting that it should replace the text within the substring range. For example: @@ -95,26 +118,47 @@ ~^ %s +*/ + +format_string_diagnostic_t:: +format_string_diagnostic_t (const substring_loc &fmt_loc, + const range_label *fmt_label, + location_t param_loc, + const range_label *param_label, + const char *corrected_substring) +: m_fmt_loc (fmt_loc), + m_fmt_label (fmt_label), + m_param_loc (param_loc), + m_param_label (param_label), + m_corrected_substring (corrected_substring) +{ +} + +/* Emit a warning governed by option OPT, using SINGULAR_GMSGID as the + format string (or if PLURAL_GMSGID is different from SINGULAR_GMSGID, + using SINGULAR_GMSGID, PLURAL_GMSGID and N as arguments to ngettext) + and AP as its arguments. + Return true if a warning was emitted, false otherwise. */ -ATTRIBUTE_GCC_DIAG (5,0) bool -format_warning_va (const substring_loc &fmt_loc, - location_t param_loc, - const char *corrected_substring, - int opt, const char *gmsgid, va_list *ap) +format_string_diagnostic_t::emit_warning_n_va (int opt, + unsigned HOST_WIDE_INT n, + const char *singular_gmsgid, + const char *plural_gmsgid, + va_list *ap) const { bool substring_within_range = false; location_t primary_loc; location_t fmt_substring_loc = UNKNOWN_LOCATION; source_range fmt_loc_range - = get_range_from_loc (line_table, fmt_loc.get_fmt_string_loc ()); - const char *err = fmt_loc.get_location (&fmt_substring_loc); + = get_range_from_loc (line_table, m_fmt_loc.get_fmt_string_loc ()); + const char *err = m_fmt_loc.get_location (&fmt_substring_loc); source_range fmt_substring_range = get_range_from_loc (line_table, fmt_substring_loc); if (err) /* Case 3: unable to get substring location. */ - primary_loc = fmt_loc.get_fmt_string_loc (); + primary_loc = m_fmt_loc.get_fmt_string_loc (); else { if (fmt_substring_range.m_start >= fmt_loc_range.m_start @@ -130,20 +174,44 @@ /* Case 2. */ { substring_within_range = false; - primary_loc = fmt_loc.get_fmt_string_loc (); + primary_loc = m_fmt_loc.get_fmt_string_loc (); } } - rich_location richloc (line_table, primary_loc); + /* Only use fmt_label in the initial warning for case 1. */ + const range_label *primary_label = NULL; + if (substring_within_range) + primary_label = m_fmt_label; - if (param_loc != UNKNOWN_LOCATION) - richloc.add_range (param_loc, false); + auto_diagnostic_group d; + gcc_rich_location richloc (primary_loc, primary_label); - if (!err && corrected_substring && substring_within_range) - richloc.add_fixit_replace (fmt_substring_range, corrected_substring); + if (m_param_loc != UNKNOWN_LOCATION) + richloc.add_range (m_param_loc, SHOW_RANGE_WITHOUT_CARET, m_param_label); + + if (!err && m_corrected_substring && substring_within_range) + richloc.add_fixit_replace (fmt_substring_range, m_corrected_substring); diagnostic_info diagnostic; - diagnostic_set_info (&diagnostic, gmsgid, ap, &richloc, DK_WARNING); + if (singular_gmsgid != plural_gmsgid) + { + unsigned long gtn; + + if (sizeof n <= sizeof gtn) + gtn = n; + else + /* Use the largest number ngettext can handle, otherwise + preserve the six least significant decimal digits for + languages where the plural form depends on them. */ + gtn = n <= ULONG_MAX ? n : n % 1000000LU + 1000000LU; + + const char *text = ngettext (singular_gmsgid, plural_gmsgid, gtn); + diagnostic_set_info_translated (&diagnostic, text, ap, &richloc, + DK_WARNING); + } + else + diagnostic_set_info (&diagnostic, singular_gmsgid, ap, &richloc, + DK_WARNING); diagnostic.option_index = opt; bool warned = diagnostic_report_diagnostic (global_dc, &diagnostic); @@ -151,29 +219,54 @@ /* Case 2. */ if (warned) { - rich_location substring_richloc (line_table, fmt_substring_loc); - if (corrected_substring) + /* Use fmt_label in the note for case 2. */ + rich_location substring_richloc (line_table, fmt_substring_loc, + m_fmt_label); + if (m_corrected_substring) substring_richloc.add_fixit_replace (fmt_substring_range, - corrected_substring); - inform_at_rich_loc (&substring_richloc, - "format string is defined here"); + m_corrected_substring); + inform (&substring_richloc, + "format string is defined here"); } return warned; } -/* Variadic call to format_warning_va. */ +/* Singular-only version of the above. */ bool -format_warning_at_substring (const substring_loc &fmt_loc, - location_t param_loc, - const char *corrected_substring, - int opt, const char *gmsgid, ...) +format_string_diagnostic_t::emit_warning_va (int opt, const char *gmsgid, + va_list *ap) const +{ + return emit_warning_n_va (opt, 0, gmsgid, gmsgid, ap); +} + +/* Variadic version of the above (singular only). */ + +bool +format_string_diagnostic_t::emit_warning (int opt, const char *gmsgid, + ...) const { va_list ap; va_start (ap, gmsgid); - bool warned = format_warning_va (fmt_loc, param_loc, corrected_substring, - opt, gmsgid, &ap); + bool warned = emit_warning_va (opt, gmsgid, &ap); + va_end (ap); + + return warned; +} + +/* Variadic version of the above (singular vs plural). */ + +bool +format_string_diagnostic_t::emit_warning_n (int opt, unsigned HOST_WIDE_INT n, + const char *singular_gmsgid, + const char *plural_gmsgid, + ...) const +{ + va_list ap; + va_start (ap, plural_gmsgid); + bool warned = emit_warning_n_va (opt, n, singular_gmsgid, plural_gmsgid, + &ap); va_end (ap); return warned;