X-Git-Url: http://git.sourceforge.jp/view?a=blobdiff_plain;ds=sidebyside;f=gcc%2Fc-format.c;h=9d20d12b97bd66574523f935b08260b7881d8541;hb=75a70cf95f65fe9204b15ad9aba31c571381d224;hp=10a5f21db5967dd311923a020bb1d5b9f2f73584;hpb=bbec950d3d77e66424bc836865acc4fc633d837e;p=pf3gnuchains%2Fgcc-fork.git diff --git a/gcc/c-format.c b/gcc/c-format.c index 10a5f21db59..9d20d12b97b 100644 --- a/gcc/c-format.c +++ b/gcc/c-format.c @@ -1,12 +1,12 @@ /* Check calls to formatted I/O functions (-Wformat). Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, - 2001, 2002, 2003, 2004, 2005 Free Software Foundation, Inc. + 2001, 2002, 2003, 2004, 2005, 2007 Free Software Foundation, Inc. This file is part of GCC. GCC is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free -Software Foundation; either version 2, or (at your option) any later +Software Foundation; either version 3, or (at your option) any later version. GCC is distributed in the hope that it will be useful, but WITHOUT ANY @@ -15,9 +15,8 @@ FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License -along with GCC; see the file COPYING. If not, write to the Free -Software Foundation, 51 Franklin Street, Fifth Floor, Boston, MA -02110-1301, USA. */ +along with GCC; see the file COPYING3. If not see +. */ #include "config.h" #include "system.h" @@ -31,6 +30,7 @@ Software Foundation, 51 Franklin Street, Fifth Floor, Boston, MA #include "diagnostic.h" #include "langhooks.h" #include "c-format.h" +#include "alloc-pool.h" /* Set format warning options according to a -Wformat=n option. */ @@ -40,6 +40,7 @@ set_Wformat (int setting) warn_format = setting; warn_format_extra_args = setting; warn_format_zero_length = setting; + warn_format_contains_nul = setting; if (setting != 1) { warn_format_nonliteral = setting; @@ -61,8 +62,7 @@ enum format_type { printf_format_type, asm_fprintf_format_type, gcc_diag_format_type, gcc_tdiag_format_type, gcc_cdiag_format_type, gcc_cxxdiag_format_type, gcc_gfc_format_type, - scanf_format_type, strftime_format_type, - strfmon_format_type, format_type_error = -1}; + format_type_error = -1}; typedef struct function_format_info { @@ -79,7 +79,8 @@ static bool check_format_string (tree argument, int flags, bool *no_add_attrs); static bool get_constant (tree expr, unsigned HOST_WIDE_INT *value, int validated_p); - +static const char *convert_format_name_to_system_name (const char *attr_name); +static bool cmp_attribs (const char *tattr_name, const char *attr_name); /* Handle a "format_arg" attribute; arguments as in struct attribute_spec.handler. */ @@ -190,6 +191,8 @@ decode_format_attr (tree args, function_format_info *info, int validated_p) { const char *p = IDENTIFIER_POINTER (format_type_id); + p = convert_format_name_to_system_name (p); + info->format_type = decode_format_type (p); if (info->format_type == format_type_error) @@ -280,34 +283,38 @@ typedef struct format_wanted_type struct format_wanted_type *next; } format_wanted_type; +/* Convenience macro for format_length_info meaning unused. */ +#define NO_FMT NULL, FMT_LEN_none, STD_C89 static const format_length_info printf_length_specs[] = { { "h", FMT_LEN_h, STD_C89, "hh", FMT_LEN_hh, STD_C99 }, { "l", FMT_LEN_l, STD_C89, "ll", FMT_LEN_ll, STD_C9L }, - { "q", FMT_LEN_ll, STD_EXT, NULL, 0, 0 }, - { "L", FMT_LEN_L, STD_C89, NULL, 0, 0 }, - { "z", FMT_LEN_z, STD_C99, NULL, 0, 0 }, - { "Z", FMT_LEN_z, STD_EXT, NULL, 0, 0 }, - { "t", FMT_LEN_t, STD_C99, NULL, 0, 0 }, - { "j", FMT_LEN_j, STD_C99, NULL, 0, 0 }, - { NULL, 0, 0, NULL, 0, 0 } + { "q", FMT_LEN_ll, STD_EXT, NO_FMT }, + { "L", FMT_LEN_L, STD_C89, NO_FMT }, + { "z", FMT_LEN_z, STD_C99, NO_FMT }, + { "Z", FMT_LEN_z, STD_EXT, NO_FMT }, + { "t", FMT_LEN_t, STD_C99, NO_FMT }, + { "j", FMT_LEN_j, STD_C99, NO_FMT }, + { "H", FMT_LEN_H, STD_EXT, NO_FMT }, + { "D", FMT_LEN_D, STD_EXT, "DD", FMT_LEN_DD, STD_EXT }, + { NO_FMT, NO_FMT } }; /* Length specifiers valid for asm_fprintf. */ static const format_length_info asm_fprintf_length_specs[] = { { "l", FMT_LEN_l, STD_C89, "ll", FMT_LEN_ll, STD_C89 }, - { "w", FMT_LEN_none, STD_C89, NULL, 0, 0 }, - { NULL, 0, 0, NULL, 0, 0 } + { "w", FMT_LEN_none, STD_C89, NO_FMT }, + { NO_FMT, NO_FMT } }; /* Length specifiers valid for GCC diagnostics. */ static const format_length_info gcc_diag_length_specs[] = { { "l", FMT_LEN_l, STD_C89, "ll", FMT_LEN_ll, STD_C89 }, - { "w", FMT_LEN_none, STD_C89, NULL, 0, 0 }, - { NULL, 0, 0, NULL, 0, 0 } + { "w", FMT_LEN_none, STD_C89, NO_FMT }, + { NO_FMT, NO_FMT } }; /* The custom diagnostics all accept the same length specifiers. */ @@ -320,12 +327,14 @@ static const format_length_info scanf_length_specs[] = { { "h", FMT_LEN_h, STD_C89, "hh", FMT_LEN_hh, STD_C99 }, { "l", FMT_LEN_l, STD_C89, "ll", FMT_LEN_ll, STD_C9L }, - { "q", FMT_LEN_ll, STD_EXT, NULL, 0, 0 }, - { "L", FMT_LEN_L, STD_C89, NULL, 0, 0 }, - { "z", FMT_LEN_z, STD_C99, NULL, 0, 0 }, - { "t", FMT_LEN_t, STD_C99, NULL, 0, 0 }, - { "j", FMT_LEN_j, STD_C99, NULL, 0, 0 }, - { NULL, 0, 0, NULL, 0, 0 } + { "q", FMT_LEN_ll, STD_EXT, NO_FMT }, + { "L", FMT_LEN_L, STD_C89, NO_FMT }, + { "z", FMT_LEN_z, STD_C99, NO_FMT }, + { "t", FMT_LEN_t, STD_C99, NO_FMT }, + { "j", FMT_LEN_j, STD_C99, NO_FMT }, + { "H", FMT_LEN_H, STD_EXT, NO_FMT }, + { "D", FMT_LEN_D, STD_EXT, "DD", FMT_LEN_DD, STD_EXT }, + { NO_FMT, NO_FMT } }; @@ -334,10 +343,19 @@ static const format_length_info scanf_length_specs[] = static const format_length_info strfmon_length_specs[] = { /* A GNU extension. */ - { "L", FMT_LEN_L, STD_C89, NULL, 0, 0 }, - { NULL, 0, 0, NULL, 0, 0 } + { "L", FMT_LEN_L, STD_C89, NO_FMT }, + { NO_FMT, NO_FMT } }; + +/* For now, the Fortran front-end routines only use l as length modifier. */ +static const format_length_info gcc_gfc_length_specs[] = +{ + { "l", FMT_LEN_l, STD_C89, NO_FMT }, + { NO_FMT, NO_FMT } +}; + + static const format_flag_spec printf_flag_specs[] = { { ' ', 0, 0, N_("' ' flag"), N_("the ' ' printf flag"), STD_C89 }, @@ -350,7 +368,7 @@ static const format_flag_spec printf_flag_specs[] = { 'w', 0, 0, N_("field width"), N_("field width in printf format"), STD_C89 }, { 'p', 0, 0, N_("precision"), N_("precision in printf format"), STD_C89 }, { 'L', 0, 0, N_("length modifier"), N_("length modifier in printf format"), STD_C89 }, - { 0, 0, 0, NULL, NULL, 0 } + { 0, 0, 0, NULL, NULL, STD_C89 } }; @@ -372,7 +390,7 @@ static const format_flag_spec asm_fprintf_flag_specs[] = { 'w', 0, 0, N_("field width"), N_("field width in printf format"), STD_C89 }, { 'p', 0, 0, N_("precision"), N_("precision in printf format"), STD_C89 }, { 'L', 0, 0, N_("length modifier"), N_("length modifier in printf format"), STD_C89 }, - { 0, 0, 0, NULL, NULL, 0 } + { 0, 0, 0, NULL, NULL, STD_C89 } }; static const format_flag_pair asm_fprintf_flag_pairs[] = @@ -403,7 +421,7 @@ static const format_flag_spec gcc_diag_flag_specs[] = { 'q', 0, 0, N_("'q' flag"), N_("the 'q' diagnostic flag"), STD_C89 }, { 'p', 0, 0, N_("precision"), N_("precision in printf format"), STD_C89 }, { 'L', 0, 0, N_("length modifier"), N_("length modifier in printf format"), STD_C89 }, - { 0, 0, 0, NULL, NULL, 0 } + { 0, 0, 0, NULL, NULL, STD_C89 } }; #define gcc_tdiag_flag_specs gcc_diag_flag_specs @@ -416,24 +434,26 @@ static const format_flag_spec gcc_cxxdiag_flag_specs[] = { 'q', 0, 0, N_("'q' flag"), N_("the 'q' diagnostic flag"), STD_C89 }, { 'p', 0, 0, N_("precision"), N_("precision in printf format"), STD_C89 }, { 'L', 0, 0, N_("length modifier"), N_("length modifier in printf format"), STD_C89 }, - { 0, 0, 0, NULL, NULL, 0 } + { 0, 0, 0, NULL, NULL, STD_C89 } }; static const format_flag_spec scanf_flag_specs[] = { { '*', 0, 0, N_("assignment suppression"), N_("the assignment suppression scanf feature"), STD_C89 }, { 'a', 0, 0, N_("'a' flag"), N_("the 'a' scanf flag"), STD_EXT }, + { 'm', 0, 0, N_("'m' flag"), N_("the 'm' scanf flag"), STD_EXT }, { 'w', 0, 0, N_("field width"), N_("field width in scanf format"), STD_C89 }, { 'L', 0, 0, N_("length modifier"), N_("length modifier in scanf format"), STD_C89 }, { '\'', 0, 0, N_("''' flag"), N_("the ''' scanf flag"), STD_EXT }, { 'I', 0, 0, N_("'I' flag"), N_("the 'I' scanf flag"), STD_EXT }, - { 0, 0, 0, NULL, NULL, 0 } + { 0, 0, 0, NULL, NULL, STD_C89 } }; static const format_flag_pair scanf_flag_pairs[] = { { '*', 'L', 0, 0 }, + { 'a', 'm', 0, 0 }, { 0, 0, 0, 0 } }; @@ -449,7 +469,7 @@ static const format_flag_spec strftime_flag_specs[] = { 'E', 0, 0, N_("'E' modifier"), N_("the 'E' strftime modifier"), STD_C99 }, { 'O', 0, 0, N_("'O' modifier"), N_("the 'O' strftime modifier"), STD_C99 }, { 'O', 'o', 0, NULL, N_("the 'O' modifier"), STD_EXT }, - { 0, 0, 0, NULL, NULL, 0 } + { 0, 0, 0, NULL, NULL, STD_C89 } }; @@ -476,7 +496,7 @@ static const format_flag_spec strfmon_flag_specs[] = { '#', 0, 0, N_("left precision"), N_("left precision in strfmon format"), STD_C89 }, { 'p', 0, 0, N_("right precision"), N_("right precision in strfmon format"), STD_C89 }, { 'L', 0, 0, N_("length modifier"), N_("length modifier in strfmon format"), STD_C89 }, - { 0, 0, 0, NULL, NULL, 0 } + { 0, 0, 0, NULL, NULL, STD_C89 } }; static const format_flag_pair strfmon_flag_pairs[] = @@ -489,34 +509,34 @@ static const format_flag_pair strfmon_flag_pairs[] = static const format_char_info print_char_table[] = { /* C89 conversion specifiers. */ - { "di", 0, STD_C89, { T89_I, T99_SC, T89_S, T89_L, T9L_LL, TEX_LL, T99_SST, T99_PD, T99_IM }, "-wp0 +'I", "i", NULL }, - { "oxX", 0, STD_C89, { T89_UI, T99_UC, T89_US, T89_UL, T9L_ULL, TEX_ULL, T99_ST, T99_UPD, T99_UIM }, "-wp0#", "i", NULL }, - { "u", 0, STD_C89, { T89_UI, T99_UC, T89_US, T89_UL, T9L_ULL, TEX_ULL, T99_ST, T99_UPD, T99_UIM }, "-wp0'I", "i", NULL }, - { "fgG", 0, STD_C89, { T89_D, BADLEN, BADLEN, T99_D, BADLEN, T89_LD, BADLEN, BADLEN, BADLEN }, "-wp0 +#'I", "", NULL }, - { "eE", 0, STD_C89, { T89_D, BADLEN, BADLEN, T99_D, BADLEN, T89_LD, BADLEN, BADLEN, BADLEN }, "-wp0 +#I", "", NULL }, - { "c", 0, STD_C89, { T89_I, BADLEN, BADLEN, T94_WI, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN }, "-w", "", NULL }, - { "s", 1, STD_C89, { T89_C, BADLEN, BADLEN, T94_W, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN }, "-wp", "cR", NULL }, - { "p", 1, STD_C89, { T89_V, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN }, "-w", "c", NULL }, - { "n", 1, STD_C89, { T89_I, T99_SC, T89_S, T89_L, T9L_LL, BADLEN, T99_SST, T99_PD, T99_IM }, "", "W", NULL }, + { "di", 0, STD_C89, { T89_I, T99_SC, T89_S, T89_L, T9L_LL, TEX_LL, T99_SST, T99_PD, T99_IM, BADLEN, BADLEN, BADLEN }, "-wp0 +'I", "i", NULL }, + { "oxX", 0, STD_C89, { T89_UI, T99_UC, T89_US, T89_UL, T9L_ULL, TEX_ULL, T99_ST, T99_UPD, T99_UIM, BADLEN, BADLEN, BADLEN }, "-wp0#", "i", NULL }, + { "u", 0, STD_C89, { T89_UI, T99_UC, T89_US, T89_UL, T9L_ULL, TEX_ULL, T99_ST, T99_UPD, T99_UIM, BADLEN, BADLEN, BADLEN }, "-wp0'I", "i", NULL }, + { "fgG", 0, STD_C89, { T89_D, BADLEN, BADLEN, T99_D, BADLEN, T89_LD, BADLEN, BADLEN, BADLEN, TEX_D32, TEX_D64, TEX_D128 }, "-wp0 +#'I", "", NULL }, + { "eE", 0, STD_C89, { T89_D, BADLEN, BADLEN, T99_D, BADLEN, T89_LD, BADLEN, BADLEN, BADLEN, TEX_D32, TEX_D64, TEX_D128 }, "-wp0 +#I", "", NULL }, + { "c", 0, STD_C89, { T89_I, BADLEN, BADLEN, T94_WI, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN }, "-w", "", NULL }, + { "s", 1, STD_C89, { T89_C, BADLEN, BADLEN, T94_W, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN }, "-wp", "cR", NULL }, + { "p", 1, STD_C89, { T89_V, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN }, "-w", "c", NULL }, + { "n", 1, STD_C89, { T89_I, T99_SC, T89_S, T89_L, T9L_LL, BADLEN, T99_SST, T99_PD, T99_IM, BADLEN, BADLEN, BADLEN }, "", "W", NULL }, /* C99 conversion specifiers. */ - { "F", 0, STD_C99, { T99_D, BADLEN, BADLEN, T99_D, BADLEN, T99_LD, BADLEN, BADLEN, BADLEN }, "-wp0 +#'I", "", NULL }, - { "aA", 0, STD_C99, { T99_D, BADLEN, BADLEN, T99_D, BADLEN, T99_LD, BADLEN, BADLEN, BADLEN }, "-wp0 +#", "", NULL }, + { "F", 0, STD_C99, { T99_D, BADLEN, BADLEN, T99_D, BADLEN, T99_LD, BADLEN, BADLEN, BADLEN, TEX_D32, TEX_D64, TEX_D128 }, "-wp0 +#'I", "", NULL }, + { "aA", 0, STD_C99, { T99_D, BADLEN, BADLEN, T99_D, BADLEN, T99_LD, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN }, "-wp0 +#", "", NULL }, /* X/Open conversion specifiers. */ - { "C", 0, STD_EXT, { TEX_WI, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN }, "-w", "", NULL }, - { "S", 1, STD_EXT, { TEX_W, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN }, "-wp", "R", NULL }, + { "C", 0, STD_EXT, { TEX_WI, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN }, "-w", "", NULL }, + { "S", 1, STD_EXT, { TEX_W, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN }, "-wp", "R", NULL }, /* GNU conversion specifiers. */ - { "m", 0, STD_EXT, { T89_V, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN }, "-wp", "", NULL }, - { NULL, 0, 0, NOLENGTHS, NULL, NULL, NULL } + { "m", 0, STD_EXT, { T89_V, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN }, "-wp", "", NULL }, + { NULL, 0, STD_C89, NOLENGTHS, NULL, NULL, NULL } }; static const format_char_info asm_fprintf_char_table[] = { /* C89 conversion specifiers. */ - { "di", 0, STD_C89, { T89_I, BADLEN, BADLEN, T89_L, T9L_LL, BADLEN, BADLEN, BADLEN, BADLEN }, "-wp0 +", "i", NULL }, - { "oxX", 0, STD_C89, { T89_UI, BADLEN, BADLEN, T89_UL, T9L_ULL, BADLEN, BADLEN, BADLEN, BADLEN }, "-wp0#", "i", NULL }, - { "u", 0, STD_C89, { T89_UI, BADLEN, BADLEN, T89_UL, T9L_ULL, BADLEN, BADLEN, BADLEN, BADLEN }, "-wp0", "i", NULL }, - { "c", 0, STD_C89, { T89_I, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN }, "-w", "", NULL }, - { "s", 1, STD_C89, { T89_C, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN }, "-wp", "cR", NULL }, + { "di", 0, STD_C89, { T89_I, BADLEN, BADLEN, T89_L, T9L_LL, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN }, "-wp0 +", "i", NULL }, + { "oxX", 0, STD_C89, { T89_UI, BADLEN, BADLEN, T89_UL, T9L_ULL, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN }, "-wp0#", "i", NULL }, + { "u", 0, STD_C89, { T89_UI, BADLEN, BADLEN, T89_UL, T9L_ULL, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN }, "-wp0", "i", NULL }, + { "c", 0, STD_C89, { T89_I, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN }, "-w", "", NULL }, + { "s", 1, STD_C89, { T89_C, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN }, "-wp", "cR", NULL }, /* asm_fprintf conversion specifiers. */ { "O", 0, STD_C89, NOARGUMENTS, "", "", NULL }, @@ -524,32 +544,32 @@ static const format_char_info asm_fprintf_char_table[] = { "I", 0, STD_C89, NOARGUMENTS, "", "", NULL }, { "L", 0, STD_C89, NOARGUMENTS, "", "", NULL }, { "U", 0, STD_C89, NOARGUMENTS, "", "", NULL }, - { "r", 0, STD_C89, { T89_I, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN }, "", "", NULL }, + { "r", 0, STD_C89, { T89_I, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN }, "", "", NULL }, { "@", 0, STD_C89, NOARGUMENTS, "", "", NULL }, - { NULL, 0, 0, NOLENGTHS, NULL, NULL, NULL } + { NULL, 0, STD_C89, NOLENGTHS, NULL, NULL, NULL } }; static const format_char_info gcc_diag_char_table[] = { /* C89 conversion specifiers. */ - { "di", 0, STD_C89, { T89_I, BADLEN, BADLEN, T89_L, T9L_LL, BADLEN, BADLEN, BADLEN, BADLEN }, "q", "", NULL }, - { "ox", 0, STD_C89, { T89_UI, BADLEN, BADLEN, T89_UL, T9L_ULL, BADLEN, BADLEN, BADLEN, BADLEN }, "q", "", NULL }, - { "u", 0, STD_C89, { T89_UI, BADLEN, BADLEN, T89_UL, T9L_ULL, BADLEN, BADLEN, BADLEN, BADLEN }, "q", "", NULL }, - { "c", 0, STD_C89, { T89_I, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN }, "q", "", NULL }, - { "s", 1, STD_C89, { T89_C, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN }, "pq", "cR", NULL }, - { "p", 1, STD_C89, { T89_V, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN }, "q", "c", NULL }, + { "di", 0, STD_C89, { T89_I, BADLEN, BADLEN, T89_L, T9L_LL, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN }, "q", "", NULL }, + { "ox", 0, STD_C89, { T89_UI, BADLEN, BADLEN, T89_UL, T9L_ULL, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN }, "q", "", NULL }, + { "u", 0, STD_C89, { T89_UI, BADLEN, BADLEN, T89_UL, T9L_ULL, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN }, "q", "", NULL }, + { "c", 0, STD_C89, { T89_I, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN }, "q", "", NULL }, + { "s", 1, STD_C89, { T89_C, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN }, "pq", "cR", NULL }, + { "p", 1, STD_C89, { T89_V, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN }, "q", "c", NULL }, /* Custom conversion specifiers. */ /* %H will require "location_t" at runtime. */ - { "H", 0, STD_C89, { T89_V, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN }, "q", "", NULL }, + { "H", 0, STD_C89, { T89_V, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN }, "q", "", NULL }, /* These will require a "tree" at runtime. */ - { "J", 0, STD_C89, { T89_V, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN }, "q", "", NULL }, + { "JK", 0, STD_C89, { T89_V, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN }, "q", "", NULL }, { "<>'", 0, STD_C89, NOARGUMENTS, "", "", NULL }, { "m", 0, STD_C89, NOARGUMENTS, "q", "", NULL }, - { NULL, 0, 0, NOLENGTHS, NULL, NULL, NULL } + { NULL, 0, STD_C89, NOLENGTHS, NULL, NULL, NULL } }; static const format_char_info gcc_tdiag_char_table[] = @@ -568,66 +588,67 @@ static const format_char_info gcc_tdiag_char_table[] = { "H", 0, STD_C89, { T89_V, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN }, "q", "", NULL }, /* These will require a "tree" at runtime. */ - { "DFJT", 0, STD_C89, { T89_V, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN }, "q+", "", NULL }, + { "DFJKT", 0, STD_C89, { T89_V, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN }, "q+", "", NULL }, { "<>'", 0, STD_C89, NOARGUMENTS, "", "", NULL }, { "m", 0, STD_C89, NOARGUMENTS, "q", "", NULL }, - { NULL, 0, 0, NOLENGTHS, NULL, NULL, NULL } + { NULL, 0, STD_C89, NOLENGTHS, NULL, NULL, NULL } }; static const format_char_info gcc_cdiag_char_table[] = { /* C89 conversion specifiers. */ - { "di", 0, STD_C89, { T89_I, BADLEN, BADLEN, T89_L, T9L_LL, BADLEN, BADLEN, BADLEN, BADLEN }, "q", "", NULL }, - { "ox", 0, STD_C89, { T89_UI, BADLEN, BADLEN, T89_UL, T9L_ULL, BADLEN, BADLEN, BADLEN, BADLEN }, "q", "", NULL }, - { "u", 0, STD_C89, { T89_UI, BADLEN, BADLEN, T89_UL, T9L_ULL, BADLEN, BADLEN, BADLEN, BADLEN }, "q", "", NULL }, - { "c", 0, STD_C89, { T89_I, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN }, "q", "", NULL }, - { "s", 1, STD_C89, { T89_C, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN }, "pq", "cR", NULL }, - { "p", 1, STD_C89, { T89_V, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN }, "q", "c", NULL }, + { "di", 0, STD_C89, { T89_I, BADLEN, BADLEN, T89_L, T9L_LL, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN }, "q", "", NULL }, + { "ox", 0, STD_C89, { T89_UI, BADLEN, BADLEN, T89_UL, T9L_ULL, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN }, "q", "", NULL }, + { "u", 0, STD_C89, { T89_UI, BADLEN, BADLEN, T89_UL, T9L_ULL, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN }, "q", "", NULL }, + { "c", 0, STD_C89, { T89_I, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN }, "q", "", NULL }, + { "s", 1, STD_C89, { T89_C, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN }, "pq", "cR", NULL }, + { "p", 1, STD_C89, { T89_V, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN }, "q", "c", NULL }, /* Custom conversion specifiers. */ /* %H will require "location_t" at runtime. */ - { "H", 0, STD_C89, { T89_V, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN }, "q", "", NULL }, + { "H", 0, STD_C89, { T89_V, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN }, "q", "", NULL }, /* These will require a "tree" at runtime. */ - { "DEFJT", 0, STD_C89, { T89_V, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN }, "q+", "", NULL }, + { "DEFJKT", 0, STD_C89, { T89_V, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN }, "q+", "", NULL }, { "<>'", 0, STD_C89, NOARGUMENTS, "", "", NULL }, { "m", 0, STD_C89, NOARGUMENTS, "q", "", NULL }, - { NULL, 0, 0, NOLENGTHS, NULL, NULL, NULL } + { NULL, 0, STD_C89, NOLENGTHS, NULL, NULL, NULL } }; static const format_char_info gcc_cxxdiag_char_table[] = { /* C89 conversion specifiers. */ - { "di", 0, STD_C89, { T89_I, BADLEN, BADLEN, T89_L, T9L_LL, BADLEN, BADLEN, BADLEN, BADLEN }, "q", "", NULL }, - { "ox", 0, STD_C89, { T89_UI, BADLEN, BADLEN, T89_UL, T9L_ULL, BADLEN, BADLEN, BADLEN, BADLEN }, "q", "", NULL }, - { "u", 0, STD_C89, { T89_UI, BADLEN, BADLEN, T89_UL, T9L_ULL, BADLEN, BADLEN, BADLEN, BADLEN }, "q", "", NULL }, - { "c", 0, STD_C89, { T89_I, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN }, "q", "", NULL }, - { "s", 1, STD_C89, { T89_C, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN }, "pq", "cR", NULL }, - { "p", 1, STD_C89, { T89_V, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN }, "q", "c", NULL }, + { "di", 0, STD_C89, { T89_I, BADLEN, BADLEN, T89_L, T9L_LL, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN }, "q", "", NULL }, + { "ox", 0, STD_C89, { T89_UI, BADLEN, BADLEN, T89_UL, T9L_ULL, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN }, "q", "", NULL }, + { "u", 0, STD_C89, { T89_UI, BADLEN, BADLEN, T89_UL, T9L_ULL, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN }, "q", "", NULL }, + { "c", 0, STD_C89, { T89_I, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN }, "q", "", NULL }, + { "s", 1, STD_C89, { T89_C, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN }, "pq", "cR", NULL }, + { "p", 1, STD_C89, { T89_V, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN }, "q", "c", NULL }, /* Custom conversion specifiers. */ /* %H will require "location_t" at runtime. */ - { "H", 0, STD_C89, { T89_V, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN }, "q", "", NULL }, + { "H", 0, STD_C89, { T89_V, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN }, "q", "", NULL }, /* These will require a "tree" at runtime. */ - { "ADEFJTV",0,STD_C89,{ T89_V, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN }, "q+#", "", NULL }, + { "ADEFJKTV",0,STD_C89,{ T89_V, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN }, "q+#", "", NULL }, /* These accept either an 'int' or an 'enum tree_code' (which is handled as an 'int'.) */ - { "CLOPQ",0,STD_C89, { T89_I, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN }, "q", "", NULL }, + { "CLOPQ",0,STD_C89, { T89_I, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN }, "q", "", NULL }, { "<>'", 0, STD_C89, NOARGUMENTS, "", "", NULL }, { "m", 0, STD_C89, NOARGUMENTS, "q", "", NULL }, - { NULL, 0, 0, NOLENGTHS, NULL, NULL, NULL } + { NULL, 0, STD_C89, NOLENGTHS, NULL, NULL, NULL } }; static const format_char_info gcc_gfc_char_table[] = { /* C89 conversion specifiers. */ - { "di", 0, STD_C89, { T89_I, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN }, "", "", NULL }, + { "di", 0, STD_C89, { T89_I, BADLEN, BADLEN, T89_L, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN }, "", "", NULL }, + { "u", 0, STD_C89, { T89_UI, BADLEN, BADLEN, T89_UL, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN }, "", "", NULL }, { "c", 0, STD_C89, { T89_I, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN }, "", "", NULL }, { "s", 1, STD_C89, { T89_C, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN }, "", "cR", NULL }, @@ -638,121 +659,122 @@ static const format_char_info gcc_gfc_char_table[] = /* This will require a "locus" at runtime. */ { "L", 0, STD_C89, { T89_V, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN }, "", "R", NULL }, - { NULL, 0, 0, NOLENGTHS, NULL, NULL, NULL } + { NULL, 0, STD_C89, NOLENGTHS, NULL, NULL, NULL } }; static const format_char_info scan_char_table[] = { /* C89 conversion specifiers. */ - { "di", 1, STD_C89, { T89_I, T99_SC, T89_S, T89_L, T9L_LL, TEX_LL, T99_SST, T99_PD, T99_IM }, "*w'I", "W", NULL }, - { "u", 1, STD_C89, { T89_UI, T99_UC, T89_US, T89_UL, T9L_ULL, TEX_ULL, T99_ST, T99_UPD, T99_UIM }, "*w'I", "W", NULL }, - { "oxX", 1, STD_C89, { T89_UI, T99_UC, T89_US, T89_UL, T9L_ULL, TEX_ULL, T99_ST, T99_UPD, T99_UIM }, "*w", "W", NULL }, - { "efgEG", 1, STD_C89, { T89_F, BADLEN, BADLEN, T89_D, BADLEN, T89_LD, BADLEN, BADLEN, BADLEN }, "*w'", "W", NULL }, - { "c", 1, STD_C89, { T89_C, BADLEN, BADLEN, T94_W, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN }, "*w", "cW", NULL }, - { "s", 1, STD_C89, { T89_C, BADLEN, BADLEN, T94_W, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN }, "*aw", "cW", NULL }, - { "[", 1, STD_C89, { T89_C, BADLEN, BADLEN, T94_W, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN }, "*aw", "cW[", NULL }, - { "p", 2, STD_C89, { T89_V, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN }, "*w", "W", NULL }, - { "n", 1, STD_C89, { T89_I, T99_SC, T89_S, T89_L, T9L_LL, BADLEN, T99_SST, T99_PD, T99_IM }, "", "W", NULL }, + { "di", 1, STD_C89, { T89_I, T99_SC, T89_S, T89_L, T9L_LL, TEX_LL, T99_SST, T99_PD, T99_IM, BADLEN, BADLEN, BADLEN }, "*w'I", "W", NULL }, + { "u", 1, STD_C89, { T89_UI, T99_UC, T89_US, T89_UL, T9L_ULL, TEX_ULL, T99_ST, T99_UPD, T99_UIM, BADLEN, BADLEN, BADLEN }, "*w'I", "W", NULL }, + { "oxX", 1, STD_C89, { T89_UI, T99_UC, T89_US, T89_UL, T9L_ULL, TEX_ULL, T99_ST, T99_UPD, T99_UIM, BADLEN, BADLEN, BADLEN }, "*w", "W", NULL }, + { "efgEG", 1, STD_C89, { T89_F, BADLEN, BADLEN, T89_D, BADLEN, T89_LD, BADLEN, BADLEN, BADLEN, TEX_D32, TEX_D64, TEX_D128 }, "*w'", "W", NULL }, + { "c", 1, STD_C89, { T89_C, BADLEN, BADLEN, T94_W, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN }, "*mw", "cW", NULL }, + { "s", 1, STD_C89, { T89_C, BADLEN, BADLEN, T94_W, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN }, "*amw", "cW", NULL }, + { "[", 1, STD_C89, { T89_C, BADLEN, BADLEN, T94_W, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN }, "*amw", "cW[", NULL }, + { "p", 2, STD_C89, { T89_V, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN }, "*w", "W", NULL }, + { "n", 1, STD_C89, { T89_I, T99_SC, T89_S, T89_L, T9L_LL, BADLEN, T99_SST, T99_PD, T99_IM, BADLEN, BADLEN, BADLEN }, "", "W", NULL }, /* C99 conversion specifiers. */ - { "FaA", 1, STD_C99, { T99_F, BADLEN, BADLEN, T99_D, BADLEN, T99_LD, BADLEN, BADLEN, BADLEN }, "*w'", "W", NULL }, + { "F", 1, STD_C99, { T99_F, BADLEN, BADLEN, T99_D, BADLEN, T99_LD, BADLEN, BADLEN, BADLEN, TEX_D32, TEX_D64, TEX_D128 }, "*w'", "W", NULL }, + { "aA", 1, STD_C99, { T99_F, BADLEN, BADLEN, T99_D, BADLEN, T99_LD, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN }, "*w'", "W", NULL }, /* X/Open conversion specifiers. */ - { "C", 1, STD_EXT, { TEX_W, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN }, "*w", "W", NULL }, - { "S", 1, STD_EXT, { TEX_W, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN }, "*aw", "W", NULL }, - { NULL, 0, 0, NOLENGTHS, NULL, NULL, NULL } + { "C", 1, STD_EXT, { TEX_W, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN }, "*mw", "W", NULL }, + { "S", 1, STD_EXT, { TEX_W, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN }, "*amw", "W", NULL }, + { NULL, 0, STD_C89, NOLENGTHS, NULL, NULL, NULL } }; static const format_char_info time_char_table[] = { /* C89 conversion specifiers. */ { "ABZab", 0, STD_C89, NOLENGTHS, "^#", "", NULL }, - { "cx", 0, STD_C89, NOLENGTHS, "E", "3", NULL }, + { "cx", 0, STD_C89, NOLENGTHS, "E", "3", NULL }, { "HIMSUWdmw", 0, STD_C89, NOLENGTHS, "-_0Ow", "", NULL }, { "j", 0, STD_C89, NOLENGTHS, "-_0Ow", "o", NULL }, { "p", 0, STD_C89, NOLENGTHS, "#", "", NULL }, { "X", 0, STD_C89, NOLENGTHS, "E", "", NULL }, - { "y", 0, STD_C89, NOLENGTHS, "EO-_0w", "4", NULL }, + { "y", 0, STD_C89, NOLENGTHS, "EO-_0w", "4", NULL }, { "Y", 0, STD_C89, NOLENGTHS, "-_0EOw", "o", NULL }, { "%", 0, STD_C89, NOLENGTHS, "", "", NULL }, /* C99 conversion specifiers. */ { "C", 0, STD_C99, NOLENGTHS, "-_0EOw", "o", NULL }, - { "D", 0, STD_C99, NOLENGTHS, "", "2", NULL }, + { "D", 0, STD_C99, NOLENGTHS, "", "2", NULL }, { "eVu", 0, STD_C99, NOLENGTHS, "-_0Ow", "", NULL }, { "FRTnrt", 0, STD_C99, NOLENGTHS, "", "", NULL }, - { "g", 0, STD_C99, NOLENGTHS, "O-_0w", "2o", NULL }, + { "g", 0, STD_C99, NOLENGTHS, "O-_0w", "2o", NULL }, { "G", 0, STD_C99, NOLENGTHS, "-_0Ow", "o", NULL }, { "h", 0, STD_C99, NOLENGTHS, "^#", "", NULL }, { "z", 0, STD_C99, NOLENGTHS, "O", "o", NULL }, /* GNU conversion specifiers. */ { "kls", 0, STD_EXT, NOLENGTHS, "-_0Ow", "", NULL }, { "P", 0, STD_EXT, NOLENGTHS, "", "", NULL }, - { NULL, 0, 0, NOLENGTHS, NULL, NULL, NULL } + { NULL, 0, STD_C89, NOLENGTHS, NULL, NULL, NULL } }; static const format_char_info monetary_char_table[] = { - { "in", 0, STD_C89, { T89_D, BADLEN, BADLEN, BADLEN, BADLEN, T89_LD, BADLEN, BADLEN, BADLEN }, "=^+(!-w#p", "", NULL }, - { NULL, 0, 0, NOLENGTHS, NULL, NULL, NULL } + { "in", 0, STD_C89, { T89_D, BADLEN, BADLEN, BADLEN, BADLEN, T89_LD, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN }, "=^+(!-w#p", "", NULL }, + { NULL, 0, STD_C89, NOLENGTHS, NULL, NULL, NULL } }; /* This must be in the same order as enum format_type. */ static const format_kind_info format_types_orig[] = { - { "printf", printf_length_specs, print_char_table, " +#0-'I", NULL, + { "gnu_printf", printf_length_specs, print_char_table, " +#0-'I", NULL, printf_flag_specs, printf_flag_pairs, FMT_FLAG_ARG_CONVERT|FMT_FLAG_DOLLAR_MULTIPLE|FMT_FLAG_USE_DOLLAR|FMT_FLAG_EMPTY_PREC_OK, - 'w', 0, 'p', 0, 'L', + 'w', 0, 'p', 0, 'L', 0, &integer_type_node, &integer_type_node }, - { "asm_fprintf", asm_fprintf_length_specs, asm_fprintf_char_table, " +#0-", NULL, + { "asm_fprintf", asm_fprintf_length_specs, asm_fprintf_char_table, " +#0-", NULL, asm_fprintf_flag_specs, asm_fprintf_flag_pairs, FMT_FLAG_ARG_CONVERT|FMT_FLAG_EMPTY_PREC_OK, - 'w', 0, 'p', 0, 'L', + 'w', 0, 'p', 0, 'L', 0, NULL, NULL }, - { "gcc_diag", gcc_diag_length_specs, gcc_diag_char_table, "q+", NULL, + { "gcc_diag", gcc_diag_length_specs, gcc_diag_char_table, "q+", NULL, gcc_diag_flag_specs, gcc_diag_flag_pairs, FMT_FLAG_ARG_CONVERT, - 0, 0, 'p', 0, 'L', + 0, 0, 'p', 0, 'L', 0, NULL, &integer_type_node }, - { "gcc_tdiag", gcc_tdiag_length_specs, gcc_tdiag_char_table, "q+", NULL, + { "gcc_tdiag", gcc_tdiag_length_specs, gcc_tdiag_char_table, "q+", NULL, gcc_tdiag_flag_specs, gcc_tdiag_flag_pairs, FMT_FLAG_ARG_CONVERT, - 0, 0, 'p', 0, 'L', + 0, 0, 'p', 0, 'L', 0, NULL, &integer_type_node }, - { "gcc_cdiag", gcc_cdiag_length_specs, gcc_cdiag_char_table, "q+", NULL, + { "gcc_cdiag", gcc_cdiag_length_specs, gcc_cdiag_char_table, "q+", NULL, gcc_cdiag_flag_specs, gcc_cdiag_flag_pairs, FMT_FLAG_ARG_CONVERT, - 0, 0, 'p', 0, 'L', + 0, 0, 'p', 0, 'L', 0, NULL, &integer_type_node }, - { "gcc_cxxdiag", gcc_cxxdiag_length_specs, gcc_cxxdiag_char_table, "q+#", NULL, + { "gcc_cxxdiag", gcc_cxxdiag_length_specs, gcc_cxxdiag_char_table, "q+#", NULL, gcc_cxxdiag_flag_specs, gcc_cxxdiag_flag_pairs, FMT_FLAG_ARG_CONVERT, - 0, 0, 'p', 0, 'L', + 0, 0, 'p', 0, 'L', 0, NULL, &integer_type_node }, - { "gcc_gfc", NULL, gcc_gfc_char_table, "", NULL, + { "gcc_gfc", gcc_gfc_length_specs, gcc_gfc_char_table, "", NULL, NULL, gcc_gfc_flag_pairs, FMT_FLAG_ARG_CONVERT, - 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, NULL, NULL }, - { "scanf", scanf_length_specs, scan_char_table, "*'I", NULL, + { "gnu_scanf", scanf_length_specs, scan_char_table, "*'I", NULL, scanf_flag_specs, scanf_flag_pairs, FMT_FLAG_ARG_CONVERT|FMT_FLAG_SCANF_A_KLUDGE|FMT_FLAG_USE_DOLLAR|FMT_FLAG_ZERO_WIDTH_BAD|FMT_FLAG_DOLLAR_GAP_POINTER_OK, - 'w', 0, 0, '*', 'L', + 'w', 0, 0, '*', 'L', 'm', NULL, NULL }, - { "strftime", NULL, time_char_table, "_-0^#", "EO", + { "gnu_strftime", NULL, time_char_table, "_-0^#", "EO", strftime_flag_specs, strftime_flag_pairs, - FMT_FLAG_FANCY_PERCENT_OK, 'w', 0, 0, 0, 0, + FMT_FLAG_FANCY_PERCENT_OK, 'w', 0, 0, 0, 0, 0, NULL, NULL }, - { "strfmon", strfmon_length_specs, monetary_char_table, "=^+(!-", NULL, + { "gnu_strfmon", strfmon_length_specs, monetary_char_table, "=^+(!-", NULL, strfmon_flag_specs, strfmon_flag_pairs, - FMT_FLAG_ARG_CONVERT, 'w', '#', 'p', 0, 'L', + FMT_FLAG_ARG_CONVERT, 'w', '#', 'p', 0, 'L', 0, NULL, NULL } }; @@ -806,7 +828,7 @@ static void check_format_arg (void *, tree, unsigned HOST_WIDE_INT); static void check_format_info_main (format_check_results *, function_format_info *, const char *, int, tree, - unsigned HOST_WIDE_INT); + unsigned HOST_WIDE_INT, alloc_pool); static void init_dollar_format_checking (int, tree); static int maybe_read_dollar_number (const char **, int, @@ -829,6 +851,8 @@ decode_format_type (const char *s) { int i; int slen; + + s = convert_format_name_to_system_name (s); slen = strlen (s); for (i = 0; i < n_format_types; i++) { @@ -846,13 +870,14 @@ decode_format_type (const char *s) /* Check the argument list of a call to printf, scanf, etc. - ATTRS are the attributes on the function type. - PARAMS is the list of argument values. Also, if -Wmissing-format-attribute, + ATTRS are the attributes on the function type. There are NARGS argument + values in the array ARGARRAY. + Also, if -Wmissing-format-attribute, warn for calls to vprintf or vscanf in functions with no such format attribute themselves. */ void -check_function_format (tree attrs, tree params) +check_function_format (tree attrs, int nargs, tree *argarray) { tree a; @@ -864,7 +889,17 @@ check_function_format (tree attrs, tree params) /* Yup; check it. */ function_format_info info; decode_format_attr (TREE_VALUE (a), &info, 1); - check_format_info (&info, params); + if (warn_format) + { + /* FIXME: Rewrite all the internal functions in this file + to use the ARGARRAY directly instead of constructing this + temporary list. */ + tree params = NULL_TREE; + int i; + for (i = nargs - 1; i >= 0; i--) + params = tree_cons (NULL_TREE, argarray[i], params); + check_format_info (&info, params); + } if (warn_missing_format_attribute && info.first_arg_num == 0 && (format_types[info.format_type].flags & (int) FMT_FLAG_ARG_CONVERT)) @@ -895,8 +930,8 @@ check_function_format (tree attrs, tree params) break; } if (args != 0) - warning (OPT_Wattributes, "function might be possible " - "candidate for %qs format attribute", + warning (OPT_Wmissing_format_attribute, "function might " + "be possible candidate for %qs format attribute", format_types[info.format_type].name); } } @@ -1274,6 +1309,7 @@ check_format_arg (void *ctx, tree format_tree, const char *format_chars; tree array_size = 0; tree array_init; + alloc_pool fwt_pool; if (integer_zerop (format_tree)) { @@ -1296,7 +1332,7 @@ check_format_arg (void *ctx, tree format_tree, } offset = 0; - if (TREE_CODE (format_tree) == PLUS_EXPR) + if (TREE_CODE (format_tree) == POINTER_PLUS_EXPR) { tree arg0, arg1; @@ -1306,11 +1342,6 @@ check_format_arg (void *ctx, tree format_tree, STRIP_NOPS (arg1); if (TREE_CODE (arg1) == INTEGER_CST) format_tree = arg0; - else if (TREE_CODE (arg0) == INTEGER_CST) - { - format_tree = arg1; - arg1 = arg0; - } else { res->number_non_literal++; @@ -1360,7 +1391,7 @@ check_format_arg (void *ctx, tree format_tree, { /* Variable length arrays can't be initialized. */ gcc_assert (TREE_CODE (array_size) == INTEGER_CST); - + if (host_integerp (array_size, 0)) { HOST_WIDE_INT array_size_value = TREE_INT_CST_LOW (array_size); @@ -1380,21 +1411,16 @@ check_format_arg (void *ctx, tree format_tree, format_chars += offset; format_length -= offset; } - if (format_length < 1) + if (format_length < 1 || format_chars[--format_length] != 0) { res->number_unterminated++; return; } - if (format_length == 1) + if (format_length == 0) { res->number_empty++; return; } - if (format_chars[--format_length] != 0) - { - res->number_unterminated++; - return; - } /* Skip to first argument to check. */ while (arg_num + 1 < info->first_arg_num) @@ -1408,8 +1434,11 @@ check_format_arg (void *ctx, tree format_tree, will decrement it if it finds there are extra arguments, but this way need not adjust it for every return. */ res->number_other++; + fwt_pool = create_alloc_pool ("format_wanted_type pool", + sizeof (format_wanted_type), 10); check_format_info_main (res, info, format_chars, format_length, - params, arg_num); + params, arg_num, fwt_pool); + free_alloc_pool (fwt_pool); } @@ -1424,7 +1453,7 @@ static void check_format_info_main (format_check_results *res, function_format_info *info, const char *format_chars, int format_length, tree params, - unsigned HOST_WIDE_INT arg_num) + unsigned HOST_WIDE_INT arg_num, alloc_pool fwt_pool) { const char *orig_format_chars = format_chars; tree first_fillin_param = params; @@ -1461,12 +1490,12 @@ check_format_info_main (format_check_results *res, const format_length_info *fli = NULL; const format_char_info *fci = NULL; char flag_chars[256]; - int aflag = 0; + int alloc_flag = 0; const char *format_start = format_chars; if (*format_chars == 0) { if (format_chars - orig_format_chars != format_length) - warning (OPT_Wformat, "embedded %<\\0%> in format"); + warning (OPT_Wformat_contains_nul, "embedded %<\\0%> in format"); if (info->first_arg_num != 0 && params != 0 && has_operand_number <= 0) { @@ -1720,6 +1749,31 @@ check_format_info_main (format_check_results *res, } } + if (fki->alloc_char && fki->alloc_char == *format_chars) + { + i = strlen (flag_chars); + flag_chars[i++] = fki->alloc_char; + flag_chars[i] = 0; + format_chars++; + } + + /* Handle the scanf allocation kludge. */ + if (fki->flags & (int) FMT_FLAG_SCANF_A_KLUDGE) + { + if (*format_chars == 'a' && !flag_isoc99) + { + if (format_chars[1] == 's' || format_chars[1] == 'S' + || format_chars[1] == '[') + { + /* 'a' is used as a flag. */ + i = strlen (flag_chars); + flag_chars[i++] = 'a'; + flag_chars[i] = 0; + format_chars++; + } + } + } + /* Read any length modifier, if this kind of format has them. */ fli = fki->length_char_specs; length_chars = NULL; @@ -1727,11 +1781,12 @@ check_format_info_main (format_check_results *res, length_chars_std = STD_C89; if (fli) { - while (fli->name != 0 && fli->name[0] != *format_chars) - fli++; + while (fli->name != 0 + && strncmp (fli->name, format_chars, strlen (fli->name))) + fli++; if (fli->name != 0) { - format_chars++; + format_chars += strlen (fli->name); if (fli->double_name != 0 && fli->name[0] == *format_chars) { format_chars++; @@ -1782,23 +1837,6 @@ check_format_info_main (format_check_results *res, } } - /* Handle the scanf allocation kludge. */ - if (fki->flags & (int) FMT_FLAG_SCANF_A_KLUDGE) - { - if (*format_chars == 'a' && !flag_isoc99) - { - if (format_chars[1] == 's' || format_chars[1] == 'S' - || format_chars[1] == '[') - { - /* 'a' is used as a flag. */ - i = strlen (flag_chars); - flag_chars[i++] = 'a'; - flag_chars[i] = 0; - format_chars++; - } - } - } - format_char = *format_chars; if (format_char == 0 || (!(fki->flags & (int) FMT_FLAG_FANCY_PERCENT_OK) @@ -1814,7 +1852,7 @@ check_format_info_main (format_check_results *res, ++fci; if (fci->format_chars == 0) { - if (ISGRAPH (format_char)) + if (ISGRAPH (format_char)) warning (OPT_Wformat, "unknown conversion type character %qc in format", format_char); else @@ -1871,7 +1909,9 @@ check_format_info_main (format_check_results *res, if ((fki->flags & (int) FMT_FLAG_SCANF_A_KLUDGE) && strchr (flag_chars, 'a') != 0) - aflag = 1; + alloc_flag = 1; + if (fki->alloc_char && strchr (flag_chars, fki->alloc_char) != 0) + alloc_flag = 1; if (fki->suppression_char && strchr (flag_chars, fki->suppression_char) != 0) @@ -2043,13 +2083,13 @@ check_format_info_main (format_check_results *res, wanted_type_ptr->wanted_type = wanted_type; wanted_type_ptr->wanted_type_name = wanted_type_name; - wanted_type_ptr->pointer_count = fci->pointer_count + aflag; + wanted_type_ptr->pointer_count = fci->pointer_count + alloc_flag; wanted_type_ptr->char_lenient_flag = 0; if (strchr (fci->flags2, 'c') != 0) wanted_type_ptr->char_lenient_flag = 1; wanted_type_ptr->writing_in_flag = 0; wanted_type_ptr->reading_from_flag = 0; - if (aflag) + if (alloc_flag) wanted_type_ptr->writing_in_flag = 1; else { @@ -2071,7 +2111,8 @@ check_format_info_main (format_check_results *res, fci = fci->chain; if (fci) { - wanted_type_ptr = ggc_alloc (sizeof (main_wanted_type)); + wanted_type_ptr = (format_wanted_type *) + pool_alloc (fwt_pool); arg_num++; wanted_type = *fci->types[length_chars_val].type; wanted_type_name = fci->types[length_chars_val].name; @@ -2082,17 +2123,6 @@ check_format_info_main (format_check_results *res, if (first_wanted_type != 0) check_format_types (first_wanted_type, format_start, format_chars - format_start); - - if (main_wanted_type.next != NULL) - { - format_wanted_type *wanted_type_ptr = main_wanted_type.next; - while (wanted_type_ptr) - { - format_wanted_type *next = wanted_type_ptr->next; - ggc_free (wanted_type_ptr); - wanted_type_ptr = next; - } - } } } @@ -2215,7 +2245,7 @@ check_format_types (format_wanted_type *types, const char *format_start, || cur_type == unsigned_char_type_node); /* Check the type of the "real" argument, if there's a type we want. */ - if (wanted_type == cur_type) + if (lang_hooks.types_compatible_p (wanted_type, cur_type)) continue; /* If we want 'void *', allow any pointer type. (Anything else would already have got a warning.) @@ -2232,7 +2262,7 @@ check_format_types (format_wanted_type *types, const char *format_start, && TREE_CODE (cur_type) == INTEGER_TYPE && (!pedantic || i == 0 || (i == 1 && char_type_flag)) && (TYPE_UNSIGNED (wanted_type) - ? wanted_type == c_common_unsigned_type (cur_type) + ? wanted_type == unsigned_type_for (cur_type) : wanted_type == c_common_signed_type (cur_type))) continue; /* Likewise, "signed char", "unsigned char" and "char" are @@ -2280,7 +2310,7 @@ format_type_warning (const char *descr, const char *format_start, this is adequate, but formats taking pointers to functions or arrays would require the full type to be built up in order to print it with %T. */ - p = alloca (pointer_count + 2); + p = (char *) alloca (pointer_count + 2); if (pointer_count == 0) p[0] = 0; else if (c_dialect_cxx ()) @@ -2331,7 +2361,7 @@ find_char_info_specifier_index (const format_char_info *fci, int c) for (i = 0; fci->format_chars; i++, fci++) if (strchr (fci->format_chars, c)) return i; - + /* We shouldn't be looking for a non-existent specifier. */ gcc_unreachable (); } @@ -2347,7 +2377,7 @@ find_length_info_modifier_index (const format_length_info *fli, int c) for (i = 0; fli->name; i++, fli++) if (strchr (fli->name, c)) return i; - + /* We shouldn't be looking for a non-existent modifier. */ gcc_unreachable (); } @@ -2364,7 +2394,7 @@ init_dynamic_asm_fprintf_info (void) { format_length_info *new_asm_fprintf_length_specs; unsigned int i; - + /* Find the underlying type for HOST_WIDE_INT. For the %w length modifier to work, one must have issued: "typedef HOST_WIDE_INT __gcc_host_wide_int__;" in one's source code @@ -2418,7 +2448,7 @@ static void init_dynamic_gfc_info (void) { static tree locus; - + if (!locus) { static format_char_info *gfc_fci; @@ -2432,7 +2462,8 @@ init_dynamic_gfc_info (void) locus = identifier_global_value (locus); if (locus) { - if (TREE_CODE (locus) != TYPE_DECL) + if (TREE_CODE (locus) != TYPE_DECL + || TREE_TYPE (locus) == error_mark_node) { error ("% is not defined as a type"); locus = 0; @@ -2452,7 +2483,7 @@ init_dynamic_gfc_info (void) sizeof (gcc_gfc_char_table), sizeof (gcc_gfc_char_table)); if (locus) - { + { const unsigned i = find_char_info_specifier_index (gfc_fci, 'L'); gfc_fci[i].types[0].type = &locus; gfc_fci[i].pointer_count = 1; @@ -2516,7 +2547,7 @@ init_dynamic_diag_info (void) t = TREE_TYPE (TREE_TYPE (t)); } } - + /* Find the underlying type for HOST_WIDE_INT. For the %w length modifier to work, one must have issued: "typedef HOST_WIDE_INT __gcc_host_wide_int__;" in one's source code @@ -2545,7 +2576,7 @@ init_dynamic_diag_info (void) } } } - + /* Assign the new data for use. */ /* All the GCC diag formats use the same length specs. */ @@ -2557,9 +2588,9 @@ init_dynamic_diag_info (void) diag_ls = (format_length_info *) xmemdup (gcc_diag_length_specs, sizeof (gcc_diag_length_specs), - sizeof (gcc_diag_length_specs)); + sizeof (gcc_diag_length_specs)); if (hwi) - { + { /* HOST_WIDE_INT must be one of 'long' or 'long long'. */ i = find_length_info_modifier_index (diag_ls, 'w'); if (hwi == long_integer_type_node) @@ -2578,16 +2609,19 @@ init_dynamic_diag_info (void) sizeof (gcc_diag_char_table), sizeof (gcc_diag_char_table)); if (loc) - { + { i = find_char_info_specifier_index (diag_fci, 'H'); diag_fci[i].types[0].type = &loc; diag_fci[i].pointer_count = 1; } if (t) - { + { i = find_char_info_specifier_index (diag_fci, 'J'); diag_fci[i].types[0].type = &t; diag_fci[i].pointer_count = 1; + i = find_char_info_specifier_index (diag_fci, 'K'); + diag_fci[i].types[0].type = &t; + diag_fci[i].pointer_count = 1; } /* Handle the __gcc_tdiag__ format specifics. */ @@ -2598,13 +2632,13 @@ init_dynamic_diag_info (void) sizeof (gcc_tdiag_char_table), sizeof (gcc_tdiag_char_table)); if (loc) - { + { i = find_char_info_specifier_index (tdiag_fci, 'H'); tdiag_fci[i].types[0].type = &loc; tdiag_fci[i].pointer_count = 1; } if (t) - { + { /* All specifiers taking a tree share the same struct. */ i = find_char_info_specifier_index (tdiag_fci, 'D'); tdiag_fci[i].types[0].type = &t; @@ -2612,6 +2646,9 @@ init_dynamic_diag_info (void) i = find_char_info_specifier_index (tdiag_fci, 'J'); tdiag_fci[i].types[0].type = &t; tdiag_fci[i].pointer_count = 1; + i = find_char_info_specifier_index (tdiag_fci, 'K'); + tdiag_fci[i].types[0].type = &t; + tdiag_fci[i].pointer_count = 1; } /* Handle the __gcc_cdiag__ format specifics. */ @@ -2622,13 +2659,13 @@ init_dynamic_diag_info (void) sizeof (gcc_cdiag_char_table), sizeof (gcc_cdiag_char_table)); if (loc) - { + { i = find_char_info_specifier_index (cdiag_fci, 'H'); cdiag_fci[i].types[0].type = &loc; cdiag_fci[i].pointer_count = 1; } if (t) - { + { /* All specifiers taking a tree share the same struct. */ i = find_char_info_specifier_index (cdiag_fci, 'D'); cdiag_fci[i].types[0].type = &t; @@ -2636,6 +2673,9 @@ init_dynamic_diag_info (void) i = find_char_info_specifier_index (cdiag_fci, 'J'); cdiag_fci[i].types[0].type = &t; cdiag_fci[i].pointer_count = 1; + i = find_char_info_specifier_index (cdiag_fci, 'K'); + cdiag_fci[i].types[0].type = &t; + cdiag_fci[i].pointer_count = 1; } /* Handle the __gcc_cxxdiag__ format specifics. */ @@ -2646,13 +2686,13 @@ init_dynamic_diag_info (void) sizeof (gcc_cxxdiag_char_table), sizeof (gcc_cxxdiag_char_table)); if (loc) - { + { i = find_char_info_specifier_index (cxxdiag_fci, 'H'); cxxdiag_fci[i].types[0].type = &loc; cxxdiag_fci[i].pointer_count = 1; } if (t) - { + { /* All specifiers taking a tree share the same struct. */ i = find_char_info_specifier_index (cxxdiag_fci, 'D'); cxxdiag_fci[i].types[0].type = &t; @@ -2660,6 +2700,9 @@ init_dynamic_diag_info (void) i = find_char_info_specifier_index (cxxdiag_fci, 'J'); cxxdiag_fci[i].types[0].type = &t; cxxdiag_fci[i].pointer_count = 1; + i = find_char_info_specifier_index (cxxdiag_fci, 'K'); + cxxdiag_fci[i].types[0].type = &t; + cxxdiag_fci[i].pointer_count = 1; } } } @@ -2668,6 +2711,84 @@ init_dynamic_diag_info (void) extern const format_kind_info TARGET_FORMAT_TYPES[]; #endif +#ifdef TARGET_OVERRIDES_FORMAT_ATTRIBUTES +extern const target_ovr_attr TARGET_OVERRIDES_FORMAT_ATTRIBUTES[]; +#endif + +/* Attributes such as "printf" are equivalent to those such as + "gnu_printf" unless this is overridden by a target. */ +static const target_ovr_attr gnu_target_overrides_format_attributes[] = +{ + { "gnu_printf", "printf" }, + { "gnu_scanf", "scanf" }, + { "gnu_strftime", "strftime" }, + { "gnu_strfmon", "strfmon" }, + { NULL, NULL } +}; + +/* Translate to unified attribute name. This is used in decode_format_type and + decode_format_attr. In attr_name the user specified argument is passed. It + returns the unified format name from TARGET_OVERRIDES_FORMAT_ATTRIBUTES + or the attr_name passed to this function, if there is no matching entry. */ +static const char * +convert_format_name_to_system_name (const char *attr_name) +{ + int i; + + if (attr_name == NULL || *attr_name == 0 + || strncmp (attr_name, "gcc_", 4) == 0) + return attr_name; + +#ifdef TARGET_OVERRIDES_FORMAT_ATTRIBUTES + /* Check if format attribute is overridden by target. */ + if (TARGET_OVERRIDES_FORMAT_ATTRIBUTES != NULL + && TARGET_OVERRIDES_FORMAT_ATTRIBUTES_COUNT > 0) + { + for (i = 0; i < TARGET_OVERRIDES_FORMAT_ATTRIBUTES_COUNT; ++i) + { + if (cmp_attribs (TARGET_OVERRIDES_FORMAT_ATTRIBUTES[i].named_attr_src, + attr_name)) + return attr_name; + if (cmp_attribs (TARGET_OVERRIDES_FORMAT_ATTRIBUTES[i].named_attr_dst, + attr_name)) + return TARGET_OVERRIDES_FORMAT_ATTRIBUTES[i].named_attr_src; + } + } +#endif + /* Otherwise default to gnu format. */ + for (i = 0; + gnu_target_overrides_format_attributes[i].named_attr_src != NULL; + ++i) + { + if (cmp_attribs (gnu_target_overrides_format_attributes[i].named_attr_src, + attr_name)) + return attr_name; + if (cmp_attribs (gnu_target_overrides_format_attributes[i].named_attr_dst, + attr_name)) + return gnu_target_overrides_format_attributes[i].named_attr_src; + } + + return attr_name; +} + +/* Return true if TATTR_NAME and ATTR_NAME are the same format attribute, + counting "name" and "__name__" as the same, false otherwise. */ +static bool +cmp_attribs (const char *tattr_name, const char *attr_name) +{ + int alen = strlen (attr_name); + int slen = (tattr_name ? strlen (tattr_name) : 0); + if (alen > 4 && attr_name[0] == '_' && attr_name[1] == '_' + && attr_name[alen - 1] == '_' && attr_name[alen - 2] == '_') + { + attr_name += 2; + alen -= 4; + } + if (alen != slen || strncmp (tattr_name, attr_name, alen) != 0) + return false; + return true; +} + /* Handle a "format" attribute; arguments as in struct attribute_spec.handler. */ tree @@ -2683,8 +2804,8 @@ handle_format_attribute (tree *node, tree ARG_UNUSED (name), tree args, add them to FORMAT_TYPES at first use. */ if (TARGET_FORMAT_TYPES != NULL && !dynamic_format_types) { - dynamic_format_types = xmalloc ((n_format_types + TARGET_N_FORMAT_TYPES) - * sizeof (dynamic_format_types[0])); + dynamic_format_types = XNEWVEC (format_kind_info, + n_format_types + TARGET_N_FORMAT_TYPES); memcpy (dynamic_format_types, format_types_orig, sizeof (format_types_orig)); memcpy (&dynamic_format_types[n_format_types], TARGET_FORMAT_TYPES, @@ -2727,7 +2848,10 @@ handle_format_attribute (tree *node, tree ARG_UNUSED (name), tree args, } } - if (info.format_type == strftime_format_type && info.first_arg_num != 0) + /* Check if this is a strftime variant. Just for this variant + FMT_FLAG_ARG_CONVERT is not set. */ + if ((format_types[info.format_type].flags & (int) FMT_FLAG_ARG_CONVERT) == 0 + && info.first_arg_num != 0) { error ("strftime formats cannot format arguments"); *no_add_attrs = true; @@ -2744,14 +2868,14 @@ handle_format_attribute (tree *node, tree ARG_UNUSED (name), tree args, || info.format_type == gcc_cxxdiag_format_type) { /* Our first time through, we have to make sure that our - format_type data is allocated dynamically and is modifiable. */ + format_type data is allocated dynamically and is modifiable. */ if (!dynamic_format_types) format_types = dynamic_format_types = (format_kind_info *) xmemdup (format_types_orig, sizeof (format_types_orig), sizeof (format_types_orig)); /* If this is format __asm_fprintf__, we have to initialize - GCC's notion of HOST_WIDE_INT for checking %wd. */ + GCC's notion of HOST_WIDE_INT for checking %wd. */ if (info.format_type == asm_fprintf_format_type) init_dynamic_asm_fprintf_info (); /* If this is format __gcc_gfc__, we have to initialize GCC's @@ -2759,7 +2883,7 @@ handle_format_attribute (tree *node, tree ARG_UNUSED (name), tree args, else if (info.format_type == gcc_gfc_format_type) init_dynamic_gfc_info (); /* If this is one of the diagnostic attributes, then we have to - initialize 'location_t' and 'tree' at runtime. */ + initialize 'location_t' and 'tree' at runtime. */ else if (info.format_type == gcc_diag_format_type || info.format_type == gcc_tdiag_format_type || info.format_type == gcc_cdiag_format_type