OpenCores
URL https://opencores.org/ocsvn/scarts/scarts/trunk

Subversion Repositories scarts

[/] [scarts/] [trunk/] [toolchain/] [scarts-gcc/] [gcc-4.1.1/] [gcc/] [c-format.c] - Blame information for rev 12

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 12 jlechner
/* Check calls to formatted I/O functions (-Wformat).
2
   Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000,
3
   2001, 2002, 2003, 2004, 2005 Free Software Foundation, Inc.
4
 
5
This file is part of GCC.
6
 
7
GCC is free software; you can redistribute it and/or modify it under
8
the terms of the GNU General Public License as published by the Free
9
Software Foundation; either version 2, or (at your option) any later
10
version.
11
 
12
GCC is distributed in the hope that it will be useful, but WITHOUT ANY
13
WARRANTY; without even the implied warranty of MERCHANTABILITY or
14
FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
15
for more details.
16
 
17
You should have received a copy of the GNU General Public License
18
along with GCC; see the file COPYING.  If not, write to the Free
19
Software Foundation, 51 Franklin Street, Fifth Floor, Boston, MA
20
02110-1301, USA.  */
21
 
22
#include "config.h"
23
#include "system.h"
24
#include "coretypes.h"
25
#include "tm.h"
26
#include "tree.h"
27
#include "flags.h"
28
#include "c-common.h"
29
#include "toplev.h"
30
#include "intl.h"
31
#include "diagnostic.h"
32
#include "langhooks.h"
33
#include "c-format.h"
34
 
35
/* Set format warning options according to a -Wformat=n option.  */
36
 
37
void
38
set_Wformat (int setting)
39
{
40
  warn_format = setting;
41
  warn_format_extra_args = setting;
42
  warn_format_zero_length = setting;
43
  if (setting != 1)
44
    {
45
      warn_format_nonliteral = setting;
46
      warn_format_security = setting;
47
      warn_format_y2k = setting;
48
    }
49
  /* Make sure not to disable -Wnonnull if -Wformat=0 is specified.  */
50
  if (setting)
51
    warn_nonnull = setting;
52
}
53
 
54
 
55
/* Handle attributes associated with format checking.  */
56
 
57
/* This must be in the same order as format_types, except for
58
   format_type_error.  Target-specific format types do not have
59
   matching enum values.  */
60
enum format_type { printf_format_type, asm_fprintf_format_type,
61
                   gcc_diag_format_type, gcc_tdiag_format_type,
62
                   gcc_cdiag_format_type,
63
                   gcc_cxxdiag_format_type, gcc_gfc_format_type,
64
                   scanf_format_type, strftime_format_type,
65
                   strfmon_format_type, format_type_error = -1};
66
 
67
typedef struct function_format_info
68
{
69
  int format_type;                      /* type of format (printf, scanf, etc.) */
70
  unsigned HOST_WIDE_INT format_num;    /* number of format argument */
71
  unsigned HOST_WIDE_INT first_arg_num; /* number of first arg (zero for varargs) */
72
} function_format_info;
73
 
74
static bool decode_format_attr (tree, function_format_info *, int);
75
static int decode_format_type (const char *);
76
 
77
static bool check_format_string (tree argument,
78
                                 unsigned HOST_WIDE_INT format_num,
79
                                 int flags, bool *no_add_attrs);
80
static bool get_constant (tree expr, unsigned HOST_WIDE_INT *value,
81
                          int validated_p);
82
 
83
 
84
/* Handle a "format_arg" attribute; arguments as in
85
   struct attribute_spec.handler.  */
86
tree
87
handle_format_arg_attribute (tree *node, tree ARG_UNUSED (name),
88
                             tree args, int flags, bool *no_add_attrs)
89
{
90
  tree type = *node;
91
  tree format_num_expr = TREE_VALUE (args);
92
  unsigned HOST_WIDE_INT format_num = 0;
93
  tree argument;
94
 
95
  if (!get_constant (format_num_expr, &format_num, 0))
96
    {
97
      error ("format string has invalid operand number");
98
      *no_add_attrs = true;
99
      return NULL_TREE;
100
    }
101
 
102
  argument = TYPE_ARG_TYPES (type);
103
  if (argument)
104
    {
105
      if (!check_format_string (argument, format_num, flags, no_add_attrs))
106
        return NULL_TREE;
107
    }
108
 
109
  if (TREE_CODE (TREE_TYPE (type)) != POINTER_TYPE
110
      || (TYPE_MAIN_VARIANT (TREE_TYPE (TREE_TYPE (type)))
111
          != char_type_node))
112
    {
113
      if (!(flags & (int) ATTR_FLAG_BUILT_IN))
114
        error ("function does not return string type");
115
      *no_add_attrs = true;
116
      return NULL_TREE;
117
    }
118
 
119
  return NULL_TREE;
120
}
121
 
122
/* Verify that the format_num argument is actually a string, in case
123
   the format attribute is in error.  */
124
static bool
125
check_format_string (tree argument, unsigned HOST_WIDE_INT format_num,
126
                     int flags, bool *no_add_attrs)
127
{
128
  unsigned HOST_WIDE_INT i;
129
 
130
  for (i = 1; i != format_num; i++)
131
    {
132
      if (argument == 0)
133
        break;
134
      argument = TREE_CHAIN (argument);
135
    }
136
 
137
  if (!argument
138
      || TREE_CODE (TREE_VALUE (argument)) != POINTER_TYPE
139
      || (TYPE_MAIN_VARIANT (TREE_TYPE (TREE_VALUE (argument)))
140
          != char_type_node))
141
    {
142
      if (!(flags & (int) ATTR_FLAG_BUILT_IN))
143
        error ("format string argument not a string type");
144
      *no_add_attrs = true;
145
      return false;
146
    }
147
 
148
  return true;
149
}
150
 
151
/* Verify EXPR is a constant, and store its value.
152
   If validated_p is true there should be no errors.
153
   Returns true on success, false otherwise.  */
154
static bool
155
get_constant (tree expr, unsigned HOST_WIDE_INT *value, int validated_p)
156
{
157
  if (TREE_CODE (expr) != INTEGER_CST || TREE_INT_CST_HIGH (expr) != 0)
158
    {
159
      gcc_assert (!validated_p);
160
      return false;
161
    }
162
 
163
  *value = TREE_INT_CST_LOW (expr);
164
 
165
  return true;
166
}
167
 
168
/* Decode the arguments to a "format" attribute into a
169
   function_format_info structure.  It is already known that the list
170
   is of the right length.  If VALIDATED_P is true, then these
171
   attributes have already been validated and must not be erroneous;
172
   if false, it will give an error message.  Returns true if the
173
   attributes are successfully decoded, false otherwise.  */
174
 
175
static bool
176
decode_format_attr (tree args, function_format_info *info, int validated_p)
177
{
178
  tree format_type_id = TREE_VALUE (args);
179
  tree format_num_expr = TREE_VALUE (TREE_CHAIN (args));
180
  tree first_arg_num_expr
181
    = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (args)));
182
 
183
  if (TREE_CODE (format_type_id) != IDENTIFIER_NODE)
184
    {
185
      gcc_assert (!validated_p);
186
      error ("unrecognized format specifier");
187
      return false;
188
    }
189
  else
190
    {
191
      const char *p = IDENTIFIER_POINTER (format_type_id);
192
 
193
      info->format_type = decode_format_type (p);
194
 
195
      if (info->format_type == format_type_error)
196
        {
197
          gcc_assert (!validated_p);
198
          warning (OPT_Wformat, "%qE is an unrecognized format function type",
199
                   format_type_id);
200
          return false;
201
        }
202
    }
203
 
204
  if (!get_constant (format_num_expr, &info->format_num, validated_p))
205
    {
206
      error ("format string has invalid operand number");
207
      return false;
208
    }
209
 
210
  if (!get_constant (first_arg_num_expr, &info->first_arg_num, validated_p))
211
    {
212
      error ("%<...%> has invalid operand number");
213
      return false;
214
    }
215
 
216
  if (info->first_arg_num != 0 && info->first_arg_num <= info->format_num)
217
    {
218
      gcc_assert (!validated_p);
219
      error ("format string argument follows the args to be formatted");
220
      return false;
221
    }
222
 
223
  return true;
224
}
225
 
226
/* Check a call to a format function against a parameter list.  */
227
 
228
/* The C standard version C++ is treated as equivalent to
229
   or inheriting from, for the purpose of format features supported.  */
230
#define CPLUSPLUS_STD_VER       STD_C94
231
/* The C standard version we are checking formats against when pedantic.  */
232
#define C_STD_VER               ((int) (c_dialect_cxx ()                   \
233
                                 ? CPLUSPLUS_STD_VER                       \
234
                                 : (flag_isoc99                            \
235
                                    ? STD_C99                              \
236
                                    : (flag_isoc94 ? STD_C94 : STD_C89))))
237
/* The name to give to the standard version we are warning about when
238
   pedantic.  FEATURE_VER is the version in which the feature warned out
239
   appeared, which is higher than C_STD_VER.  */
240
#define C_STD_NAME(FEATURE_VER) (c_dialect_cxx ()               \
241
                                 ? "ISO C++"                    \
242
                                 : ((FEATURE_VER) == STD_EXT    \
243
                                    ? "ISO C"                   \
244
                                    : "ISO C90"))
245
/* Adjust a C standard version, which may be STD_C9L, to account for
246
   -Wno-long-long.  Returns other standard versions unchanged.  */
247
#define ADJ_STD(VER)            ((int) ((VER) == STD_C9L                      \
248
                                       ? (warn_long_long ? STD_C99 : STD_C89) \
249
                                       : (VER)))
250
 
251
/* Structure describing details of a type expected in format checking,
252
   and the type to check against it.  */
253
typedef struct format_wanted_type
254
{
255
  /* The type wanted.  */
256
  tree wanted_type;
257
  /* The name of this type to use in diagnostics.  */
258
  const char *wanted_type_name;
259
  /* The level of indirection through pointers at which this type occurs.  */
260
  int pointer_count;
261
  /* Whether, when pointer_count is 1, to allow any character type when
262
     pedantic, rather than just the character or void type specified.  */
263
  int char_lenient_flag;
264
  /* Whether the argument, dereferenced once, is written into and so the
265
     argument must not be a pointer to a const-qualified type.  */
266
  int writing_in_flag;
267
  /* Whether the argument, dereferenced once, is read from and so
268
     must not be a NULL pointer.  */
269
  int reading_from_flag;
270
  /* If warnings should be of the form "field precision should have
271
     type 'int'", the name to use (in this case "field precision"),
272
     otherwise NULL, for "format expects type 'long'" type
273
     messages.  */
274
  const char *name;
275
  /* The actual parameter to check against the wanted type.  */
276
  tree param;
277
  /* The argument number of that parameter.  */
278
  int arg_num;
279
  /* The next type to check for this format conversion, or NULL if none.  */
280
  struct format_wanted_type *next;
281
} format_wanted_type;
282
 
283
 
284
static const format_length_info printf_length_specs[] =
285
{
286
  { "h", FMT_LEN_h, STD_C89, "hh", FMT_LEN_hh, STD_C99 },
287
  { "l", FMT_LEN_l, STD_C89, "ll", FMT_LEN_ll, STD_C9L },
288
  { "q", FMT_LEN_ll, STD_EXT, NULL, 0, 0 },
289
  { "L", FMT_LEN_L, STD_C89, NULL, 0, 0 },
290
  { "z", FMT_LEN_z, STD_C99, NULL, 0, 0 },
291
  { "Z", FMT_LEN_z, STD_EXT, NULL, 0, 0 },
292
  { "t", FMT_LEN_t, STD_C99, NULL, 0, 0 },
293
  { "j", FMT_LEN_j, STD_C99, NULL, 0, 0 },
294
  { NULL, 0, 0, NULL, 0, 0 }
295
};
296
 
297
/* Length specifiers valid for asm_fprintf.  */
298
static const format_length_info asm_fprintf_length_specs[] =
299
{
300
  { "l", FMT_LEN_l, STD_C89, "ll", FMT_LEN_ll, STD_C89 },
301
  { "w", FMT_LEN_none, STD_C89, NULL, 0, 0 },
302
  { NULL, 0, 0, NULL, 0, 0 }
303
};
304
 
305
/* Length specifiers valid for GCC diagnostics.  */
306
static const format_length_info gcc_diag_length_specs[] =
307
{
308
  { "l", FMT_LEN_l, STD_C89, "ll", FMT_LEN_ll, STD_C89 },
309
  { "w", FMT_LEN_none, STD_C89, NULL, 0, 0 },
310
  { NULL, 0, 0, NULL, 0, 0 }
311
};
312
 
313
/* The custom diagnostics all accept the same length specifiers.  */
314
#define gcc_tdiag_length_specs gcc_diag_length_specs
315
#define gcc_cdiag_length_specs gcc_diag_length_specs
316
#define gcc_cxxdiag_length_specs gcc_diag_length_specs
317
 
318
/* This differs from printf_length_specs only in that "Z" is not accepted.  */
319
static const format_length_info scanf_length_specs[] =
320
{
321
  { "h", FMT_LEN_h, STD_C89, "hh", FMT_LEN_hh, STD_C99 },
322
  { "l", FMT_LEN_l, STD_C89, "ll", FMT_LEN_ll, STD_C9L },
323
  { "q", FMT_LEN_ll, STD_EXT, NULL, 0, 0 },
324
  { "L", FMT_LEN_L, STD_C89, NULL, 0, 0 },
325
  { "z", FMT_LEN_z, STD_C99, NULL, 0, 0 },
326
  { "t", FMT_LEN_t, STD_C99, NULL, 0, 0 },
327
  { "j", FMT_LEN_j, STD_C99, NULL, 0, 0 },
328
  { NULL, 0, 0, NULL, 0, 0 }
329
};
330
 
331
 
332
/* All tables for strfmon use STD_C89 everywhere, since -pedantic warnings
333
   make no sense for a format type not part of any C standard version.  */
334
static const format_length_info strfmon_length_specs[] =
335
{
336
  /* A GNU extension.  */
337
  { "L", FMT_LEN_L, STD_C89, NULL, 0, 0 },
338
  { NULL, 0, 0, NULL, 0, 0 }
339
};
340
 
341
static const format_flag_spec printf_flag_specs[] =
342
{
343
  { ' ',  0, 0, N_("' ' flag"),        N_("the ' ' printf flag"),              STD_C89 },
344
  { '+',  0, 0, N_("'+' flag"),        N_("the '+' printf flag"),              STD_C89 },
345
  { '#',  0, 0, N_("'#' flag"),        N_("the '#' printf flag"),              STD_C89 },
346
  { '0',  0, 0, N_("'0' flag"),        N_("the '0' printf flag"),              STD_C89 },
347
  { '-',  0, 0, N_("'-' flag"),        N_("the '-' printf flag"),              STD_C89 },
348
  { '\'', 0, 0, N_("''' flag"),        N_("the ''' printf flag"),              STD_EXT },
349
  { 'I',  0, 0, N_("'I' flag"),        N_("the 'I' printf flag"),              STD_EXT },
350
  { 'w',  0, 0, N_("field width"),     N_("field width in printf format"),     STD_C89 },
351
  { 'p',  0, 0, N_("precision"),       N_("precision in printf format"),       STD_C89 },
352
  { 'L',  0, 0, N_("length modifier"), N_("length modifier in printf format"), STD_C89 },
353
  { 0, 0, 0, NULL, NULL, 0 }
354
};
355
 
356
 
357
static const format_flag_pair printf_flag_pairs[] =
358
{
359
  { ' ', '+', 1, 0   },
360
  { '0', '-', 1, 0   },
361
  { '0', 'p', 1, 'i' },
362
  { 0, 0, 0, 0 }
363
};
364
 
365
static const format_flag_spec asm_fprintf_flag_specs[] =
366
{
367
  { ' ',  0, 0, N_("' ' flag"),        N_("the ' ' printf flag"),              STD_C89 },
368
  { '+',  0, 0, N_("'+' flag"),        N_("the '+' printf flag"),              STD_C89 },
369
  { '#',  0, 0, N_("'#' flag"),        N_("the '#' printf flag"),              STD_C89 },
370
  { '0',  0, 0, N_("'0' flag"),        N_("the '0' printf flag"),              STD_C89 },
371
  { '-',  0, 0, N_("'-' flag"),        N_("the '-' printf flag"),              STD_C89 },
372
  { 'w',  0, 0, N_("field width"),     N_("field width in printf format"),     STD_C89 },
373
  { 'p',  0, 0, N_("precision"),       N_("precision in printf format"),       STD_C89 },
374
  { 'L',  0, 0, N_("length modifier"), N_("length modifier in printf format"), STD_C89 },
375
  { 0, 0, 0, NULL, NULL, 0 }
376
};
377
 
378
static const format_flag_pair asm_fprintf_flag_pairs[] =
379
{
380
  { ' ', '+', 1, 0   },
381
  { '0', '-', 1, 0   },
382
  { '0', 'p', 1, 'i' },
383
  { 0, 0, 0, 0 }
384
};
385
 
386
static const format_flag_pair gcc_diag_flag_pairs[] =
387
{
388
  { 0, 0, 0, 0 }
389
};
390
 
391
#define gcc_tdiag_flag_pairs gcc_diag_flag_pairs
392
#define gcc_cdiag_flag_pairs gcc_diag_flag_pairs
393
#define gcc_cxxdiag_flag_pairs gcc_diag_flag_pairs
394
 
395
static const format_flag_pair gcc_gfc_flag_pairs[] =
396
{
397
  { 0, 0, 0, 0 }
398
};
399
 
400
static const format_flag_spec gcc_diag_flag_specs[] =
401
{
402
  { '+',  0, 0, N_("'+' flag"),        N_("the '+' printf flag"),              STD_C89 },
403
  { 'q',  0, 0, N_("'q' flag"),        N_("the 'q' diagnostic flag"),          STD_C89 },
404
  { 'p',  0, 0, N_("precision"),       N_("precision in printf format"),       STD_C89 },
405
  { 'L',  0, 0, N_("length modifier"), N_("length modifier in printf format"), STD_C89 },
406
  { 0, 0, 0, NULL, NULL, 0 }
407
};
408
 
409
#define gcc_tdiag_flag_specs gcc_diag_flag_specs
410
#define gcc_cdiag_flag_specs gcc_diag_flag_specs
411
 
412
static const format_flag_spec gcc_cxxdiag_flag_specs[] =
413
{
414
  { '+',  0, 0, N_("'+' flag"),        N_("the '+' printf flag"),              STD_C89 },
415
  { '#',  0, 0, N_("'#' flag"),        N_("the '#' printf flag"),              STD_C89 },
416
  { 'q',  0, 0, N_("'q' flag"),        N_("the 'q' diagnostic flag"),          STD_C89 },
417
  { 'p',  0, 0, N_("precision"),       N_("precision in printf format"),       STD_C89 },
418
  { 'L',  0, 0, N_("length modifier"), N_("length modifier in printf format"), STD_C89 },
419
  { 0, 0, 0, NULL, NULL, 0 }
420
};
421
 
422
static const format_flag_spec scanf_flag_specs[] =
423
{
424
  { '*',  0, 0, N_("assignment suppression"), N_("the assignment suppression scanf feature"), STD_C89 },
425
  { 'a',  0, 0, N_("'a' flag"),               N_("the 'a' scanf flag"),                       STD_EXT },
426
  { 'w',  0, 0, N_("field width"),            N_("field width in scanf format"),              STD_C89 },
427
  { 'L',  0, 0, N_("length modifier"),        N_("length modifier in scanf format"),          STD_C89 },
428
  { '\'', 0, 0, N_("''' flag"),               N_("the ''' scanf flag"),                       STD_EXT },
429
  { 'I',  0, 0, N_("'I' flag"),               N_("the 'I' scanf flag"),                       STD_EXT },
430
  { 0, 0, 0, NULL, NULL, 0 }
431
};
432
 
433
 
434
static const format_flag_pair scanf_flag_pairs[] =
435
{
436
  { '*', 'L', 0, 0 },
437
  { 0, 0, 0, 0 }
438
};
439
 
440
 
441
static const format_flag_spec strftime_flag_specs[] =
442
{
443
  { '_', 0,   0, N_("'_' flag"),     N_("the '_' strftime flag"),          STD_EXT },
444
  { '-', 0,   0, N_("'-' flag"),     N_("the '-' strftime flag"),          STD_EXT },
445
  { '0', 0,   0, N_("'0' flag"),     N_("the '0' strftime flag"),          STD_EXT },
446
  { '^', 0,   0, N_("'^' flag"),     N_("the '^' strftime flag"),          STD_EXT },
447
  { '#', 0,   0, N_("'#' flag"),     N_("the '#' strftime flag"),          STD_EXT },
448
  { 'w', 0,   0, N_("field width"),  N_("field width in strftime format"), STD_EXT },
449
  { 'E', 0,   0, N_("'E' modifier"), N_("the 'E' strftime modifier"),      STD_C99 },
450
  { 'O', 0,   0, N_("'O' modifier"), N_("the 'O' strftime modifier"),      STD_C99 },
451
  { 'O', 'o', 0, NULL,               N_("the 'O' modifier"),               STD_EXT },
452
  { 0, 0, 0, NULL, NULL, 0 }
453
};
454
 
455
 
456
static const format_flag_pair strftime_flag_pairs[] =
457
{
458
  { 'E', 'O', 0, 0 },
459
  { '_', '-', 0, 0 },
460
  { '_', '0', 0, 0 },
461
  { '-', '0', 0, 0 },
462
  { '^', '#', 0, 0 },
463
  { 0, 0, 0, 0 }
464
};
465
 
466
 
467
static const format_flag_spec strfmon_flag_specs[] =
468
{
469
  { '=',  0, 1, N_("fill character"),  N_("fill character in strfmon format"),  STD_C89 },
470
  { '^',  0, 0, N_("'^' flag"),        N_("the '^' strfmon flag"),              STD_C89 },
471
  { '+',  0, 0, N_("'+' flag"),        N_("the '+' strfmon flag"),              STD_C89 },
472
  { '(',  0, 0, N_("'(' flag"),        N_("the '(' strfmon flag"),              STD_C89 },
473
  { '!',  0, 0, N_("'!' flag"),        N_("the '!' strfmon flag"),              STD_C89 },
474
  { '-',  0, 0, N_("'-' flag"),        N_("the '-' strfmon flag"),              STD_C89 },
475
  { 'w',  0, 0, N_("field width"),     N_("field width in strfmon format"),     STD_C89 },
476
  { '#',  0, 0, N_("left precision"),  N_("left precision in strfmon format"),  STD_C89 },
477
  { 'p',  0, 0, N_("right precision"), N_("right precision in strfmon format"), STD_C89 },
478
  { 'L',  0, 0, N_("length modifier"), N_("length modifier in strfmon format"), STD_C89 },
479
  { 0, 0, 0, NULL, NULL, 0 }
480
};
481
 
482
static const format_flag_pair strfmon_flag_pairs[] =
483
{
484
  { '+', '(', 0, 0 },
485
  { 0, 0, 0, 0 }
486
};
487
 
488
 
489
static const format_char_info print_char_table[] =
490
{
491
  /* C89 conversion specifiers.  */
492
  { "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 },
493
  { "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 },
494
  { "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 },
495
  { "fgG", 0, STD_C89, { T89_D,   BADLEN,  BADLEN,  T99_D,   BADLEN,  T89_LD,  BADLEN,  BADLEN,  BADLEN  }, "-wp0 +#'I", "",   NULL },
496
  { "eE",  0, STD_C89, { T89_D,   BADLEN,  BADLEN,  T99_D,   BADLEN,  T89_LD,  BADLEN,  BADLEN,  BADLEN  }, "-wp0 +#I",  "",   NULL },
497
  { "c",   0, STD_C89, { T89_I,   BADLEN,  BADLEN,  T94_WI,  BADLEN,  BADLEN,  BADLEN,  BADLEN,  BADLEN  }, "-w",        "",   NULL },
498
  { "s",   1, STD_C89, { T89_C,   BADLEN,  BADLEN,  T94_W,   BADLEN,  BADLEN,  BADLEN,  BADLEN,  BADLEN  }, "-wp",       "cR", NULL },
499
  { "p",   1, STD_C89, { T89_V,   BADLEN,  BADLEN,  BADLEN,  BADLEN,  BADLEN,  BADLEN,  BADLEN,  BADLEN  }, "-w",        "c",  NULL },
500
  { "n",   1, STD_C89, { T89_I,   T99_SC,  T89_S,   T89_L,   T9L_LL,  BADLEN,  T99_SST, T99_PD,  T99_IM  }, "",          "W",  NULL },
501
  /* C99 conversion specifiers.  */
502
  { "F",   0, STD_C99, { T99_D,   BADLEN,  BADLEN,  T99_D,   BADLEN,  T99_LD,  BADLEN,  BADLEN,  BADLEN  }, "-wp0 +#'I", "",   NULL },
503
  { "aA",  0, STD_C99, { T99_D,   BADLEN,  BADLEN,  T99_D,   BADLEN,  T99_LD,  BADLEN,  BADLEN,  BADLEN  }, "-wp0 +#",   "",   NULL },
504
  /* X/Open conversion specifiers.  */
505
  { "C",   0, STD_EXT, { TEX_WI,  BADLEN,  BADLEN,  BADLEN,  BADLEN,  BADLEN,  BADLEN,  BADLEN,  BADLEN  }, "-w",        "",   NULL },
506
  { "S",   1, STD_EXT, { TEX_W,   BADLEN,  BADLEN,  BADLEN,  BADLEN,  BADLEN,  BADLEN,  BADLEN,  BADLEN  }, "-wp",       "R",  NULL },
507
  /* GNU conversion specifiers.  */
508
  { "m",   0, STD_EXT, { T89_V,   BADLEN,  BADLEN,  BADLEN,  BADLEN,  BADLEN,  BADLEN,  BADLEN,  BADLEN  }, "-wp",       "",   NULL },
509
  { NULL,  0, 0, NOLENGTHS, NULL, NULL, NULL }
510
};
511
 
512
static const format_char_info asm_fprintf_char_table[] =
513
{
514
  /* C89 conversion specifiers.  */
515
  { "di",  0, STD_C89, { T89_I,   BADLEN,  BADLEN,  T89_L,   T9L_LL,  BADLEN,  BADLEN,  BADLEN,  BADLEN  }, "-wp0 +",  "i", NULL },
516
  { "oxX", 0, STD_C89, { T89_UI,  BADLEN,  BADLEN,  T89_UL,  T9L_ULL, BADLEN,  BADLEN,  BADLEN,  BADLEN  }, "-wp0#",   "i", NULL },
517
  { "u",   0, STD_C89, { T89_UI,  BADLEN,  BADLEN,  T89_UL,  T9L_ULL, BADLEN,  BADLEN,  BADLEN,  BADLEN  }, "-wp0",    "i", NULL },
518
  { "c",   0, STD_C89, { T89_I,   BADLEN,  BADLEN,  BADLEN,  BADLEN,  BADLEN,  BADLEN,  BADLEN,  BADLEN  }, "-w",       "", NULL },
519
  { "s",   1, STD_C89, { T89_C,   BADLEN,  BADLEN,  BADLEN,  BADLEN,  BADLEN,  BADLEN,  BADLEN,  BADLEN  }, "-wp",    "cR", NULL },
520
 
521
  /* asm_fprintf conversion specifiers.  */
522
  { "O",   0, STD_C89, NOARGUMENTS, "",      "",   NULL },
523
  { "R",   0, STD_C89, NOARGUMENTS, "",      "",   NULL },
524
  { "I",   0, STD_C89, NOARGUMENTS, "",      "",   NULL },
525
  { "L",   0, STD_C89, NOARGUMENTS, "",      "",   NULL },
526
  { "U",   0, STD_C89, NOARGUMENTS, "",      "",   NULL },
527
  { "r",   0, STD_C89, { T89_I,   BADLEN,  BADLEN,  BADLEN,  BADLEN,  BADLEN,  BADLEN,  BADLEN,  BADLEN  }, "",  "", NULL },
528
  { "@",   0, STD_C89, NOARGUMENTS, "",      "",   NULL },
529
  { NULL,  0, 0, NOLENGTHS, NULL, NULL, NULL }
530
};
531
 
532
static const format_char_info gcc_diag_char_table[] =
533
{
534
  /* C89 conversion specifiers.  */
535
  { "di",  0, STD_C89, { T89_I,   BADLEN,  BADLEN,  T89_L,   T9L_LL,  BADLEN,  BADLEN,  BADLEN,  BADLEN  }, "q",  "",   NULL },
536
  { "ox",  0, STD_C89, { T89_UI,  BADLEN,  BADLEN,  T89_UL,  T9L_ULL, BADLEN,  BADLEN,  BADLEN,  BADLEN  }, "q",  "",   NULL },
537
  { "u",   0, STD_C89, { T89_UI,  BADLEN,  BADLEN,  T89_UL,  T9L_ULL, BADLEN,  BADLEN,  BADLEN,  BADLEN  }, "q",  "",   NULL },
538
  { "c",   0, STD_C89, { T89_I,   BADLEN,  BADLEN,  BADLEN,  BADLEN,  BADLEN,  BADLEN,  BADLEN,  BADLEN  }, "q",  "",   NULL },
539
  { "s",   1, STD_C89, { T89_C,   BADLEN,  BADLEN,  BADLEN,  BADLEN,  BADLEN,  BADLEN,  BADLEN,  BADLEN  }, "pq", "cR", NULL },
540
  { "p",   1, STD_C89, { T89_V,   BADLEN,  BADLEN,  BADLEN,  BADLEN,  BADLEN,  BADLEN,  BADLEN,  BADLEN  }, "q",  "c",  NULL },
541
 
542
  /* Custom conversion specifiers.  */
543
 
544
  /* %H will require "location_t" at runtime.  */
545
  { "H",   0, STD_C89, { T89_V,   BADLEN,  BADLEN,  BADLEN,  BADLEN,  BADLEN,  BADLEN,  BADLEN,  BADLEN  }, "q",  "",   NULL },
546
 
547
  /* These will require a "tree" at runtime.  */
548
  { "J", 0, STD_C89, { T89_V,   BADLEN,  BADLEN,  BADLEN,  BADLEN,  BADLEN,  BADLEN,  BADLEN,  BADLEN  }, "q",    "",   NULL },
549
 
550
  { "<>'", 0, STD_C89, NOARGUMENTS, "",      "",   NULL },
551
  { "m",   0, STD_C89, NOARGUMENTS, "q",     "",   NULL },
552
  { NULL,  0, 0, NOLENGTHS, NULL, NULL, NULL }
553
};
554
 
555
static const format_char_info gcc_tdiag_char_table[] =
556
{
557
  /* C89 conversion specifiers.  */
558
  { "di",  0, STD_C89, { T89_I,   BADLEN,  BADLEN,  T89_L,   T9L_LL,  BADLEN,  BADLEN,  BADLEN,  BADLEN  }, "q",  "",   NULL },
559
  { "ox",  0, STD_C89, { T89_UI,  BADLEN,  BADLEN,  T89_UL,  T9L_ULL, BADLEN,  BADLEN,  BADLEN,  BADLEN  }, "q",  "",   NULL },
560
  { "u",   0, STD_C89, { T89_UI,  BADLEN,  BADLEN,  T89_UL,  T9L_ULL, BADLEN,  BADLEN,  BADLEN,  BADLEN  }, "q",  "",   NULL },
561
  { "c",   0, STD_C89, { T89_I,   BADLEN,  BADLEN,  BADLEN,  BADLEN,  BADLEN,  BADLEN,  BADLEN,  BADLEN  }, "q",  "",   NULL },
562
  { "s",   1, STD_C89, { T89_C,   BADLEN,  BADLEN,  BADLEN,  BADLEN,  BADLEN,  BADLEN,  BADLEN,  BADLEN  }, "pq", "cR", NULL },
563
  { "p",   1, STD_C89, { T89_V,   BADLEN,  BADLEN,  BADLEN,  BADLEN,  BADLEN,  BADLEN,  BADLEN,  BADLEN  }, "q",  "c",  NULL },
564
 
565
  /* Custom conversion specifiers.  */
566
 
567
  /* %H will require "location_t" at runtime.  */
568
  { "H",   0, STD_C89, { T89_V,   BADLEN,  BADLEN,  BADLEN,  BADLEN,  BADLEN,  BADLEN,  BADLEN,  BADLEN  }, "q",  "",   NULL },
569
 
570
  /* These will require a "tree" at runtime.  */
571
  { "DFJT", 0, STD_C89, { T89_V,   BADLEN,  BADLEN,  BADLEN,  BADLEN,  BADLEN,  BADLEN,  BADLEN,  BADLEN  }, "q+", "",   NULL },
572
 
573
  { "<>'", 0, STD_C89, NOARGUMENTS, "",      "",   NULL },
574
  { "m",   0, STD_C89, NOARGUMENTS, "q",     "",   NULL },
575
  { NULL,  0, 0, NOLENGTHS, NULL, NULL, NULL }
576
};
577
 
578
static const format_char_info gcc_cdiag_char_table[] =
579
{
580
  /* C89 conversion specifiers.  */
581
  { "di",  0, STD_C89, { T89_I,   BADLEN,  BADLEN,  T89_L,   T9L_LL,  BADLEN,  BADLEN,  BADLEN,  BADLEN  }, "q",  "",   NULL },
582
  { "ox",  0, STD_C89, { T89_UI,  BADLEN,  BADLEN,  T89_UL,  T9L_ULL, BADLEN,  BADLEN,  BADLEN,  BADLEN  }, "q",  "",   NULL },
583
  { "u",   0, STD_C89, { T89_UI,  BADLEN,  BADLEN,  T89_UL,  T9L_ULL, BADLEN,  BADLEN,  BADLEN,  BADLEN  }, "q",  "",   NULL },
584
  { "c",   0, STD_C89, { T89_I,   BADLEN,  BADLEN,  BADLEN,  BADLEN,  BADLEN,  BADLEN,  BADLEN,  BADLEN  }, "q",  "",   NULL },
585
  { "s",   1, STD_C89, { T89_C,   BADLEN,  BADLEN,  BADLEN,  BADLEN,  BADLEN,  BADLEN,  BADLEN,  BADLEN  }, "pq", "cR", NULL },
586
  { "p",   1, STD_C89, { T89_V,   BADLEN,  BADLEN,  BADLEN,  BADLEN,  BADLEN,  BADLEN,  BADLEN,  BADLEN  }, "q",  "c",  NULL },
587
 
588
  /* Custom conversion specifiers.  */
589
 
590
  /* %H will require "location_t" at runtime.  */
591
  { "H",   0, STD_C89, { T89_V,   BADLEN,  BADLEN,  BADLEN,  BADLEN,  BADLEN,  BADLEN,  BADLEN,  BADLEN  }, "q",  "",   NULL },
592
 
593
  /* These will require a "tree" at runtime.  */
594
  { "DEFJT", 0, STD_C89, { T89_V,   BADLEN,  BADLEN,  BADLEN,  BADLEN,  BADLEN,  BADLEN,  BADLEN,  BADLEN  }, "q+", "",   NULL },
595
 
596
  { "<>'", 0, STD_C89, NOARGUMENTS, "",      "",   NULL },
597
  { "m",   0, STD_C89, NOARGUMENTS, "q",     "",   NULL },
598
  { NULL,  0, 0, NOLENGTHS, NULL, NULL, NULL }
599
};
600
 
601
static const format_char_info gcc_cxxdiag_char_table[] =
602
{
603
  /* C89 conversion specifiers.  */
604
  { "di",  0, STD_C89, { T89_I,   BADLEN,  BADLEN,  T89_L,   T9L_LL,  BADLEN,  BADLEN,  BADLEN,  BADLEN  }, "q",  "",   NULL },
605
  { "ox",  0, STD_C89, { T89_UI,  BADLEN,  BADLEN,  T89_UL,  T9L_ULL, BADLEN,  BADLEN,  BADLEN,  BADLEN  }, "q",  "",   NULL },
606
  { "u",   0, STD_C89, { T89_UI,  BADLEN,  BADLEN,  T89_UL,  T9L_ULL, BADLEN,  BADLEN,  BADLEN,  BADLEN  }, "q",  "",   NULL },
607
  { "c",   0, STD_C89, { T89_I,   BADLEN,  BADLEN,  BADLEN,  BADLEN,  BADLEN,  BADLEN,  BADLEN,  BADLEN  }, "q",  "",   NULL },
608
  { "s",   1, STD_C89, { T89_C,   BADLEN,  BADLEN,  BADLEN,  BADLEN,  BADLEN,  BADLEN,  BADLEN,  BADLEN  }, "pq", "cR", NULL },
609
  { "p",   1, STD_C89, { T89_V,   BADLEN,  BADLEN,  BADLEN,  BADLEN,  BADLEN,  BADLEN,  BADLEN,  BADLEN  }, "q",  "c",  NULL },
610
 
611
  /* Custom conversion specifiers.  */
612
 
613
  /* %H will require "location_t" at runtime.  */
614
  { "H",   0, STD_C89, { T89_V,   BADLEN,  BADLEN,  BADLEN,  BADLEN,  BADLEN,  BADLEN,  BADLEN,  BADLEN  }, "q",  "",   NULL },
615
 
616
  /* These will require a "tree" at runtime.  */
617
  { "ADEFJTV",0,STD_C89,{ T89_V,   BADLEN,  BADLEN,  BADLEN,  BADLEN,  BADLEN,  BADLEN,  BADLEN,  BADLEN  }, "q+#",   "",   NULL },
618
 
619
  /* These accept either an 'int' or an 'enum tree_code' (which is handled as an 'int'.)  */
620
  { "CLOPQ",0,STD_C89, { T89_I,   BADLEN,  BADLEN,  BADLEN,  BADLEN,  BADLEN,  BADLEN,  BADLEN,  BADLEN  }, "q",  "",   NULL },
621
 
622
  { "<>'", 0, STD_C89, NOARGUMENTS, "",      "",   NULL },
623
  { "m",   0, STD_C89, NOARGUMENTS, "q",     "",   NULL },
624
  { NULL,  0, 0, NOLENGTHS, NULL, NULL, NULL }
625
};
626
 
627
static const format_char_info gcc_gfc_char_table[] =
628
{
629
  /* C89 conversion specifiers.  */
630
  { "di",  0, STD_C89, { T89_I,   BADLEN,  BADLEN,  BADLEN,  BADLEN,  BADLEN,  BADLEN,  BADLEN,  BADLEN  }, "", "", NULL },
631
  { "c",   0, STD_C89, { T89_I,   BADLEN,  BADLEN,  BADLEN,  BADLEN,  BADLEN,  BADLEN,  BADLEN,  BADLEN  }, "", "", NULL },
632
  { "s",   1, STD_C89, { T89_C,   BADLEN,  BADLEN,  BADLEN,  BADLEN,  BADLEN,  BADLEN,  BADLEN,  BADLEN  }, "", "cR", NULL },
633
 
634
  /* gfc conversion specifiers.  */
635
 
636
  { "C",   0, STD_C89, NOARGUMENTS, "",      "",   NULL },
637
 
638
  /* This will require a "locus" at runtime.  */
639
  { "L",   0, STD_C89, { T89_V,   BADLEN,  BADLEN,  BADLEN,  BADLEN,  BADLEN,  BADLEN,  BADLEN,  BADLEN  }, "", "R", NULL },
640
 
641
  { NULL,  0, 0, NOLENGTHS, NULL, NULL, NULL }
642
};
643
 
644
static const format_char_info scan_char_table[] =
645
{
646
  /* C89 conversion specifiers.  */
647
  { "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 },
648
  { "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 },
649
  { "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 },
650
  { "efgEG", 1, STD_C89, { T89_F,   BADLEN,  BADLEN,  T89_D,   BADLEN,  T89_LD,  BADLEN,  BADLEN,  BADLEN  }, "*w'",  "W",   NULL },
651
  { "c",     1, STD_C89, { T89_C,   BADLEN,  BADLEN,  T94_W,   BADLEN,  BADLEN,  BADLEN,  BADLEN,  BADLEN  }, "*w",   "cW",  NULL },
652
  { "s",     1, STD_C89, { T89_C,   BADLEN,  BADLEN,  T94_W,   BADLEN,  BADLEN,  BADLEN,  BADLEN,  BADLEN  }, "*aw",  "cW",  NULL },
653
  { "[",     1, STD_C89, { T89_C,   BADLEN,  BADLEN,  T94_W,   BADLEN,  BADLEN,  BADLEN,  BADLEN,  BADLEN  }, "*aw",  "cW[", NULL },
654
  { "p",     2, STD_C89, { T89_V,   BADLEN,  BADLEN,  BADLEN,  BADLEN,  BADLEN,  BADLEN,  BADLEN,  BADLEN  }, "*w",   "W",   NULL },
655
  { "n",     1, STD_C89, { T89_I,   T99_SC,  T89_S,   T89_L,   T9L_LL,  BADLEN,  T99_SST, T99_PD,  T99_IM  }, "",     "W",   NULL },
656
  /* C99 conversion specifiers.  */
657
  { "FaA",   1, STD_C99, { T99_F,   BADLEN,  BADLEN,  T99_D,   BADLEN,  T99_LD,  BADLEN,  BADLEN,  BADLEN  }, "*w'",  "W",   NULL },
658
  /* X/Open conversion specifiers.  */
659
  { "C",     1, STD_EXT, { TEX_W,   BADLEN,  BADLEN,  BADLEN,  BADLEN,  BADLEN,  BADLEN,  BADLEN,  BADLEN  }, "*w",   "W",   NULL },
660
  { "S",     1, STD_EXT, { TEX_W,   BADLEN,  BADLEN,  BADLEN,  BADLEN,  BADLEN,  BADLEN,  BADLEN,  BADLEN  }, "*aw",  "W",   NULL },
661
  { NULL, 0, 0, NOLENGTHS, NULL, NULL, NULL }
662
};
663
 
664
static const format_char_info time_char_table[] =
665
{
666
  /* C89 conversion specifiers.  */
667
  { "ABZab",            0, STD_C89, NOLENGTHS, "^#",     "",   NULL },
668
  { "cx",               0, STD_C89, NOLENGTHS, "E",      "3",  NULL },
669
  { "HIMSUWdmw",        0, STD_C89, NOLENGTHS, "-_0Ow",  "",   NULL },
670
  { "j",                0, STD_C89, NOLENGTHS, "-_0Ow",  "o",  NULL },
671
  { "p",                0, STD_C89, NOLENGTHS, "#",      "",   NULL },
672
  { "X",                0, STD_C89, NOLENGTHS, "E",      "",   NULL },
673
  { "y",                0, STD_C89, NOLENGTHS, "EO-_0w", "4",  NULL },
674
  { "Y",                0, STD_C89, NOLENGTHS, "-_0EOw", "o",  NULL },
675
  { "%",                0, STD_C89, NOLENGTHS, "",       "",   NULL },
676
  /* C99 conversion specifiers.  */
677
  { "C",                0, STD_C99, NOLENGTHS, "-_0EOw", "o",  NULL },
678
  { "D",                0, STD_C99, NOLENGTHS, "",       "2",  NULL },
679
  { "eVu",              0, STD_C99, NOLENGTHS, "-_0Ow",  "",   NULL },
680
  { "FRTnrt",           0, STD_C99, NOLENGTHS, "",       "",   NULL },
681
  { "g",                0, STD_C99, NOLENGTHS, "O-_0w",  "2o", NULL },
682
  { "G",                0, STD_C99, NOLENGTHS, "-_0Ow",  "o",  NULL },
683
  { "h",                0, STD_C99, NOLENGTHS, "^#",     "",   NULL },
684
  { "z",                0, STD_C99, NOLENGTHS, "O",      "o",  NULL },
685
  /* GNU conversion specifiers.  */
686
  { "kls",              0, STD_EXT, NOLENGTHS, "-_0Ow",  "",   NULL },
687
  { "P",                0, STD_EXT, NOLENGTHS, "",       "",   NULL },
688
  { NULL,               0, 0, NOLENGTHS, NULL, NULL, NULL }
689
};
690
 
691
static const format_char_info monetary_char_table[] =
692
{
693
  { "in", 0, STD_C89, { T89_D, BADLEN, BADLEN, BADLEN, BADLEN, T89_LD, BADLEN, BADLEN, BADLEN }, "=^+(!-w#p", "", NULL },
694
  { NULL, 0, 0, NOLENGTHS, NULL, NULL, NULL }
695
};
696
 
697
/* This must be in the same order as enum format_type.  */
698
static const format_kind_info format_types_orig[] =
699
{
700
  { "printf",   printf_length_specs,  print_char_table, " +#0-'I", NULL,
701
    printf_flag_specs, printf_flag_pairs,
702
    FMT_FLAG_ARG_CONVERT|FMT_FLAG_DOLLAR_MULTIPLE|FMT_FLAG_USE_DOLLAR|FMT_FLAG_EMPTY_PREC_OK,
703
    'w', 0, 'p', 0, 'L',
704
    &integer_type_node, &integer_type_node
705
  },
706
  { "asm_fprintf",   asm_fprintf_length_specs,  asm_fprintf_char_table, " +#0-", NULL,
707
    asm_fprintf_flag_specs, asm_fprintf_flag_pairs,
708
    FMT_FLAG_ARG_CONVERT|FMT_FLAG_EMPTY_PREC_OK,
709
    'w', 0, 'p', 0, 'L',
710
    NULL, NULL
711
  },
712
  { "gcc_diag",   gcc_diag_length_specs,  gcc_diag_char_table, "q+", NULL,
713
    gcc_diag_flag_specs, gcc_diag_flag_pairs,
714
    FMT_FLAG_ARG_CONVERT,
715
    0, 0, 'p', 0, 'L',
716
    NULL, &integer_type_node
717
  },
718
  { "gcc_tdiag",   gcc_tdiag_length_specs,  gcc_tdiag_char_table, "q+", NULL,
719
    gcc_tdiag_flag_specs, gcc_tdiag_flag_pairs,
720
    FMT_FLAG_ARG_CONVERT,
721
    0, 0, 'p', 0, 'L',
722
    NULL, &integer_type_node
723
  },
724
  { "gcc_cdiag",   gcc_cdiag_length_specs,  gcc_cdiag_char_table, "q+", NULL,
725
    gcc_cdiag_flag_specs, gcc_cdiag_flag_pairs,
726
    FMT_FLAG_ARG_CONVERT,
727
    0, 0, 'p', 0, 'L',
728
    NULL, &integer_type_node
729
  },
730
  { "gcc_cxxdiag",   gcc_cxxdiag_length_specs,  gcc_cxxdiag_char_table, "q+#", NULL,
731
    gcc_cxxdiag_flag_specs, gcc_cxxdiag_flag_pairs,
732
    FMT_FLAG_ARG_CONVERT,
733
    0, 0, 'p', 0, 'L',
734
    NULL, &integer_type_node
735
  },
736
  { "gcc_gfc", NULL, gcc_gfc_char_table, "", NULL,
737
    NULL, gcc_gfc_flag_pairs,
738
    FMT_FLAG_ARG_CONVERT,
739
    0, 0, 0, 0, 0,
740
    NULL, NULL
741
  },
742
  { "scanf",    scanf_length_specs,   scan_char_table,  "*'I", NULL,
743
    scanf_flag_specs, scanf_flag_pairs,
744
    FMT_FLAG_ARG_CONVERT|FMT_FLAG_SCANF_A_KLUDGE|FMT_FLAG_USE_DOLLAR|FMT_FLAG_ZERO_WIDTH_BAD|FMT_FLAG_DOLLAR_GAP_POINTER_OK,
745
    'w', 0, 0, '*', 'L',
746
    NULL, NULL
747
  },
748
  { "strftime", NULL,                 time_char_table,  "_-0^#", "EO",
749
    strftime_flag_specs, strftime_flag_pairs,
750
    FMT_FLAG_FANCY_PERCENT_OK, 'w', 0, 0, 0, 0,
751
    NULL, NULL
752
  },
753
  { "strfmon",  strfmon_length_specs, monetary_char_table, "=^+(!-", NULL,
754
    strfmon_flag_specs, strfmon_flag_pairs,
755
    FMT_FLAG_ARG_CONVERT, 'w', '#', 'p', 0, 'L',
756
    NULL, NULL
757
  }
758
};
759
 
760
/* This layer of indirection allows GCC to reassign format_types with
761
   new data if necessary, while still allowing the original data to be
762
   const.  */
763
static const format_kind_info *format_types = format_types_orig;
764
/* We can modify this one.  We also add target-specific format types
765
   to the end of the array.  */
766
static format_kind_info *dynamic_format_types;
767
 
768
static int n_format_types = ARRAY_SIZE (format_types_orig);
769
 
770
/* Structure detailing the results of checking a format function call
771
   where the format expression may be a conditional expression with
772
   many leaves resulting from nested conditional expressions.  */
773
typedef struct
774
{
775
  /* Number of leaves of the format argument that could not be checked
776
     as they were not string literals.  */
777
  int number_non_literal;
778
  /* Number of leaves of the format argument that were null pointers or
779
     string literals, but had extra format arguments.  */
780
  int number_extra_args;
781
  /* Number of leaves of the format argument that were null pointers or
782
     string literals, but had extra format arguments and used $ operand
783
     numbers.  */
784
  int number_dollar_extra_args;
785
  /* Number of leaves of the format argument that were wide string
786
     literals.  */
787
  int number_wide;
788
  /* Number of leaves of the format argument that were empty strings.  */
789
  int number_empty;
790
  /* Number of leaves of the format argument that were unterminated
791
     strings.  */
792
  int number_unterminated;
793
  /* Number of leaves of the format argument that were not counted above.  */
794
  int number_other;
795
} format_check_results;
796
 
797
typedef struct
798
{
799
  format_check_results *res;
800
  function_format_info *info;
801
  tree params;
802
} format_check_context;
803
 
804
static void check_format_info (function_format_info *, tree);
805
static void check_format_arg (void *, tree, unsigned HOST_WIDE_INT);
806
static void check_format_info_main (format_check_results *,
807
                                    function_format_info *,
808
                                    const char *, int, tree,
809
                                    unsigned HOST_WIDE_INT);
810
 
811
static void init_dollar_format_checking (int, tree);
812
static int maybe_read_dollar_number (const char **, int,
813
                                     tree, tree *, const format_kind_info *);
814
static bool avoid_dollar_number (const char *);
815
static void finish_dollar_format_checking (format_check_results *, int);
816
 
817
static const format_flag_spec *get_flag_spec (const format_flag_spec *,
818
                                              int, const char *);
819
 
820
static void check_format_types (format_wanted_type *, const char *, int);
821
static void format_type_warning (const char *, const char *, int, tree,
822
                                 int, const char *, tree, int);
823
 
824
/* Decode a format type from a string, returning the type, or
825
   format_type_error if not valid, in which case the caller should print an
826
   error message.  */
827
static int
828
decode_format_type (const char *s)
829
{
830
  int i;
831
  int slen;
832
  slen = strlen (s);
833
  for (i = 0; i < n_format_types; i++)
834
    {
835
      int alen;
836
      if (!strcmp (s, format_types[i].name))
837
        return i;
838
      alen = strlen (format_types[i].name);
839
      if (slen == alen + 4 && s[0] == '_' && s[1] == '_'
840
          && s[slen - 1] == '_' && s[slen - 2] == '_'
841
          && !strncmp (s + 2, format_types[i].name, alen))
842
        return i;
843
    }
844
  return format_type_error;
845
}
846
 
847
 
848
/* Check the argument list of a call to printf, scanf, etc.
849
   ATTRS are the attributes on the function type.
850
   PARAMS is the list of argument values.  Also, if -Wmissing-format-attribute,
851
   warn for calls to vprintf or vscanf in functions with no such format
852
   attribute themselves.  */
853
 
854
void
855
check_function_format (tree attrs, tree params)
856
{
857
  tree a;
858
 
859
  /* See if this function has any format attributes.  */
860
  for (a = attrs; a; a = TREE_CHAIN (a))
861
    {
862
      if (is_attribute_p ("format", TREE_PURPOSE (a)))
863
        {
864
          /* Yup; check it.  */
865
          function_format_info info;
866
          decode_format_attr (TREE_VALUE (a), &info, 1);
867
          if (warn_format)
868
            check_format_info (&info, params);
869
          if (warn_missing_format_attribute && info.first_arg_num == 0
870
              && (format_types[info.format_type].flags
871
                  & (int) FMT_FLAG_ARG_CONVERT))
872
            {
873
              tree c;
874
              for (c = TYPE_ATTRIBUTES (TREE_TYPE (current_function_decl));
875
                   c;
876
                   c = TREE_CHAIN (c))
877
                if (is_attribute_p ("format", TREE_PURPOSE (c))
878
                    && (decode_format_type (IDENTIFIER_POINTER
879
                                            (TREE_VALUE (TREE_VALUE (c))))
880
                        == info.format_type))
881
                  break;
882
              if (c == NULL_TREE)
883
                {
884
                  /* Check if the current function has a parameter to which
885
                     the format attribute could be attached; if not, it
886
                     can't be a candidate for a format attribute, despite
887
                     the vprintf-like or vscanf-like call.  */
888
                  tree args;
889
                  for (args = DECL_ARGUMENTS (current_function_decl);
890
                       args != 0;
891
                       args = TREE_CHAIN (args))
892
                    {
893
                      if (TREE_CODE (TREE_TYPE (args)) == POINTER_TYPE
894
                          && (TYPE_MAIN_VARIANT (TREE_TYPE (TREE_TYPE (args)))
895
                              == char_type_node))
896
                        break;
897
                    }
898
                  if (args != 0)
899
                    warning (OPT_Wmissing_format_attribute, "function might "
900
                             "be possible candidate for %qs format attribute",
901
                             format_types[info.format_type].name);
902
                }
903
            }
904
        }
905
    }
906
}
907
 
908
 
909
/* Variables used by the checking of $ operand number formats.  */
910
static char *dollar_arguments_used = NULL;
911
static char *dollar_arguments_pointer_p = NULL;
912
static int dollar_arguments_alloc = 0;
913
static int dollar_arguments_count;
914
static int dollar_first_arg_num;
915
static int dollar_max_arg_used;
916
static int dollar_format_warned;
917
 
918
/* Initialize the checking for a format string that may contain $
919
   parameter number specifications; we will need to keep track of whether
920
   each parameter has been used.  FIRST_ARG_NUM is the number of the first
921
   argument that is a parameter to the format, or 0 for a vprintf-style
922
   function; PARAMS is the list of arguments starting at this argument.  */
923
 
924
static void
925
init_dollar_format_checking (int first_arg_num, tree params)
926
{
927
  tree oparams = params;
928
 
929
  dollar_first_arg_num = first_arg_num;
930
  dollar_arguments_count = 0;
931
  dollar_max_arg_used = 0;
932
  dollar_format_warned = 0;
933
  if (first_arg_num > 0)
934
    {
935
      while (params)
936
        {
937
          dollar_arguments_count++;
938
          params = TREE_CHAIN (params);
939
        }
940
    }
941
  if (dollar_arguments_alloc < dollar_arguments_count)
942
    {
943
      if (dollar_arguments_used)
944
        free (dollar_arguments_used);
945
      if (dollar_arguments_pointer_p)
946
        free (dollar_arguments_pointer_p);
947
      dollar_arguments_alloc = dollar_arguments_count;
948
      dollar_arguments_used = XNEWVEC (char, dollar_arguments_alloc);
949
      dollar_arguments_pointer_p = XNEWVEC (char, dollar_arguments_alloc);
950
    }
951
  if (dollar_arguments_alloc)
952
    {
953
      memset (dollar_arguments_used, 0, dollar_arguments_alloc);
954
      if (first_arg_num > 0)
955
        {
956
          int i = 0;
957
          params = oparams;
958
          while (params)
959
            {
960
              dollar_arguments_pointer_p[i] = (TREE_CODE (TREE_TYPE (TREE_VALUE (params)))
961
                                               == POINTER_TYPE);
962
              params = TREE_CHAIN (params);
963
              i++;
964
            }
965
        }
966
    }
967
}
968
 
969
 
970
/* Look for a decimal number followed by a $ in *FORMAT.  If DOLLAR_NEEDED
971
   is set, it is an error if one is not found; otherwise, it is OK.  If
972
   such a number is found, check whether it is within range and mark that
973
   numbered operand as being used for later checking.  Returns the operand
974
   number if found and within range, zero if no such number was found and
975
   this is OK, or -1 on error.  PARAMS points to the first operand of the
976
   format; PARAM_PTR is made to point to the parameter referred to.  If
977
   a $ format is found, *FORMAT is updated to point just after it.  */
978
 
979
static int
980
maybe_read_dollar_number (const char **format,
981
                          int dollar_needed, tree params, tree *param_ptr,
982
                          const format_kind_info *fki)
983
{
984
  int argnum;
985
  int overflow_flag;
986
  const char *fcp = *format;
987
  if (!ISDIGIT (*fcp))
988
    {
989
      if (dollar_needed)
990
        {
991
          warning (OPT_Wformat, "missing $ operand number in format");
992
          return -1;
993
        }
994
      else
995
        return 0;
996
    }
997
  argnum = 0;
998
  overflow_flag = 0;
999
  while (ISDIGIT (*fcp))
1000
    {
1001
      int nargnum;
1002
      nargnum = 10 * argnum + (*fcp - '0');
1003
      if (nargnum < 0 || nargnum / 10 != argnum)
1004
        overflow_flag = 1;
1005
      argnum = nargnum;
1006
      fcp++;
1007
    }
1008
  if (*fcp != '$')
1009
    {
1010
      if (dollar_needed)
1011
        {
1012
          warning (OPT_Wformat, "missing $ operand number in format");
1013
          return -1;
1014
        }
1015
      else
1016
        return 0;
1017
    }
1018
  *format = fcp + 1;
1019
  if (pedantic && !dollar_format_warned)
1020
    {
1021
      warning (OPT_Wformat, "%s does not support %%n$ operand number formats",
1022
               C_STD_NAME (STD_EXT));
1023
      dollar_format_warned = 1;
1024
    }
1025
  if (overflow_flag || argnum == 0
1026
      || (dollar_first_arg_num && argnum > dollar_arguments_count))
1027
    {
1028
      warning (OPT_Wformat, "operand number out of range in format");
1029
      return -1;
1030
    }
1031
  if (argnum > dollar_max_arg_used)
1032
    dollar_max_arg_used = argnum;
1033
  /* For vprintf-style functions we may need to allocate more memory to
1034
     track which arguments are used.  */
1035
  while (dollar_arguments_alloc < dollar_max_arg_used)
1036
    {
1037
      int nalloc;
1038
      nalloc = 2 * dollar_arguments_alloc + 16;
1039
      dollar_arguments_used = XRESIZEVEC (char, dollar_arguments_used,
1040
                                          nalloc);
1041
      dollar_arguments_pointer_p = XRESIZEVEC (char, dollar_arguments_pointer_p,
1042
                                               nalloc);
1043
      memset (dollar_arguments_used + dollar_arguments_alloc, 0,
1044
              nalloc - dollar_arguments_alloc);
1045
      dollar_arguments_alloc = nalloc;
1046
    }
1047
  if (!(fki->flags & (int) FMT_FLAG_DOLLAR_MULTIPLE)
1048
      && dollar_arguments_used[argnum - 1] == 1)
1049
    {
1050
      dollar_arguments_used[argnum - 1] = 2;
1051
      warning (OPT_Wformat, "format argument %d used more than once in %s format",
1052
               argnum, fki->name);
1053
    }
1054
  else
1055
    dollar_arguments_used[argnum - 1] = 1;
1056
  if (dollar_first_arg_num)
1057
    {
1058
      int i;
1059
      *param_ptr = params;
1060
      for (i = 1; i < argnum && *param_ptr != 0; i++)
1061
        *param_ptr = TREE_CHAIN (*param_ptr);
1062
 
1063
      /* This case shouldn't be caught here.  */
1064
      gcc_assert (*param_ptr);
1065
    }
1066
  else
1067
    *param_ptr = 0;
1068
  return argnum;
1069
}
1070
 
1071
/* Ensure that FORMAT does not start with a decimal number followed by
1072
   a $; give a diagnostic and return true if it does, false otherwise.  */
1073
 
1074
static bool
1075
avoid_dollar_number (const char *format)
1076
{
1077
  if (!ISDIGIT (*format))
1078
    return false;
1079
  while (ISDIGIT (*format))
1080
    format++;
1081
  if (*format == '$')
1082
    {
1083
      warning (OPT_Wformat, "$ operand number used after format without operand number");
1084
      return true;
1085
    }
1086
  return false;
1087
}
1088
 
1089
 
1090
/* Finish the checking for a format string that used $ operand number formats
1091
   instead of non-$ formats.  We check for unused operands before used ones
1092
   (a serious error, since the implementation of the format function
1093
   can't know what types to pass to va_arg to find the later arguments).
1094
   and for unused operands at the end of the format (if we know how many
1095
   arguments the format had, so not for vprintf).  If there were operand
1096
   numbers out of range on a non-vprintf-style format, we won't have reached
1097
   here.  If POINTER_GAP_OK, unused arguments are OK if all arguments are
1098
   pointers.  */
1099
 
1100
static void
1101
finish_dollar_format_checking (format_check_results *res, int pointer_gap_ok)
1102
{
1103
  int i;
1104
  bool found_pointer_gap = false;
1105
  for (i = 0; i < dollar_max_arg_used; i++)
1106
    {
1107
      if (!dollar_arguments_used[i])
1108
        {
1109
          if (pointer_gap_ok && (dollar_first_arg_num == 0
1110
                                 || dollar_arguments_pointer_p[i]))
1111
            found_pointer_gap = true;
1112
          else
1113
            warning (OPT_Wformat,
1114
                     "format argument %d unused before used argument %d in $-style format",
1115
                     i + 1, dollar_max_arg_used);
1116
        }
1117
    }
1118
  if (found_pointer_gap
1119
      || (dollar_first_arg_num
1120
          && dollar_max_arg_used < dollar_arguments_count))
1121
    {
1122
      res->number_other--;
1123
      res->number_dollar_extra_args++;
1124
    }
1125
}
1126
 
1127
 
1128
/* Retrieve the specification for a format flag.  SPEC contains the
1129
   specifications for format flags for the applicable kind of format.
1130
   FLAG is the flag in question.  If PREDICATES is NULL, the basic
1131
   spec for that flag must be retrieved and must exist.  If
1132
   PREDICATES is not NULL, it is a string listing possible predicates
1133
   for the spec entry; if an entry predicated on any of these is
1134
   found, it is returned, otherwise NULL is returned.  */
1135
 
1136
static const format_flag_spec *
1137
get_flag_spec (const format_flag_spec *spec, int flag, const char *predicates)
1138
{
1139
  int i;
1140
  for (i = 0; spec[i].flag_char != 0; i++)
1141
    {
1142
      if (spec[i].flag_char != flag)
1143
        continue;
1144
      if (predicates != NULL)
1145
        {
1146
          if (spec[i].predicate != 0
1147
              && strchr (predicates, spec[i].predicate) != 0)
1148
            return &spec[i];
1149
        }
1150
      else if (spec[i].predicate == 0)
1151
        return &spec[i];
1152
    }
1153
  gcc_assert (predicates);
1154
  return NULL;
1155
}
1156
 
1157
 
1158
/* Check the argument list of a call to printf, scanf, etc.
1159
   INFO points to the function_format_info structure.
1160
   PARAMS is the list of argument values.  */
1161
 
1162
static void
1163
check_format_info (function_format_info *info, tree params)
1164
{
1165
  format_check_context format_ctx;
1166
  unsigned HOST_WIDE_INT arg_num;
1167
  tree format_tree;
1168
  format_check_results res;
1169
  /* Skip to format argument.  If the argument isn't available, there's
1170
     no work for us to do; prototype checking will catch the problem.  */
1171
  for (arg_num = 1; ; ++arg_num)
1172
    {
1173
      if (params == 0)
1174
        return;
1175
      if (arg_num == info->format_num)
1176
        break;
1177
      params = TREE_CHAIN (params);
1178
    }
1179
  format_tree = TREE_VALUE (params);
1180
  params = TREE_CHAIN (params);
1181
  if (format_tree == 0)
1182
    return;
1183
 
1184
  res.number_non_literal = 0;
1185
  res.number_extra_args = 0;
1186
  res.number_dollar_extra_args = 0;
1187
  res.number_wide = 0;
1188
  res.number_empty = 0;
1189
  res.number_unterminated = 0;
1190
  res.number_other = 0;
1191
 
1192
  format_ctx.res = &res;
1193
  format_ctx.info = info;
1194
  format_ctx.params = params;
1195
 
1196
  check_function_arguments_recurse (check_format_arg, &format_ctx,
1197
                                    format_tree, arg_num);
1198
 
1199
  if (res.number_non_literal > 0)
1200
    {
1201
      /* Functions taking a va_list normally pass a non-literal format
1202
         string.  These functions typically are declared with
1203
         first_arg_num == 0, so avoid warning in those cases.  */
1204
      if (!(format_types[info->format_type].flags & (int) FMT_FLAG_ARG_CONVERT))
1205
        {
1206
          /* For strftime-like formats, warn for not checking the format
1207
             string; but there are no arguments to check.  */
1208
          warning (OPT_Wformat_nonliteral,
1209
                   "format not a string literal, format string not checked");
1210
        }
1211
      else if (info->first_arg_num != 0)
1212
        {
1213
          /* If there are no arguments for the format at all, we may have
1214
             printf (foo) which is likely to be a security hole.  */
1215
          while (arg_num + 1 < info->first_arg_num)
1216
            {
1217
              if (params == 0)
1218
                break;
1219
              params = TREE_CHAIN (params);
1220
              ++arg_num;
1221
            }
1222
          if (params == 0 && warn_format_security)
1223
            warning (OPT_Wformat_security,
1224
                     "format not a string literal and no format arguments");
1225
          else if (params == 0 && warn_format_nonliteral)
1226
            warning (OPT_Wformat_nonliteral,
1227
                     "format not a string literal and no format arguments");
1228
          else
1229
            warning (OPT_Wformat_nonliteral,
1230
                     "format not a string literal, argument types not checked");
1231
        }
1232
    }
1233
 
1234
  /* If there were extra arguments to the format, normally warn.  However,
1235
     the standard does say extra arguments are ignored, so in the specific
1236
     case where we have multiple leaves (conditional expressions or
1237
     ngettext) allow extra arguments if at least one leaf didn't have extra
1238
     arguments, but was otherwise OK (either non-literal or checked OK).
1239
     If the format is an empty string, this should be counted similarly to the
1240
     case of extra format arguments.  */
1241
  if (res.number_extra_args > 0 && res.number_non_literal == 0
1242
      && res.number_other == 0)
1243
    warning (OPT_Wformat_extra_args, "too many arguments for format");
1244
  if (res.number_dollar_extra_args > 0 && res.number_non_literal == 0
1245
      && res.number_other == 0)
1246
    warning (OPT_Wformat_extra_args, "unused arguments in $-style format");
1247
  if (res.number_empty > 0 && res.number_non_literal == 0
1248
      && res.number_other == 0)
1249
    warning (OPT_Wformat_zero_length, "zero-length %s format string",
1250
             format_types[info->format_type].name);
1251
 
1252
  if (res.number_wide > 0)
1253
    warning (OPT_Wformat, "format is a wide character string");
1254
 
1255
  if (res.number_unterminated > 0)
1256
    warning (OPT_Wformat, "unterminated format string");
1257
}
1258
 
1259
/* Callback from check_function_arguments_recurse to check a
1260
   format string.  FORMAT_TREE is the format parameter.  ARG_NUM
1261
   is the number of the format argument.  CTX points to a
1262
   format_check_context.  */
1263
 
1264
static void
1265
check_format_arg (void *ctx, tree format_tree,
1266
                  unsigned HOST_WIDE_INT arg_num)
1267
{
1268
  format_check_context *format_ctx = (format_check_context *) ctx;
1269
  format_check_results *res = format_ctx->res;
1270
  function_format_info *info = format_ctx->info;
1271
  tree params = format_ctx->params;
1272
 
1273
  int format_length;
1274
  HOST_WIDE_INT offset;
1275
  const char *format_chars;
1276
  tree array_size = 0;
1277
  tree array_init;
1278
 
1279
  if (integer_zerop (format_tree))
1280
    {
1281
      /* Skip to first argument to check, so we can see if this format
1282
         has any arguments (it shouldn't).  */
1283
      while (arg_num + 1 < info->first_arg_num)
1284
        {
1285
          if (params == 0)
1286
            return;
1287
          params = TREE_CHAIN (params);
1288
          ++arg_num;
1289
        }
1290
 
1291
      if (params == 0)
1292
        res->number_other++;
1293
      else
1294
        res->number_extra_args++;
1295
 
1296
      return;
1297
    }
1298
 
1299
  offset = 0;
1300
  if (TREE_CODE (format_tree) == PLUS_EXPR)
1301
    {
1302
      tree arg0, arg1;
1303
 
1304
      arg0 = TREE_OPERAND (format_tree, 0);
1305
      arg1 = TREE_OPERAND (format_tree, 1);
1306
      STRIP_NOPS (arg0);
1307
      STRIP_NOPS (arg1);
1308
      if (TREE_CODE (arg1) == INTEGER_CST)
1309
        format_tree = arg0;
1310
      else if (TREE_CODE (arg0) == INTEGER_CST)
1311
        {
1312
          format_tree = arg1;
1313
          arg1 = arg0;
1314
        }
1315
      else
1316
        {
1317
          res->number_non_literal++;
1318
          return;
1319
        }
1320
      if (!host_integerp (arg1, 0)
1321
          || (offset = tree_low_cst (arg1, 0)) < 0)
1322
        {
1323
          res->number_non_literal++;
1324
          return;
1325
        }
1326
    }
1327
  if (TREE_CODE (format_tree) != ADDR_EXPR)
1328
    {
1329
      res->number_non_literal++;
1330
      return;
1331
    }
1332
  format_tree = TREE_OPERAND (format_tree, 0);
1333
  if (TREE_CODE (format_tree) == ARRAY_REF
1334
      && host_integerp (TREE_OPERAND (format_tree, 1), 0)
1335
      && (offset += tree_low_cst (TREE_OPERAND (format_tree, 1), 0)) >= 0)
1336
    format_tree = TREE_OPERAND (format_tree, 0);
1337
  if (TREE_CODE (format_tree) == VAR_DECL
1338
      && TREE_CODE (TREE_TYPE (format_tree)) == ARRAY_TYPE
1339
      && (array_init = decl_constant_value (format_tree)) != format_tree
1340
      && TREE_CODE (array_init) == STRING_CST)
1341
    {
1342
      /* Extract the string constant initializer.  Note that this may include
1343
         a trailing NUL character that is not in the array (e.g.
1344
         const char a[3] = "foo";).  */
1345
      array_size = DECL_SIZE_UNIT (format_tree);
1346
      format_tree = array_init;
1347
    }
1348
  if (TREE_CODE (format_tree) != STRING_CST)
1349
    {
1350
      res->number_non_literal++;
1351
      return;
1352
    }
1353
  if (TYPE_MAIN_VARIANT (TREE_TYPE (TREE_TYPE (format_tree))) != char_type_node)
1354
    {
1355
      res->number_wide++;
1356
      return;
1357
    }
1358
  format_chars = TREE_STRING_POINTER (format_tree);
1359
  format_length = TREE_STRING_LENGTH (format_tree);
1360
  if (array_size != 0)
1361
    {
1362
      /* Variable length arrays can't be initialized.  */
1363
      gcc_assert (TREE_CODE (array_size) == INTEGER_CST);
1364
 
1365
      if (host_integerp (array_size, 0))
1366
        {
1367
          HOST_WIDE_INT array_size_value = TREE_INT_CST_LOW (array_size);
1368
          if (array_size_value > 0
1369
              && array_size_value == (int) array_size_value
1370
              && format_length > array_size_value)
1371
            format_length = array_size_value;
1372
        }
1373
    }
1374
  if (offset)
1375
    {
1376
      if (offset >= format_length)
1377
        {
1378
          res->number_non_literal++;
1379
          return;
1380
        }
1381
      format_chars += offset;
1382
      format_length -= offset;
1383
    }
1384
  if (format_length < 1)
1385
    {
1386
      res->number_unterminated++;
1387
      return;
1388
    }
1389
  if (format_length == 1)
1390
    {
1391
      res->number_empty++;
1392
      return;
1393
    }
1394
  if (format_chars[--format_length] != 0)
1395
    {
1396
      res->number_unterminated++;
1397
      return;
1398
    }
1399
 
1400
  /* Skip to first argument to check.  */
1401
  while (arg_num + 1 < info->first_arg_num)
1402
    {
1403
      if (params == 0)
1404
        return;
1405
      params = TREE_CHAIN (params);
1406
      ++arg_num;
1407
    }
1408
  /* Provisionally increment res->number_other; check_format_info_main
1409
     will decrement it if it finds there are extra arguments, but this way
1410
     need not adjust it for every return.  */
1411
  res->number_other++;
1412
  check_format_info_main (res, info, format_chars, format_length,
1413
                          params, arg_num);
1414
}
1415
 
1416
 
1417
/* Do the main part of checking a call to a format function.  FORMAT_CHARS
1418
   is the NUL-terminated format string (which at this point may contain
1419
   internal NUL characters); FORMAT_LENGTH is its length (excluding the
1420
   terminating NUL character).  ARG_NUM is one less than the number of
1421
   the first format argument to check; PARAMS points to that format
1422
   argument in the list of arguments.  */
1423
 
1424
static void
1425
check_format_info_main (format_check_results *res,
1426
                        function_format_info *info, const char *format_chars,
1427
                        int format_length, tree params,
1428
                        unsigned HOST_WIDE_INT arg_num)
1429
{
1430
  const char *orig_format_chars = format_chars;
1431
  tree first_fillin_param = params;
1432
 
1433
  const format_kind_info *fki = &format_types[info->format_type];
1434
  const format_flag_spec *flag_specs = fki->flag_specs;
1435
  const format_flag_pair *bad_flag_pairs = fki->bad_flag_pairs;
1436
 
1437
  /* -1 if no conversions taking an operand have been found; 0 if one has
1438
     and it didn't use $; 1 if $ formats are in use.  */
1439
  int has_operand_number = -1;
1440
 
1441
  init_dollar_format_checking (info->first_arg_num, first_fillin_param);
1442
 
1443
  while (1)
1444
    {
1445
      int i;
1446
      int suppressed = FALSE;
1447
      const char *length_chars = NULL;
1448
      enum format_lengths length_chars_val = FMT_LEN_none;
1449
      enum format_std_version length_chars_std = STD_C89;
1450
      int format_char;
1451
      tree cur_param;
1452
      tree wanted_type;
1453
      int main_arg_num = 0;
1454
      tree main_arg_params = 0;
1455
      enum format_std_version wanted_type_std;
1456
      const char *wanted_type_name;
1457
      format_wanted_type width_wanted_type;
1458
      format_wanted_type precision_wanted_type;
1459
      format_wanted_type main_wanted_type;
1460
      format_wanted_type *first_wanted_type = NULL;
1461
      format_wanted_type *last_wanted_type = NULL;
1462
      const format_length_info *fli = NULL;
1463
      const format_char_info *fci = NULL;
1464
      char flag_chars[256];
1465
      int aflag = 0;
1466
      const char *format_start = format_chars;
1467
      if (*format_chars == 0)
1468
        {
1469
          if (format_chars - orig_format_chars != format_length)
1470
            warning (OPT_Wformat, "embedded %<\\0%> in format");
1471
          if (info->first_arg_num != 0 && params != 0
1472
              && has_operand_number <= 0)
1473
            {
1474
              res->number_other--;
1475
              res->number_extra_args++;
1476
            }
1477
          if (has_operand_number > 0)
1478
            finish_dollar_format_checking (res, fki->flags & (int) FMT_FLAG_DOLLAR_GAP_POINTER_OK);
1479
          return;
1480
        }
1481
      if (*format_chars++ != '%')
1482
        continue;
1483
      if (*format_chars == 0)
1484
        {
1485
          warning (OPT_Wformat, "spurious trailing %<%%%> in format");
1486
          continue;
1487
        }
1488
      if (*format_chars == '%')
1489
        {
1490
          ++format_chars;
1491
          continue;
1492
        }
1493
      flag_chars[0] = 0;
1494
 
1495
      if ((fki->flags & (int) FMT_FLAG_USE_DOLLAR) && has_operand_number != 0)
1496
        {
1497
          /* Possibly read a $ operand number at the start of the format.
1498
             If one was previously used, one is required here.  If one
1499
             is not used here, we can't immediately conclude this is a
1500
             format without them, since it could be printf %m or scanf %*.  */
1501
          int opnum;
1502
          opnum = maybe_read_dollar_number (&format_chars, 0,
1503
                                            first_fillin_param,
1504
                                            &main_arg_params, fki);
1505
          if (opnum == -1)
1506
            return;
1507
          else if (opnum > 0)
1508
            {
1509
              has_operand_number = 1;
1510
              main_arg_num = opnum + info->first_arg_num - 1;
1511
            }
1512
        }
1513
      else if (fki->flags & FMT_FLAG_USE_DOLLAR)
1514
        {
1515
          if (avoid_dollar_number (format_chars))
1516
            return;
1517
        }
1518
 
1519
      /* Read any format flags, but do not yet validate them beyond removing
1520
         duplicates, since in general validation depends on the rest of
1521
         the format.  */
1522
      while (*format_chars != 0
1523
             && strchr (fki->flag_chars, *format_chars) != 0)
1524
        {
1525
          const format_flag_spec *s = get_flag_spec (flag_specs,
1526
                                                     *format_chars, NULL);
1527
          if (strchr (flag_chars, *format_chars) != 0)
1528
            {
1529
              warning (OPT_Wformat, "repeated %s in format", _(s->name));
1530
            }
1531
          else
1532
            {
1533
              i = strlen (flag_chars);
1534
              flag_chars[i++] = *format_chars;
1535
              flag_chars[i] = 0;
1536
            }
1537
          if (s->skip_next_char)
1538
            {
1539
              ++format_chars;
1540
              if (*format_chars == 0)
1541
                {
1542
                  warning (OPT_Wformat, "missing fill character at end of strfmon format");
1543
                  return;
1544
                }
1545
            }
1546
          ++format_chars;
1547
        }
1548
 
1549
      /* Read any format width, possibly * or *m$.  */
1550
      if (fki->width_char != 0)
1551
        {
1552
          if (fki->width_type != NULL && *format_chars == '*')
1553
            {
1554
              i = strlen (flag_chars);
1555
              flag_chars[i++] = fki->width_char;
1556
              flag_chars[i] = 0;
1557
              /* "...a field width...may be indicated by an asterisk.
1558
                 In this case, an int argument supplies the field width..."  */
1559
              ++format_chars;
1560
              if (has_operand_number != 0)
1561
                {
1562
                  int opnum;
1563
                  opnum = maybe_read_dollar_number (&format_chars,
1564
                                                    has_operand_number == 1,
1565
                                                    first_fillin_param,
1566
                                                    &params, fki);
1567
                  if (opnum == -1)
1568
                    return;
1569
                  else if (opnum > 0)
1570
                    {
1571
                      has_operand_number = 1;
1572
                      arg_num = opnum + info->first_arg_num - 1;
1573
                    }
1574
                  else
1575
                    has_operand_number = 0;
1576
                }
1577
              else
1578
                {
1579
                  if (avoid_dollar_number (format_chars))
1580
                    return;
1581
                }
1582
              if (info->first_arg_num != 0)
1583
                {
1584
                  if (params == 0)
1585
                    {
1586
                      warning (OPT_Wformat, "too few arguments for format");
1587
                      return;
1588
                    }
1589
                  cur_param = TREE_VALUE (params);
1590
                  if (has_operand_number <= 0)
1591
                    {
1592
                      params = TREE_CHAIN (params);
1593
                      ++arg_num;
1594
                    }
1595
                  width_wanted_type.wanted_type = *fki->width_type;
1596
                  width_wanted_type.wanted_type_name = NULL;
1597
                  width_wanted_type.pointer_count = 0;
1598
                  width_wanted_type.char_lenient_flag = 0;
1599
                  width_wanted_type.writing_in_flag = 0;
1600
                  width_wanted_type.reading_from_flag = 0;
1601
                  width_wanted_type.name = _("field width");
1602
                  width_wanted_type.param = cur_param;
1603
                  width_wanted_type.arg_num = arg_num;
1604
                  width_wanted_type.next = NULL;
1605
                  if (last_wanted_type != 0)
1606
                    last_wanted_type->next = &width_wanted_type;
1607
                  if (first_wanted_type == 0)
1608
                    first_wanted_type = &width_wanted_type;
1609
                  last_wanted_type = &width_wanted_type;
1610
                }
1611
            }
1612
          else
1613
            {
1614
              /* Possibly read a numeric width.  If the width is zero,
1615
                 we complain if appropriate.  */
1616
              int non_zero_width_char = FALSE;
1617
              int found_width = FALSE;
1618
              while (ISDIGIT (*format_chars))
1619
                {
1620
                  found_width = TRUE;
1621
                  if (*format_chars != '0')
1622
                    non_zero_width_char = TRUE;
1623
                  ++format_chars;
1624
                }
1625
              if (found_width && !non_zero_width_char &&
1626
                  (fki->flags & (int) FMT_FLAG_ZERO_WIDTH_BAD))
1627
                warning (OPT_Wformat, "zero width in %s format", fki->name);
1628
              if (found_width)
1629
                {
1630
                  i = strlen (flag_chars);
1631
                  flag_chars[i++] = fki->width_char;
1632
                  flag_chars[i] = 0;
1633
                }
1634
            }
1635
        }
1636
 
1637
      /* Read any format left precision (must be a number, not *).  */
1638
      if (fki->left_precision_char != 0 && *format_chars == '#')
1639
        {
1640
          ++format_chars;
1641
          i = strlen (flag_chars);
1642
          flag_chars[i++] = fki->left_precision_char;
1643
          flag_chars[i] = 0;
1644
          if (!ISDIGIT (*format_chars))
1645
            warning (OPT_Wformat, "empty left precision in %s format", fki->name);
1646
          while (ISDIGIT (*format_chars))
1647
            ++format_chars;
1648
        }
1649
 
1650
      /* Read any format precision, possibly * or *m$.  */
1651
      if (fki->precision_char != 0 && *format_chars == '.')
1652
        {
1653
          ++format_chars;
1654
          i = strlen (flag_chars);
1655
          flag_chars[i++] = fki->precision_char;
1656
          flag_chars[i] = 0;
1657
          if (fki->precision_type != NULL && *format_chars == '*')
1658
            {
1659
              /* "...a...precision...may be indicated by an asterisk.
1660
                 In this case, an int argument supplies the...precision."  */
1661
              ++format_chars;
1662
              if (has_operand_number != 0)
1663
                {
1664
                  int opnum;
1665
                  opnum = maybe_read_dollar_number (&format_chars,
1666
                                                    has_operand_number == 1,
1667
                                                    first_fillin_param,
1668
                                                    &params, fki);
1669
                  if (opnum == -1)
1670
                    return;
1671
                  else if (opnum > 0)
1672
                    {
1673
                      has_operand_number = 1;
1674
                      arg_num = opnum + info->first_arg_num - 1;
1675
                    }
1676
                  else
1677
                    has_operand_number = 0;
1678
                }
1679
              else
1680
                {
1681
                  if (avoid_dollar_number (format_chars))
1682
                    return;
1683
                }
1684
              if (info->first_arg_num != 0)
1685
                {
1686
                  if (params == 0)
1687
                    {
1688
                      warning (OPT_Wformat, "too few arguments for format");
1689
                      return;
1690
                    }
1691
                  cur_param = TREE_VALUE (params);
1692
                  if (has_operand_number <= 0)
1693
                    {
1694
                      params = TREE_CHAIN (params);
1695
                      ++arg_num;
1696
                    }
1697
                  precision_wanted_type.wanted_type = *fki->precision_type;
1698
                  precision_wanted_type.wanted_type_name = NULL;
1699
                  precision_wanted_type.pointer_count = 0;
1700
                  precision_wanted_type.char_lenient_flag = 0;
1701
                  precision_wanted_type.writing_in_flag = 0;
1702
                  precision_wanted_type.reading_from_flag = 0;
1703
                  precision_wanted_type.name = _("field precision");
1704
                  precision_wanted_type.param = cur_param;
1705
                  precision_wanted_type.arg_num = arg_num;
1706
                  precision_wanted_type.next = NULL;
1707
                  if (last_wanted_type != 0)
1708
                    last_wanted_type->next = &precision_wanted_type;
1709
                  if (first_wanted_type == 0)
1710
                    first_wanted_type = &precision_wanted_type;
1711
                  last_wanted_type = &precision_wanted_type;
1712
                }
1713
            }
1714
          else
1715
            {
1716
              if (!(fki->flags & (int) FMT_FLAG_EMPTY_PREC_OK)
1717
                  && !ISDIGIT (*format_chars))
1718
                warning (OPT_Wformat, "empty precision in %s format", fki->name);
1719
              while (ISDIGIT (*format_chars))
1720
                ++format_chars;
1721
            }
1722
        }
1723
 
1724
      /* Read any length modifier, if this kind of format has them.  */
1725
      fli = fki->length_char_specs;
1726
      length_chars = NULL;
1727
      length_chars_val = FMT_LEN_none;
1728
      length_chars_std = STD_C89;
1729
      if (fli)
1730
        {
1731
          while (fli->name != 0 && fli->name[0] != *format_chars)
1732
            fli++;
1733
          if (fli->name != 0)
1734
            {
1735
              format_chars++;
1736
              if (fli->double_name != 0 && fli->name[0] == *format_chars)
1737
                {
1738
                  format_chars++;
1739
                  length_chars = fli->double_name;
1740
                  length_chars_val = fli->double_index;
1741
                  length_chars_std = fli->double_std;
1742
                }
1743
              else
1744
                {
1745
                  length_chars = fli->name;
1746
                  length_chars_val = fli->index;
1747
                  length_chars_std = fli->std;
1748
                }
1749
              i = strlen (flag_chars);
1750
              flag_chars[i++] = fki->length_code_char;
1751
              flag_chars[i] = 0;
1752
            }
1753
          if (pedantic)
1754
            {
1755
              /* Warn if the length modifier is non-standard.  */
1756
              if (ADJ_STD (length_chars_std) > C_STD_VER)
1757
                warning (OPT_Wformat,
1758
                         "%s does not support the %qs %s length modifier",
1759
                         C_STD_NAME (length_chars_std), length_chars,
1760
                         fki->name);
1761
            }
1762
        }
1763
 
1764
      /* Read any modifier (strftime E/O).  */
1765
      if (fki->modifier_chars != NULL)
1766
        {
1767
          while (*format_chars != 0
1768
                 && strchr (fki->modifier_chars, *format_chars) != 0)
1769
            {
1770
              if (strchr (flag_chars, *format_chars) != 0)
1771
                {
1772
                  const format_flag_spec *s = get_flag_spec (flag_specs,
1773
                                                             *format_chars, NULL);
1774
                  warning (OPT_Wformat, "repeated %s in format", _(s->name));
1775
                }
1776
              else
1777
                {
1778
                  i = strlen (flag_chars);
1779
                  flag_chars[i++] = *format_chars;
1780
                  flag_chars[i] = 0;
1781
                }
1782
              ++format_chars;
1783
            }
1784
        }
1785
 
1786
      /* Handle the scanf allocation kludge.  */
1787
      if (fki->flags & (int) FMT_FLAG_SCANF_A_KLUDGE)
1788
        {
1789
          if (*format_chars == 'a' && !flag_isoc99)
1790
            {
1791
              if (format_chars[1] == 's' || format_chars[1] == 'S'
1792
                  || format_chars[1] == '[')
1793
                {
1794
                  /* 'a' is used as a flag.  */
1795
                  i = strlen (flag_chars);
1796
                  flag_chars[i++] = 'a';
1797
                  flag_chars[i] = 0;
1798
                  format_chars++;
1799
                }
1800
            }
1801
        }
1802
 
1803
      format_char = *format_chars;
1804
      if (format_char == 0
1805
          || (!(fki->flags & (int) FMT_FLAG_FANCY_PERCENT_OK)
1806
              && format_char == '%'))
1807
        {
1808
          warning (OPT_Wformat, "conversion lacks type at end of format");
1809
          continue;
1810
        }
1811
      format_chars++;
1812
      fci = fki->conversion_specs;
1813
      while (fci->format_chars != 0
1814
             && strchr (fci->format_chars, format_char) == 0)
1815
          ++fci;
1816
      if (fci->format_chars == 0)
1817
        {
1818
          if (ISGRAPH (format_char))
1819
            warning (OPT_Wformat, "unknown conversion type character %qc in format",
1820
                     format_char);
1821
          else
1822
            warning (OPT_Wformat, "unknown conversion type character 0x%x in format",
1823
                     format_char);
1824
          continue;
1825
        }
1826
      if (pedantic)
1827
        {
1828
          if (ADJ_STD (fci->std) > C_STD_VER)
1829
            warning (OPT_Wformat, "%s does not support the %<%%%c%> %s format",
1830
                     C_STD_NAME (fci->std), format_char, fki->name);
1831
        }
1832
 
1833
      /* Validate the individual flags used, removing any that are invalid.  */
1834
      {
1835
        int d = 0;
1836
        for (i = 0; flag_chars[i] != 0; i++)
1837
          {
1838
            const format_flag_spec *s = get_flag_spec (flag_specs,
1839
                                                       flag_chars[i], NULL);
1840
            flag_chars[i - d] = flag_chars[i];
1841
            if (flag_chars[i] == fki->length_code_char)
1842
              continue;
1843
            if (strchr (fci->flag_chars, flag_chars[i]) == 0)
1844
              {
1845
                warning (OPT_Wformat, "%s used with %<%%%c%> %s format",
1846
                         _(s->name), format_char, fki->name);
1847
                d++;
1848
                continue;
1849
              }
1850
            if (pedantic)
1851
              {
1852
                const format_flag_spec *t;
1853
                if (ADJ_STD (s->std) > C_STD_VER)
1854
                  warning (OPT_Wformat, "%s does not support %s",
1855
                           C_STD_NAME (s->std), _(s->long_name));
1856
                t = get_flag_spec (flag_specs, flag_chars[i], fci->flags2);
1857
                if (t != NULL && ADJ_STD (t->std) > ADJ_STD (s->std))
1858
                  {
1859
                    const char *long_name = (t->long_name != NULL
1860
                                             ? t->long_name
1861
                                             : s->long_name);
1862
                    if (ADJ_STD (t->std) > C_STD_VER)
1863
                      warning (OPT_Wformat,
1864
                               "%s does not support %s with the %<%%%c%> %s format",
1865
                               C_STD_NAME (t->std), _(long_name),
1866
                               format_char, fki->name);
1867
                  }
1868
              }
1869
          }
1870
        flag_chars[i - d] = 0;
1871
      }
1872
 
1873
      if ((fki->flags & (int) FMT_FLAG_SCANF_A_KLUDGE)
1874
          && strchr (flag_chars, 'a') != 0)
1875
        aflag = 1;
1876
 
1877
      if (fki->suppression_char
1878
          && strchr (flag_chars, fki->suppression_char) != 0)
1879
        suppressed = 1;
1880
 
1881
      /* Validate the pairs of flags used.  */
1882
      for (i = 0; bad_flag_pairs[i].flag_char1 != 0; i++)
1883
        {
1884
          const format_flag_spec *s, *t;
1885
          if (strchr (flag_chars, bad_flag_pairs[i].flag_char1) == 0)
1886
            continue;
1887
          if (strchr (flag_chars, bad_flag_pairs[i].flag_char2) == 0)
1888
            continue;
1889
          if (bad_flag_pairs[i].predicate != 0
1890
              && strchr (fci->flags2, bad_flag_pairs[i].predicate) == 0)
1891
            continue;
1892
          s = get_flag_spec (flag_specs, bad_flag_pairs[i].flag_char1, NULL);
1893
          t = get_flag_spec (flag_specs, bad_flag_pairs[i].flag_char2, NULL);
1894
          if (bad_flag_pairs[i].ignored)
1895
            {
1896
              if (bad_flag_pairs[i].predicate != 0)
1897
                warning (OPT_Wformat,
1898
                         "%s ignored with %s and %<%%%c%> %s format",
1899
                         _(s->name), _(t->name), format_char,
1900
                         fki->name);
1901
              else
1902
                warning (OPT_Wformat, "%s ignored with %s in %s format",
1903
                         _(s->name), _(t->name), fki->name);
1904
            }
1905
          else
1906
            {
1907
              if (bad_flag_pairs[i].predicate != 0)
1908
                warning (OPT_Wformat,
1909
                         "use of %s and %s together with %<%%%c%> %s format",
1910
                         _(s->name), _(t->name), format_char,
1911
                         fki->name);
1912
              else
1913
                warning (OPT_Wformat, "use of %s and %s together in %s format",
1914
                         _(s->name), _(t->name), fki->name);
1915
            }
1916
        }
1917
 
1918
      /* Give Y2K warnings.  */
1919
      if (warn_format_y2k)
1920
        {
1921
          int y2k_level = 0;
1922
          if (strchr (fci->flags2, '4') != 0)
1923
            if (strchr (flag_chars, 'E') != 0)
1924
              y2k_level = 3;
1925
            else
1926
              y2k_level = 2;
1927
          else if (strchr (fci->flags2, '3') != 0)
1928
            y2k_level = 3;
1929
          else if (strchr (fci->flags2, '2') != 0)
1930
            y2k_level = 2;
1931
          if (y2k_level == 3)
1932
            warning (OPT_Wformat_y2k, "%<%%%c%> yields only last 2 digits of "
1933
                     "year in some locales", format_char);
1934
          else if (y2k_level == 2)
1935
            warning (OPT_Wformat_y2k, "%<%%%c%> yields only last 2 digits of "
1936
                     "year", format_char);
1937
        }
1938
 
1939
      if (strchr (fci->flags2, '[') != 0)
1940
        {
1941
          /* Skip over scan set, in case it happens to have '%' in it.  */
1942
          if (*format_chars == '^')
1943
            ++format_chars;
1944
          /* Find closing bracket; if one is hit immediately, then
1945
             it's part of the scan set rather than a terminator.  */
1946
          if (*format_chars == ']')
1947
            ++format_chars;
1948
          while (*format_chars && *format_chars != ']')
1949
            ++format_chars;
1950
          if (*format_chars != ']')
1951
            /* The end of the format string was reached.  */
1952
            warning (OPT_Wformat, "no closing %<]%> for %<%%[%> format");
1953
        }
1954
 
1955
      wanted_type = 0;
1956
      wanted_type_name = 0;
1957
      if (fki->flags & (int) FMT_FLAG_ARG_CONVERT)
1958
        {
1959
          wanted_type = (fci->types[length_chars_val].type
1960
                         ? *fci->types[length_chars_val].type : 0);
1961
          wanted_type_name = fci->types[length_chars_val].name;
1962
          wanted_type_std = fci->types[length_chars_val].std;
1963
          if (wanted_type == 0)
1964
            {
1965
              warning (OPT_Wformat,
1966
                       "use of %qs length modifier with %qc type character",
1967
                       length_chars, format_char);
1968
              /* Heuristic: skip one argument when an invalid length/type
1969
                 combination is encountered.  */
1970
              arg_num++;
1971
              if (params == 0)
1972
                {
1973
                  warning (OPT_Wformat, "too few arguments for format");
1974
                  return;
1975
                }
1976
              params = TREE_CHAIN (params);
1977
              continue;
1978
            }
1979
          else if (pedantic
1980
                   /* Warn if non-standard, provided it is more non-standard
1981
                      than the length and type characters that may already
1982
                      have been warned for.  */
1983
                   && ADJ_STD (wanted_type_std) > ADJ_STD (length_chars_std)
1984
                   && ADJ_STD (wanted_type_std) > ADJ_STD (fci->std))
1985
            {
1986
              if (ADJ_STD (wanted_type_std) > C_STD_VER)
1987
                warning (OPT_Wformat,
1988
                         "%s does not support the %<%%%s%c%> %s format",
1989
                         C_STD_NAME (wanted_type_std), length_chars,
1990
                         format_char, fki->name);
1991
            }
1992
        }
1993
 
1994
      main_wanted_type.next = NULL;
1995
 
1996
      /* Finally. . .check type of argument against desired type!  */
1997
      if (info->first_arg_num == 0)
1998
        continue;
1999
      if ((fci->pointer_count == 0 && wanted_type == void_type_node)
2000
          || suppressed)
2001
        {
2002
          if (main_arg_num != 0)
2003
            {
2004
              if (suppressed)
2005
                warning (OPT_Wformat, "operand number specified with "
2006
                         "suppressed assignment");
2007
              else
2008
                warning (OPT_Wformat, "operand number specified for format "
2009
                         "taking no argument");
2010
            }
2011
        }
2012
      else
2013
        {
2014
          format_wanted_type *wanted_type_ptr;
2015
 
2016
          if (main_arg_num != 0)
2017
            {
2018
              arg_num = main_arg_num;
2019
              params = main_arg_params;
2020
            }
2021
          else
2022
            {
2023
              ++arg_num;
2024
              if (has_operand_number > 0)
2025
                {
2026
                  warning (OPT_Wformat, "missing $ operand number in format");
2027
                  return;
2028
                }
2029
              else
2030
                has_operand_number = 0;
2031
            }
2032
 
2033
          wanted_type_ptr = &main_wanted_type;
2034
          while (fci)
2035
            {
2036
              if (params == 0)
2037
                {
2038
                  warning (OPT_Wformat, "too few arguments for format");
2039
                  return;
2040
                }
2041
 
2042
              cur_param = TREE_VALUE (params);
2043
              params = TREE_CHAIN (params);
2044
 
2045
              wanted_type_ptr->wanted_type = wanted_type;
2046
              wanted_type_ptr->wanted_type_name = wanted_type_name;
2047
              wanted_type_ptr->pointer_count = fci->pointer_count + aflag;
2048
              wanted_type_ptr->char_lenient_flag = 0;
2049
              if (strchr (fci->flags2, 'c') != 0)
2050
                wanted_type_ptr->char_lenient_flag = 1;
2051
              wanted_type_ptr->writing_in_flag = 0;
2052
              wanted_type_ptr->reading_from_flag = 0;
2053
              if (aflag)
2054
                wanted_type_ptr->writing_in_flag = 1;
2055
              else
2056
                {
2057
                  if (strchr (fci->flags2, 'W') != 0)
2058
                    wanted_type_ptr->writing_in_flag = 1;
2059
                  if (strchr (fci->flags2, 'R') != 0)
2060
                    wanted_type_ptr->reading_from_flag = 1;
2061
                }
2062
              wanted_type_ptr->name = NULL;
2063
              wanted_type_ptr->param = cur_param;
2064
              wanted_type_ptr->arg_num = arg_num;
2065
              wanted_type_ptr->next = NULL;
2066
              if (last_wanted_type != 0)
2067
                last_wanted_type->next = wanted_type_ptr;
2068
              if (first_wanted_type == 0)
2069
                first_wanted_type = wanted_type_ptr;
2070
              last_wanted_type = wanted_type_ptr;
2071
 
2072
              fci = fci->chain;
2073
              if (fci)
2074
                {
2075
                  wanted_type_ptr = ggc_alloc (sizeof (main_wanted_type));
2076
                  arg_num++;
2077
                  wanted_type = *fci->types[length_chars_val].type;
2078
                  wanted_type_name = fci->types[length_chars_val].name;
2079
                }
2080
            }
2081
        }
2082
 
2083
      if (first_wanted_type != 0)
2084
        check_format_types (first_wanted_type, format_start,
2085
                            format_chars - format_start);
2086
 
2087
      if (main_wanted_type.next != NULL)
2088
        {
2089
          format_wanted_type *wanted_type_ptr = main_wanted_type.next;
2090
          while (wanted_type_ptr)
2091
            {
2092
              format_wanted_type *next = wanted_type_ptr->next;
2093
              ggc_free (wanted_type_ptr);
2094
              wanted_type_ptr = next;
2095
            }
2096
        }
2097
    }
2098
}
2099
 
2100
 
2101
/* Check the argument types from a single format conversion (possibly
2102
   including width and precision arguments).  */
2103
static void
2104
check_format_types (format_wanted_type *types, const char *format_start,
2105
                    int format_length)
2106
{
2107
  for (; types != 0; types = types->next)
2108
    {
2109
      tree cur_param;
2110
      tree cur_type;
2111
      tree orig_cur_type;
2112
      tree wanted_type;
2113
      int arg_num;
2114
      int i;
2115
      int char_type_flag;
2116
      cur_param = types->param;
2117
      cur_type = TREE_TYPE (cur_param);
2118
      if (cur_type == error_mark_node)
2119
        continue;
2120
      orig_cur_type = cur_type;
2121
      char_type_flag = 0;
2122
      wanted_type = types->wanted_type;
2123
      arg_num = types->arg_num;
2124
 
2125
      /* The following should not occur here.  */
2126
      gcc_assert (wanted_type);
2127
      gcc_assert (wanted_type != void_type_node || types->pointer_count);
2128
 
2129
      if (types->pointer_count == 0)
2130
        wanted_type = lang_hooks.types.type_promotes_to (wanted_type);
2131
 
2132
      wanted_type = TYPE_MAIN_VARIANT (wanted_type);
2133
 
2134
      STRIP_NOPS (cur_param);
2135
 
2136
      /* Check the types of any additional pointer arguments
2137
         that precede the "real" argument.  */
2138
      for (i = 0; i < types->pointer_count; ++i)
2139
        {
2140
          if (TREE_CODE (cur_type) == POINTER_TYPE)
2141
            {
2142
              cur_type = TREE_TYPE (cur_type);
2143
              if (cur_type == error_mark_node)
2144
                break;
2145
 
2146
              /* Check for writing through a NULL pointer.  */
2147
              if (types->writing_in_flag
2148
                  && i == 0
2149
                  && cur_param != 0
2150
                  && integer_zerop (cur_param))
2151
                warning (OPT_Wformat, "writing through null pointer "
2152
                         "(argument %d)", arg_num);
2153
 
2154
              /* Check for reading through a NULL pointer.  */
2155
              if (types->reading_from_flag
2156
                  && i == 0
2157
                  && cur_param != 0
2158
                  && integer_zerop (cur_param))
2159
                warning (OPT_Wformat, "reading through null pointer "
2160
                         "(argument %d)", arg_num);
2161
 
2162
              if (cur_param != 0 && TREE_CODE (cur_param) == ADDR_EXPR)
2163
                cur_param = TREE_OPERAND (cur_param, 0);
2164
              else
2165
                cur_param = 0;
2166
 
2167
              /* See if this is an attempt to write into a const type with
2168
                 scanf or with printf "%n".  Note: the writing in happens
2169
                 at the first indirection only, if for example
2170
                 void * const * is passed to scanf %p; passing
2171
                 const void ** is simply passing an incompatible type.  */
2172
              if (types->writing_in_flag
2173
                  && i == 0
2174
                  && (TYPE_READONLY (cur_type)
2175
                      || (cur_param != 0
2176
                          && (CONSTANT_CLASS_P (cur_param)
2177
                              || (DECL_P (cur_param)
2178
                                  && TREE_READONLY (cur_param))))))
2179
                warning (OPT_Wformat, "writing into constant object "
2180
                         "(argument %d)", arg_num);
2181
 
2182
              /* If there are extra type qualifiers beyond the first
2183
                 indirection, then this makes the types technically
2184
                 incompatible.  */
2185
              if (i > 0
2186
                  && pedantic
2187
                  && (TYPE_READONLY (cur_type)
2188
                      || TYPE_VOLATILE (cur_type)
2189
                      || TYPE_RESTRICT (cur_type)))
2190
                warning (OPT_Wformat, "extra type qualifiers in format "
2191
                         "argument (argument %d)",
2192
                         arg_num);
2193
 
2194
            }
2195
          else
2196
            {
2197
              format_type_warning (types->name, format_start, format_length,
2198
                                   wanted_type, types->pointer_count,
2199
                                   types->wanted_type_name, orig_cur_type,
2200
                                   arg_num);
2201
              break;
2202
            }
2203
        }
2204
 
2205
      if (i < types->pointer_count)
2206
        continue;
2207
 
2208
      cur_type = TYPE_MAIN_VARIANT (cur_type);
2209
 
2210
      /* Check whether the argument type is a character type.  This leniency
2211
         only applies to certain formats, flagged with 'c'.
2212
      */
2213
      if (types->char_lenient_flag)
2214
        char_type_flag = (cur_type == char_type_node
2215
                          || cur_type == signed_char_type_node
2216
                          || cur_type == unsigned_char_type_node);
2217
 
2218
      /* Check the type of the "real" argument, if there's a type we want.  */
2219
      if (lang_hooks.types_compatible_p (wanted_type, cur_type))
2220
        continue;
2221
      /* If we want 'void *', allow any pointer type.
2222
         (Anything else would already have got a warning.)
2223
         With -pedantic, only allow pointers to void and to character
2224
         types.  */
2225
      if (wanted_type == void_type_node
2226
          && (!pedantic || (i == 1 && char_type_flag)))
2227
        continue;
2228
      /* Don't warn about differences merely in signedness, unless
2229
         -pedantic.  With -pedantic, warn if the type is a pointer
2230
         target and not a character type, and for character types at
2231
         a second level of indirection.  */
2232
      if (TREE_CODE (wanted_type) == INTEGER_TYPE
2233
          && TREE_CODE (cur_type) == INTEGER_TYPE
2234
          && (!pedantic || i == 0 || (i == 1 && char_type_flag))
2235
          && (TYPE_UNSIGNED (wanted_type)
2236
              ? wanted_type == c_common_unsigned_type (cur_type)
2237
              : wanted_type == c_common_signed_type (cur_type)))
2238
        continue;
2239
      /* Likewise, "signed char", "unsigned char" and "char" are
2240
         equivalent but the above test won't consider them equivalent.  */
2241
      if (wanted_type == char_type_node
2242
          && (!pedantic || i < 2)
2243
          && char_type_flag)
2244
        continue;
2245
      /* Now we have a type mismatch.  */
2246
      format_type_warning (types->name, format_start, format_length,
2247
                           wanted_type, types->pointer_count,
2248
                           types->wanted_type_name, orig_cur_type, arg_num);
2249
    }
2250
}
2251
 
2252
 
2253
/* Give a warning about a format argument of different type from that
2254
   expected.  DESCR is a description such as "field precision", or
2255
   NULL for an ordinary format.  For an ordinary format, FORMAT_START
2256
   points to where the format starts in the format string and
2257
   FORMAT_LENGTH is its length.  WANTED_TYPE is the type the argument
2258
   should have after POINTER_COUNT pointer dereferences.
2259
   WANTED_NAME_NAME is a possibly more friendly name of WANTED_TYPE,
2260
   or NULL if the ordinary name of the type should be used.  ARG_TYPE
2261
   is the type of the actual argument.  ARG_NUM is the number of that
2262
   argument.  */
2263
static void
2264
format_type_warning (const char *descr, const char *format_start,
2265
                     int format_length, tree wanted_type, int pointer_count,
2266
                     const char *wanted_type_name, tree arg_type, int arg_num)
2267
{
2268
  char *p;
2269
  /* If ARG_TYPE is a typedef with a misleading name (for example,
2270
     size_t but not the standard size_t expected by printf %zu), avoid
2271
     printing the typedef name.  */
2272
  if (wanted_type_name
2273
      && TYPE_NAME (arg_type)
2274
      && TREE_CODE (TYPE_NAME (arg_type)) == TYPE_DECL
2275
      && DECL_NAME (TYPE_NAME (arg_type))
2276
      && !strcmp (wanted_type_name,
2277
                  lang_hooks.decl_printable_name (TYPE_NAME (arg_type), 2)))
2278
    arg_type = TYPE_MAIN_VARIANT (arg_type);
2279
  /* The format type and name exclude any '*' for pointers, so those
2280
     must be formatted manually.  For all the types we currently have,
2281
     this is adequate, but formats taking pointers to functions or
2282
     arrays would require the full type to be built up in order to
2283
     print it with %T.  */
2284
  p = alloca (pointer_count + 2);
2285
  if (pointer_count == 0)
2286
    p[0] = 0;
2287
  else if (c_dialect_cxx ())
2288
    {
2289
      memset (p, '*', pointer_count);
2290
      p[pointer_count] = 0;
2291
    }
2292
  else
2293
    {
2294
      p[0] = ' ';
2295
      memset (p + 1, '*', pointer_count);
2296
      p[pointer_count + 1] = 0;
2297
    }
2298
  if (wanted_type_name)
2299
    {
2300
      if (descr)
2301
        warning (OPT_Wformat, "%s should have type %<%s%s%>, "
2302
                 "but argument %d has type %qT",
2303
                 descr, wanted_type_name, p, arg_num, arg_type);
2304
      else
2305
        warning (OPT_Wformat, "format %q.*s expects type %<%s%s%>, "
2306
                 "but argument %d has type %qT",
2307
                 format_length, format_start, wanted_type_name, p,
2308
                 arg_num, arg_type);
2309
    }
2310
  else
2311
    {
2312
      if (descr)
2313
        warning (OPT_Wformat, "%s should have type %<%T%s%>, "
2314
                 "but argument %d has type %qT",
2315
                 descr, wanted_type, p, arg_num, arg_type);
2316
      else
2317
        warning (OPT_Wformat, "format %q.*s expects type %<%T%s%>, "
2318
                 "but argument %d has type %qT",
2319
                 format_length, format_start, wanted_type, p, arg_num, arg_type);
2320
    }
2321
}
2322
 
2323
 
2324
/* Given a format_char_info array FCI, and a character C, this function
2325
   returns the index into the conversion_specs where that specifier's
2326
   data is located.  The character must exist.  */
2327
static unsigned int
2328
find_char_info_specifier_index (const format_char_info *fci, int c)
2329
{
2330
  unsigned i;
2331
 
2332
  for (i = 0; fci->format_chars; i++, fci++)
2333
    if (strchr (fci->format_chars, c))
2334
      return i;
2335
 
2336
  /* We shouldn't be looking for a non-existent specifier.  */
2337
  gcc_unreachable ();
2338
}
2339
 
2340
/* Given a format_length_info array FLI, and a character C, this
2341
   function returns the index into the conversion_specs where that
2342
   modifier's data is located.  The character must exist.  */
2343
static unsigned int
2344
find_length_info_modifier_index (const format_length_info *fli, int c)
2345
{
2346
  unsigned i;
2347
 
2348
  for (i = 0; fli->name; i++, fli++)
2349
    if (strchr (fli->name, c))
2350
      return i;
2351
 
2352
  /* We shouldn't be looking for a non-existent modifier.  */
2353
  gcc_unreachable ();
2354
}
2355
 
2356
/* Determine the type of HOST_WIDE_INT in the code being compiled for
2357
   use in GCC's __asm_fprintf__ custom format attribute.  You must
2358
   have set dynamic_format_types before calling this function.  */
2359
static void
2360
init_dynamic_asm_fprintf_info (void)
2361
{
2362
  static tree hwi;
2363
 
2364
  if (!hwi)
2365
    {
2366
      format_length_info *new_asm_fprintf_length_specs;
2367
      unsigned int i;
2368
 
2369
      /* Find the underlying type for HOST_WIDE_INT.  For the %w
2370
         length modifier to work, one must have issued: "typedef
2371
         HOST_WIDE_INT __gcc_host_wide_int__;" in one's source code
2372
         prior to using that modifier.  */
2373
      hwi = maybe_get_identifier ("__gcc_host_wide_int__");
2374
      if (!hwi)
2375
        {
2376
          error ("%<__gcc_host_wide_int__%> is not defined as a type");
2377
          return;
2378
        }
2379
      hwi = identifier_global_value (hwi);
2380
      if (!hwi || TREE_CODE (hwi) != TYPE_DECL)
2381
        {
2382
          error ("%<__gcc_host_wide_int__%> is not defined as a type");
2383
          return;
2384
        }
2385
      hwi = DECL_ORIGINAL_TYPE (hwi);
2386
      gcc_assert (hwi);
2387
      if (hwi != long_integer_type_node && hwi != long_long_integer_type_node)
2388
        {
2389
          error ("%<__gcc_host_wide_int__%> is not defined as %<long%>"
2390
                 " or %<long long%>");
2391
          return;
2392
        }
2393
 
2394
      /* Create a new (writable) copy of asm_fprintf_length_specs.  */
2395
      new_asm_fprintf_length_specs = (format_length_info *)
2396
                                     xmemdup (asm_fprintf_length_specs,
2397
                                              sizeof (asm_fprintf_length_specs),
2398
                                              sizeof (asm_fprintf_length_specs));
2399
 
2400
      /* HOST_WIDE_INT must be one of 'long' or 'long long'.  */
2401
      i = find_length_info_modifier_index (new_asm_fprintf_length_specs, 'w');
2402
      if (hwi == long_integer_type_node)
2403
        new_asm_fprintf_length_specs[i].index = FMT_LEN_l;
2404
      else if (hwi == long_long_integer_type_node)
2405
        new_asm_fprintf_length_specs[i].index = FMT_LEN_ll;
2406
      else
2407
        gcc_unreachable ();
2408
 
2409
      /* Assign the new data for use.  */
2410
      dynamic_format_types[asm_fprintf_format_type].length_char_specs =
2411
        new_asm_fprintf_length_specs;
2412
    }
2413
}
2414
 
2415
/* Determine the type of a "locus" in the code being compiled for use
2416
   in GCC's __gcc_gfc__ custom format attribute.  You must have set
2417
   dynamic_format_types before calling this function.  */
2418
static void
2419
init_dynamic_gfc_info (void)
2420
{
2421
  static tree locus;
2422
 
2423
  if (!locus)
2424
    {
2425
      static format_char_info *gfc_fci;
2426
 
2427
      /* For the GCC __gcc_gfc__ custom format specifier to work, one
2428
         must have declared 'locus' prior to using this attribute.  If
2429
         we haven't seen this declarations then you shouldn't use the
2430
         specifier requiring that type.  */
2431
      if ((locus = maybe_get_identifier ("locus")))
2432
        {
2433
          locus = identifier_global_value (locus);
2434
          if (locus)
2435
            {
2436
              if (TREE_CODE (locus) != TYPE_DECL)
2437
                {
2438
                  error ("%<locus%> is not defined as a type");
2439
                  locus = 0;
2440
                }
2441
              else
2442
                locus = TREE_TYPE (locus);
2443
            }
2444
        }
2445
 
2446
      /* Assign the new data for use.  */
2447
 
2448
      /* Handle the __gcc_gfc__ format specifics.  */
2449
      if (!gfc_fci)
2450
        dynamic_format_types[gcc_gfc_format_type].conversion_specs =
2451
          gfc_fci = (format_char_info *)
2452
                     xmemdup (gcc_gfc_char_table,
2453
                              sizeof (gcc_gfc_char_table),
2454
                              sizeof (gcc_gfc_char_table));
2455
      if (locus)
2456
        {
2457
          const unsigned i = find_char_info_specifier_index (gfc_fci, 'L');
2458
          gfc_fci[i].types[0].type = &locus;
2459
          gfc_fci[i].pointer_count = 1;
2460
        }
2461
    }
2462
}
2463
 
2464
/* Determine the types of "tree" and "location_t" in the code being
2465
   compiled for use in GCC's diagnostic custom format attributes.  You
2466
   must have set dynamic_format_types before calling this function.  */
2467
static void
2468
init_dynamic_diag_info (void)
2469
{
2470
  static tree t, loc, hwi;
2471
 
2472
  if (!loc || !t || !hwi)
2473
    {
2474
      static format_char_info *diag_fci, *tdiag_fci, *cdiag_fci, *cxxdiag_fci;
2475
      static format_length_info *diag_ls;
2476
      unsigned int i;
2477
 
2478
      /* For the GCC-diagnostics custom format specifiers to work, one
2479
         must have declared 'tree' and/or 'location_t' prior to using
2480
         those attributes.  If we haven't seen these declarations then
2481
         you shouldn't use the specifiers requiring these types.
2482
         However we don't force a hard ICE because we may see only one
2483
         or the other type.  */
2484
      if ((loc = maybe_get_identifier ("location_t")))
2485
        {
2486
          loc = identifier_global_value (loc);
2487
          if (loc)
2488
            {
2489
              if (TREE_CODE (loc) != TYPE_DECL)
2490
                {
2491
                  error ("%<location_t%> is not defined as a type");
2492
                  loc = 0;
2493
                }
2494
              else
2495
                loc = TREE_TYPE (loc);
2496
            }
2497
        }
2498
 
2499
      /* We need to grab the underlying 'union tree_node' so peek into
2500
         an extra type level.  */
2501
      if ((t = maybe_get_identifier ("tree")))
2502
        {
2503
          t = identifier_global_value (t);
2504
          if (t)
2505
            {
2506
              if (TREE_CODE (t) != TYPE_DECL)
2507
                {
2508
                  error ("%<tree%> is not defined as a type");
2509
                  t = 0;
2510
                }
2511
              else if (TREE_CODE (TREE_TYPE (t)) != POINTER_TYPE)
2512
                {
2513
                  error ("%<tree%> is not defined as a pointer type");
2514
                  t = 0;
2515
                }
2516
              else
2517
                t = TREE_TYPE (TREE_TYPE (t));
2518
            }
2519
        }
2520
 
2521
      /* Find the underlying type for HOST_WIDE_INT.  For the %w
2522
         length modifier to work, one must have issued: "typedef
2523
         HOST_WIDE_INT __gcc_host_wide_int__;" in one's source code
2524
         prior to using that modifier.  */
2525
      if ((hwi = maybe_get_identifier ("__gcc_host_wide_int__")))
2526
        {
2527
          hwi = identifier_global_value (hwi);
2528
          if (hwi)
2529
            {
2530
              if (TREE_CODE (hwi) != TYPE_DECL)
2531
                {
2532
                  error ("%<__gcc_host_wide_int__%> is not defined as a type");
2533
                  hwi = 0;
2534
                }
2535
              else
2536
                {
2537
                  hwi = DECL_ORIGINAL_TYPE (hwi);
2538
                  gcc_assert (hwi);
2539
                  if (hwi != long_integer_type_node
2540
                      && hwi != long_long_integer_type_node)
2541
                    {
2542
                      error ("%<__gcc_host_wide_int__%> is not defined"
2543
                             " as %<long%> or %<long long%>");
2544
                      hwi = 0;
2545
                    }
2546
                }
2547
            }
2548
        }
2549
 
2550
      /* Assign the new data for use.  */
2551
 
2552
      /* All the GCC diag formats use the same length specs.  */
2553
      if (!diag_ls)
2554
        dynamic_format_types[gcc_diag_format_type].length_char_specs =
2555
          dynamic_format_types[gcc_tdiag_format_type].length_char_specs =
2556
          dynamic_format_types[gcc_cdiag_format_type].length_char_specs =
2557
          dynamic_format_types[gcc_cxxdiag_format_type].length_char_specs =
2558
          diag_ls = (format_length_info *)
2559
                    xmemdup (gcc_diag_length_specs,
2560
                             sizeof (gcc_diag_length_specs),
2561
                             sizeof (gcc_diag_length_specs));
2562
      if (hwi)
2563
        {
2564
          /* HOST_WIDE_INT must be one of 'long' or 'long long'.  */
2565
          i = find_length_info_modifier_index (diag_ls, 'w');
2566
          if (hwi == long_integer_type_node)
2567
            diag_ls[i].index = FMT_LEN_l;
2568
          else if (hwi == long_long_integer_type_node)
2569
            diag_ls[i].index = FMT_LEN_ll;
2570
          else
2571
            gcc_unreachable ();
2572
        }
2573
 
2574
      /* Handle the __gcc_diag__ format specifics.  */
2575
      if (!diag_fci)
2576
        dynamic_format_types[gcc_diag_format_type].conversion_specs =
2577
          diag_fci = (format_char_info *)
2578
                     xmemdup (gcc_diag_char_table,
2579
                              sizeof (gcc_diag_char_table),
2580
                              sizeof (gcc_diag_char_table));
2581
      if (loc)
2582
        {
2583
          i = find_char_info_specifier_index (diag_fci, 'H');
2584
          diag_fci[i].types[0].type = &loc;
2585
          diag_fci[i].pointer_count = 1;
2586
        }
2587
      if (t)
2588
        {
2589
          i = find_char_info_specifier_index (diag_fci, 'J');
2590
          diag_fci[i].types[0].type = &t;
2591
          diag_fci[i].pointer_count = 1;
2592
        }
2593
 
2594
      /* Handle the __gcc_tdiag__ format specifics.  */
2595
      if (!tdiag_fci)
2596
        dynamic_format_types[gcc_tdiag_format_type].conversion_specs =
2597
          tdiag_fci = (format_char_info *)
2598
                      xmemdup (gcc_tdiag_char_table,
2599
                               sizeof (gcc_tdiag_char_table),
2600
                               sizeof (gcc_tdiag_char_table));
2601
      if (loc)
2602
        {
2603
          i = find_char_info_specifier_index (tdiag_fci, 'H');
2604
          tdiag_fci[i].types[0].type = &loc;
2605
          tdiag_fci[i].pointer_count = 1;
2606
        }
2607
      if (t)
2608
        {
2609
          /* All specifiers taking a tree share the same struct.  */
2610
          i = find_char_info_specifier_index (tdiag_fci, 'D');
2611
          tdiag_fci[i].types[0].type = &t;
2612
          tdiag_fci[i].pointer_count = 1;
2613
          i = find_char_info_specifier_index (tdiag_fci, 'J');
2614
          tdiag_fci[i].types[0].type = &t;
2615
          tdiag_fci[i].pointer_count = 1;
2616
        }
2617
 
2618
      /* Handle the __gcc_cdiag__ format specifics.  */
2619
      if (!cdiag_fci)
2620
        dynamic_format_types[gcc_cdiag_format_type].conversion_specs =
2621
          cdiag_fci = (format_char_info *)
2622
                      xmemdup (gcc_cdiag_char_table,
2623
                               sizeof (gcc_cdiag_char_table),
2624
                               sizeof (gcc_cdiag_char_table));
2625
      if (loc)
2626
        {
2627
          i = find_char_info_specifier_index (cdiag_fci, 'H');
2628
          cdiag_fci[i].types[0].type = &loc;
2629
          cdiag_fci[i].pointer_count = 1;
2630
        }
2631
      if (t)
2632
        {
2633
          /* All specifiers taking a tree share the same struct.  */
2634
          i = find_char_info_specifier_index (cdiag_fci, 'D');
2635
          cdiag_fci[i].types[0].type = &t;
2636
          cdiag_fci[i].pointer_count = 1;
2637
          i = find_char_info_specifier_index (cdiag_fci, 'J');
2638
          cdiag_fci[i].types[0].type = &t;
2639
          cdiag_fci[i].pointer_count = 1;
2640
        }
2641
 
2642
      /* Handle the __gcc_cxxdiag__ format specifics.  */
2643
      if (!cxxdiag_fci)
2644
        dynamic_format_types[gcc_cxxdiag_format_type].conversion_specs =
2645
          cxxdiag_fci = (format_char_info *)
2646
                        xmemdup (gcc_cxxdiag_char_table,
2647
                                 sizeof (gcc_cxxdiag_char_table),
2648
                                 sizeof (gcc_cxxdiag_char_table));
2649
      if (loc)
2650
        {
2651
          i = find_char_info_specifier_index (cxxdiag_fci, 'H');
2652
          cxxdiag_fci[i].types[0].type = &loc;
2653
          cxxdiag_fci[i].pointer_count = 1;
2654
        }
2655
      if (t)
2656
        {
2657
          /* All specifiers taking a tree share the same struct.  */
2658
          i = find_char_info_specifier_index (cxxdiag_fci, 'D');
2659
          cxxdiag_fci[i].types[0].type = &t;
2660
          cxxdiag_fci[i].pointer_count = 1;
2661
          i = find_char_info_specifier_index (cxxdiag_fci, 'J');
2662
          cxxdiag_fci[i].types[0].type = &t;
2663
          cxxdiag_fci[i].pointer_count = 1;
2664
        }
2665
    }
2666
}
2667
 
2668
#ifdef TARGET_FORMAT_TYPES
2669
extern const format_kind_info TARGET_FORMAT_TYPES[];
2670
#endif
2671
 
2672
/* Handle a "format" attribute; arguments as in
2673
   struct attribute_spec.handler.  */
2674
tree
2675
handle_format_attribute (tree *node, tree ARG_UNUSED (name), tree args,
2676
                         int flags, bool *no_add_attrs)
2677
{
2678
  tree type = *node;
2679
  function_format_info info;
2680
  tree argument;
2681
 
2682
#ifdef TARGET_FORMAT_TYPES
2683
  /* If the target provides additional format types, we need to
2684
     add them to FORMAT_TYPES at first use.  */
2685
  if (TARGET_FORMAT_TYPES != NULL && !dynamic_format_types)
2686
    {
2687
      dynamic_format_types = xmalloc ((n_format_types + TARGET_N_FORMAT_TYPES)
2688
                                      * sizeof (dynamic_format_types[0]));
2689
      memcpy (dynamic_format_types, format_types_orig,
2690
              sizeof (format_types_orig));
2691
      memcpy (&dynamic_format_types[n_format_types], TARGET_FORMAT_TYPES,
2692
              TARGET_N_FORMAT_TYPES * sizeof (dynamic_format_types[0]));
2693
 
2694
      format_types = dynamic_format_types;
2695
      n_format_types += TARGET_N_FORMAT_TYPES;
2696
    }
2697
#endif
2698
 
2699
  if (!decode_format_attr (args, &info, 0))
2700
    {
2701
      *no_add_attrs = true;
2702
      return NULL_TREE;
2703
    }
2704
 
2705
  argument = TYPE_ARG_TYPES (type);
2706
  if (argument)
2707
    {
2708
      if (!check_format_string (argument, info.format_num, flags,
2709
                                no_add_attrs))
2710
        return NULL_TREE;
2711
 
2712
      if (info.first_arg_num != 0)
2713
        {
2714
          unsigned HOST_WIDE_INT arg_num = 1;
2715
 
2716
          /* Verify that first_arg_num points to the last arg,
2717
             the ...  */
2718
          while (argument)
2719
            arg_num++, argument = TREE_CHAIN (argument);
2720
 
2721
          if (arg_num != info.first_arg_num)
2722
            {
2723
              if (!(flags & (int) ATTR_FLAG_BUILT_IN))
2724
                error ("args to be formatted is not %<...%>");
2725
              *no_add_attrs = true;
2726
              return NULL_TREE;
2727
            }
2728
        }
2729
    }
2730
 
2731
  if (info.format_type == strftime_format_type && info.first_arg_num != 0)
2732
    {
2733
      error ("strftime formats cannot format arguments");
2734
      *no_add_attrs = true;
2735
      return NULL_TREE;
2736
    }
2737
 
2738
  /* If this is a custom GCC-internal format type, we have to
2739
     initialize certain bits a runtime.  */
2740
  if (info.format_type == asm_fprintf_format_type
2741
      || info.format_type == gcc_gfc_format_type
2742
      || info.format_type == gcc_diag_format_type
2743
      || info.format_type == gcc_tdiag_format_type
2744
      || info.format_type == gcc_cdiag_format_type
2745
      || info.format_type == gcc_cxxdiag_format_type)
2746
    {
2747
      /* Our first time through, we have to make sure that our
2748
         format_type data is allocated dynamically and is modifiable.  */
2749
      if (!dynamic_format_types)
2750
        format_types = dynamic_format_types = (format_kind_info *)
2751
          xmemdup (format_types_orig, sizeof (format_types_orig),
2752
                   sizeof (format_types_orig));
2753
 
2754
      /* If this is format __asm_fprintf__, we have to initialize
2755
         GCC's notion of HOST_WIDE_INT for checking %wd.  */
2756
      if (info.format_type == asm_fprintf_format_type)
2757
        init_dynamic_asm_fprintf_info ();
2758
      /* If this is format __gcc_gfc__, we have to initialize GCC's
2759
         notion of 'locus' at runtime for %L.  */
2760
      else if (info.format_type == gcc_gfc_format_type)
2761
        init_dynamic_gfc_info ();
2762
      /* If this is one of the diagnostic attributes, then we have to
2763
         initialize 'location_t' and 'tree' at runtime.  */
2764
      else if (info.format_type == gcc_diag_format_type
2765
               || info.format_type == gcc_tdiag_format_type
2766
               || info.format_type == gcc_cdiag_format_type
2767
               || info.format_type == gcc_cxxdiag_format_type)
2768
        init_dynamic_diag_info ();
2769
      else
2770
        gcc_unreachable ();
2771
    }
2772
 
2773
  return NULL_TREE;
2774
}

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.