111
|
1 /* Copyright (C) 2016-2017 Free Software Foundation, Inc.
|
|
2 Contributed by Martin Sebor <msebor@redhat.com>.
|
|
3
|
|
4 This file is part of GCC.
|
|
5
|
|
6 GCC is free software; you can redistribute it and/or modify it under
|
|
7 the terms of the GNU General Public License as published by the Free
|
|
8 Software Foundation; either version 3, or (at your option) any later
|
|
9 version.
|
|
10
|
|
11 GCC is distributed in the hope that it will be useful, but WITHOUT ANY
|
|
12 WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
|
13 FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
|
14 for more details.
|
|
15
|
|
16 You should have received a copy of the GNU General Public License
|
|
17 along with GCC; see the file COPYING3. If not see
|
|
18 <http://www.gnu.org/licenses/>. */
|
|
19
|
|
20 /* This file implements the printf-return-value pass. The pass does
|
|
21 two things: 1) it analyzes calls to formatted output functions like
|
|
22 sprintf looking for possible buffer overflows and calls to bounded
|
|
23 functions like snprintf for early truncation (and under the control
|
|
24 of the -Wformat-length option issues warnings), and 2) under the
|
|
25 control of the -fprintf-return-value option it folds the return
|
|
26 value of safe calls into constants, making it possible to eliminate
|
|
27 code that depends on the value of those constants.
|
|
28
|
|
29 For all functions (bounded or not) the pass uses the size of the
|
|
30 destination object. That means that it will diagnose calls to
|
|
31 snprintf not on the basis of the size specified by the function's
|
|
32 second argument but rathger on the basis of the size the first
|
|
33 argument points to (if possible). For bound-checking built-ins
|
|
34 like __builtin___snprintf_chk the pass uses the size typically
|
|
35 determined by __builtin_object_size and passed to the built-in
|
|
36 by the Glibc inline wrapper.
|
|
37
|
|
38 The pass handles all forms standard sprintf format directives,
|
|
39 including character, integer, floating point, pointer, and strings,
|
|
40 with the standard C flags, widths, and precisions. For integers
|
|
41 and strings it computes the length of output itself. For floating
|
|
42 point it uses MPFR to fornmat known constants with up and down
|
|
43 rounding and uses the resulting range of output lengths. For
|
|
44 strings it uses the length of string literals and the sizes of
|
|
45 character arrays that a character pointer may point to as a bound
|
|
46 on the longest string. */
|
|
47
|
|
48 #include "config.h"
|
|
49 #include "system.h"
|
|
50 #include "coretypes.h"
|
|
51 #include "backend.h"
|
|
52 #include "tree.h"
|
|
53 #include "gimple.h"
|
|
54 #include "tree-pass.h"
|
|
55 #include "ssa.h"
|
|
56 #include "gimple-fold.h"
|
|
57 #include "gimple-pretty-print.h"
|
|
58 #include "diagnostic-core.h"
|
|
59 #include "fold-const.h"
|
|
60 #include "gimple-iterator.h"
|
|
61 #include "tree-ssa.h"
|
|
62 #include "tree-object-size.h"
|
|
63 #include "params.h"
|
|
64 #include "tree-cfg.h"
|
|
65 #include "tree-ssa-propagate.h"
|
|
66 #include "calls.h"
|
|
67 #include "cfgloop.h"
|
|
68 #include "intl.h"
|
|
69 #include "langhooks.h"
|
|
70
|
|
71 #include "builtins.h"
|
|
72 #include "stor-layout.h"
|
|
73
|
|
74 #include "realmpfr.h"
|
|
75 #include "target.h"
|
|
76
|
|
77 #include "cpplib.h"
|
|
78 #include "input.h"
|
|
79 #include "toplev.h"
|
|
80 #include "substring-locations.h"
|
|
81 #include "diagnostic.h"
|
|
82
|
|
83 /* The likely worst case value of MB_LEN_MAX for the target, large enough
|
|
84 for UTF-8. Ideally, this would be obtained by a target hook if it were
|
|
85 to be used for optimization but it's good enough as is for warnings. */
|
|
86 #define target_mb_len_max() 6
|
|
87
|
|
88 /* The maximum number of bytes a single non-string directive can result
|
|
89 in. This is the result of printf("%.*Lf", INT_MAX, -LDBL_MAX) for
|
|
90 LDBL_MAX_10_EXP of 4932. */
|
|
91 #define IEEE_MAX_10_EXP 4932
|
|
92 #define target_dir_max() (target_int_max () + IEEE_MAX_10_EXP + 2)
|
|
93
|
|
94 namespace {
|
|
95
|
|
96 const pass_data pass_data_sprintf_length = {
|
|
97 GIMPLE_PASS, // pass type
|
|
98 "printf-return-value", // pass name
|
|
99 OPTGROUP_NONE, // optinfo_flags
|
|
100 TV_NONE, // tv_id
|
|
101 PROP_cfg, // properties_required
|
|
102 0, // properties_provided
|
|
103 0, // properties_destroyed
|
|
104 0, // properties_start
|
|
105 0, // properties_finish
|
|
106 };
|
|
107
|
|
108 /* Set to the warning level for the current function which is equal
|
|
109 either to warn_format_trunc for bounded functions or to
|
|
110 warn_format_overflow otherwise. */
|
|
111
|
|
112 static int warn_level;
|
|
113
|
|
114 struct format_result;
|
|
115
|
|
116 class pass_sprintf_length : public gimple_opt_pass
|
|
117 {
|
|
118 bool fold_return_value;
|
|
119
|
|
120 public:
|
|
121 pass_sprintf_length (gcc::context *ctxt)
|
|
122 : gimple_opt_pass (pass_data_sprintf_length, ctxt),
|
|
123 fold_return_value (false)
|
|
124 { }
|
|
125
|
|
126 opt_pass * clone () { return new pass_sprintf_length (m_ctxt); }
|
|
127
|
|
128 virtual bool gate (function *);
|
|
129
|
|
130 virtual unsigned int execute (function *);
|
|
131
|
|
132 void set_pass_param (unsigned int n, bool param)
|
|
133 {
|
|
134 gcc_assert (n == 0);
|
|
135 fold_return_value = param;
|
|
136 }
|
|
137
|
|
138 bool handle_gimple_call (gimple_stmt_iterator *);
|
|
139
|
|
140 struct call_info;
|
|
141 bool compute_format_length (call_info &, format_result *);
|
|
142 };
|
|
143
|
|
144 bool
|
|
145 pass_sprintf_length::gate (function *)
|
|
146 {
|
|
147 /* Run the pass iff -Warn-format-overflow or -Warn-format-truncation
|
|
148 is specified and either not optimizing and the pass is being invoked
|
|
149 early, or when optimizing and the pass is being invoked during
|
|
150 optimization (i.e., "late"). */
|
|
151 return ((warn_format_overflow > 0
|
|
152 || warn_format_trunc > 0
|
|
153 || flag_printf_return_value)
|
|
154 && (optimize > 0) == fold_return_value);
|
|
155 }
|
|
156
|
|
157 /* The minimum, maximum, likely, and unlikely maximum number of bytes
|
|
158 of output either a formatting function or an individual directive
|
|
159 can result in. */
|
|
160
|
|
161 struct result_range
|
|
162 {
|
|
163 /* The absolute minimum number of bytes. The result of a successful
|
|
164 conversion is guaranteed to be no less than this. (An erroneous
|
|
165 conversion can be indicated by MIN > HOST_WIDE_INT_MAX.) */
|
|
166 unsigned HOST_WIDE_INT min;
|
|
167 /* The likely maximum result that is used in diagnostics. In most
|
|
168 cases MAX is the same as the worst case UNLIKELY result. */
|
|
169 unsigned HOST_WIDE_INT max;
|
|
170 /* The likely result used to trigger diagnostics. For conversions
|
|
171 that result in a range of bytes [MIN, MAX], LIKELY is somewhere
|
|
172 in that range. */
|
|
173 unsigned HOST_WIDE_INT likely;
|
|
174 /* In rare cases (e.g., for nultibyte characters) UNLIKELY gives
|
|
175 the worst cases maximum result of a directive. In most cases
|
|
176 UNLIKELY == MAX. UNLIKELY is used to control the return value
|
|
177 optimization but not in diagnostics. */
|
|
178 unsigned HOST_WIDE_INT unlikely;
|
|
179 };
|
|
180
|
|
181 /* The result of a call to a formatted function. */
|
|
182
|
|
183 struct format_result
|
|
184 {
|
|
185 /* Range of characters written by the formatted function.
|
|
186 Setting the minimum to HOST_WIDE_INT_MAX disables all
|
|
187 length tracking for the remainder of the format string. */
|
|
188 result_range range;
|
|
189
|
|
190 /* True when the range above is obtained from known values of
|
|
191 directive arguments, or bounds on the amount of output such
|
|
192 as width and precision, and not the result of heuristics that
|
|
193 depend on warning levels. It's used to issue stricter diagnostics
|
|
194 in cases where strings of unknown lengths are bounded by the arrays
|
|
195 they are determined to refer to. KNOWNRANGE must not be used for
|
|
196 the return value optimization. */
|
|
197 bool knownrange;
|
|
198
|
|
199 /* True if no individual directive resulted in more than 4095 bytes
|
|
200 of output (the total NUMBER_CHARS_{MIN,MAX} might be greater).
|
|
201 Implementations are not required to handle directives that produce
|
|
202 more than 4K bytes (leading to undefined behavior) and so when one
|
|
203 is found it disables the return value optimization. */
|
|
204 bool under4k;
|
|
205
|
|
206 /* True when a floating point directive has been seen in the format
|
|
207 string. */
|
|
208 bool floating;
|
|
209
|
|
210 /* True when an intermediate result has caused a warning. Used to
|
|
211 avoid issuing duplicate warnings while finishing the processing
|
|
212 of a call. WARNED also disables the return value optimization. */
|
|
213 bool warned;
|
|
214
|
|
215 /* Preincrement the number of output characters by 1. */
|
|
216 format_result& operator++ ()
|
|
217 {
|
|
218 return *this += 1;
|
|
219 }
|
|
220
|
|
221 /* Postincrement the number of output characters by 1. */
|
|
222 format_result operator++ (int)
|
|
223 {
|
|
224 format_result prev (*this);
|
|
225 *this += 1;
|
|
226 return prev;
|
|
227 }
|
|
228
|
|
229 /* Increment the number of output characters by N. */
|
|
230 format_result& operator+= (unsigned HOST_WIDE_INT);
|
|
231 };
|
|
232
|
|
233 format_result&
|
|
234 format_result::operator+= (unsigned HOST_WIDE_INT n)
|
|
235 {
|
|
236 gcc_assert (n < HOST_WIDE_INT_MAX);
|
|
237
|
|
238 if (range.min < HOST_WIDE_INT_MAX)
|
|
239 range.min += n;
|
|
240
|
|
241 if (range.max < HOST_WIDE_INT_MAX)
|
|
242 range.max += n;
|
|
243
|
|
244 if (range.likely < HOST_WIDE_INT_MAX)
|
|
245 range.likely += n;
|
|
246
|
|
247 if (range.unlikely < HOST_WIDE_INT_MAX)
|
|
248 range.unlikely += n;
|
|
249
|
|
250 return *this;
|
|
251 }
|
|
252
|
|
253 /* Return the value of INT_MIN for the target. */
|
|
254
|
|
255 static inline HOST_WIDE_INT
|
|
256 target_int_min ()
|
|
257 {
|
|
258 return tree_to_shwi (TYPE_MIN_VALUE (integer_type_node));
|
|
259 }
|
|
260
|
|
261 /* Return the value of INT_MAX for the target. */
|
|
262
|
|
263 static inline unsigned HOST_WIDE_INT
|
|
264 target_int_max ()
|
|
265 {
|
|
266 return tree_to_uhwi (TYPE_MAX_VALUE (integer_type_node));
|
|
267 }
|
|
268
|
|
269 /* Return the value of SIZE_MAX for the target. */
|
|
270
|
|
271 static inline unsigned HOST_WIDE_INT
|
|
272 target_size_max ()
|
|
273 {
|
|
274 return tree_to_uhwi (TYPE_MAX_VALUE (size_type_node));
|
|
275 }
|
|
276
|
|
277 /* A straightforward mapping from the execution character set to the host
|
|
278 character set indexed by execution character. */
|
|
279
|
|
280 static char target_to_host_charmap[256];
|
|
281
|
|
282 /* Initialize a mapping from the execution character set to the host
|
|
283 character set. */
|
|
284
|
|
285 static bool
|
|
286 init_target_to_host_charmap ()
|
|
287 {
|
|
288 /* If the percent sign is non-zero the mapping has already been
|
|
289 initialized. */
|
|
290 if (target_to_host_charmap['%'])
|
|
291 return true;
|
|
292
|
|
293 /* Initialize the target_percent character (done elsewhere). */
|
|
294 if (!init_target_chars ())
|
|
295 return false;
|
|
296
|
|
297 /* The subset of the source character set used by printf conversion
|
|
298 specifications (strictly speaking, not all letters are used but
|
|
299 they are included here for the sake of simplicity). The dollar
|
|
300 sign must be included even though it's not in the basic source
|
|
301 character set. */
|
|
302 const char srcset[] = " 0123456789!\"#%&'()*+,-./:;<=>?[\\]^_{|}~$"
|
|
303 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz";
|
|
304
|
|
305 /* Set the mapping for all characters to some ordinary value (i,e.,
|
|
306 not none used in printf conversion specifications) and overwrite
|
|
307 those that are used by conversion specifications with their
|
|
308 corresponding values. */
|
|
309 memset (target_to_host_charmap + 1, '?', sizeof target_to_host_charmap - 1);
|
|
310
|
|
311 /* Are the two sets of characters the same? */
|
|
312 bool all_same_p = true;
|
|
313
|
|
314 for (const char *pc = srcset; *pc; ++pc)
|
|
315 {
|
|
316 /* Slice off the high end bits in case target characters are
|
|
317 signed. All values are expected to be non-nul, otherwise
|
|
318 there's a problem. */
|
|
319 if (unsigned char tc = lang_hooks.to_target_charset (*pc))
|
|
320 {
|
|
321 target_to_host_charmap[tc] = *pc;
|
|
322 if (tc != *pc)
|
|
323 all_same_p = false;
|
|
324 }
|
|
325 else
|
|
326 return false;
|
|
327
|
|
328 }
|
|
329
|
|
330 /* Set the first element to a non-zero value if the mapping
|
|
331 is 1-to-1, otherwise leave it clear (NUL is assumed to be
|
|
332 the same in both character sets). */
|
|
333 target_to_host_charmap[0] = all_same_p;
|
|
334
|
|
335 return true;
|
|
336 }
|
|
337
|
|
338 /* Return the host source character corresponding to the character
|
|
339 CH in the execution character set if one exists, or some innocuous
|
|
340 (non-special, non-nul) source character otherwise. */
|
|
341
|
|
342 static inline unsigned char
|
|
343 target_to_host (unsigned char ch)
|
|
344 {
|
|
345 return target_to_host_charmap[ch];
|
|
346 }
|
|
347
|
|
348 /* Convert an initial substring of the string TARGSTR consisting of
|
|
349 characters in the execution character set into a string in the
|
|
350 source character set on the host and store up to HOSTSZ characters
|
|
351 in the buffer pointed to by HOSTR. Return HOSTR. */
|
|
352
|
|
353 static const char*
|
|
354 target_to_host (char *hostr, size_t hostsz, const char *targstr)
|
|
355 {
|
|
356 /* Make sure the buffer is reasonably big. */
|
|
357 gcc_assert (hostsz > 4);
|
|
358
|
|
359 /* The interesting subset of source and execution characters are
|
|
360 the same so no conversion is necessary. However, truncate
|
|
361 overlong strings just like the translated strings are. */
|
|
362 if (target_to_host_charmap['\0'] == 1)
|
|
363 {
|
|
364 strncpy (hostr, targstr, hostsz - 4);
|
|
365 if (strlen (targstr) >= hostsz)
|
|
366 strcpy (hostr + hostsz - 4, "...");
|
|
367 return hostr;
|
|
368 }
|
|
369
|
|
370 /* Convert the initial substring of TARGSTR to the corresponding
|
|
371 characters in the host set, appending "..." if TARGSTR is too
|
|
372 long to fit. Using the static buffer assumes the function is
|
|
373 not called in between sequence points (which it isn't). */
|
|
374 for (char *ph = hostr; ; ++targstr)
|
|
375 {
|
|
376 *ph++ = target_to_host (*targstr);
|
|
377 if (!*targstr)
|
|
378 break;
|
|
379
|
|
380 if (size_t (ph - hostr) == hostsz - 4)
|
|
381 {
|
|
382 *ph = '\0';
|
|
383 strcat (ph, "...");
|
|
384 break;
|
|
385 }
|
|
386 }
|
|
387
|
|
388 return hostr;
|
|
389 }
|
|
390
|
|
391 /* Convert the sequence of decimal digits in the execution character
|
|
392 starting at S to a long, just like strtol does. Return the result
|
|
393 and set *END to one past the last converted character. On range
|
|
394 error set ERANGE to the digit that caused it. */
|
|
395
|
|
396 static inline long
|
|
397 target_strtol10 (const char **ps, const char **erange)
|
|
398 {
|
|
399 unsigned HOST_WIDE_INT val = 0;
|
|
400 for ( ; ; ++*ps)
|
|
401 {
|
|
402 unsigned char c = target_to_host (**ps);
|
|
403 if (ISDIGIT (c))
|
|
404 {
|
|
405 c -= '0';
|
|
406
|
|
407 /* Check for overflow. */
|
|
408 if (val > (LONG_MAX - c) / 10LU)
|
|
409 {
|
|
410 val = LONG_MAX;
|
|
411 *erange = *ps;
|
|
412
|
|
413 /* Skip the remaining digits. */
|
|
414 do
|
|
415 c = target_to_host (*++*ps);
|
|
416 while (ISDIGIT (c));
|
|
417 break;
|
|
418 }
|
|
419 else
|
|
420 val = val * 10 + c;
|
|
421 }
|
|
422 else
|
|
423 break;
|
|
424 }
|
|
425
|
|
426 return val;
|
|
427 }
|
|
428
|
|
429 /* Return the constant initial value of DECL if available or DECL
|
|
430 otherwise. Same as the synonymous function in c/c-typeck.c. */
|
|
431
|
|
432 static tree
|
|
433 decl_constant_value (tree decl)
|
|
434 {
|
|
435 if (/* Don't change a variable array bound or initial value to a constant
|
|
436 in a place where a variable is invalid. Note that DECL_INITIAL
|
|
437 isn't valid for a PARM_DECL. */
|
|
438 current_function_decl != 0
|
|
439 && TREE_CODE (decl) != PARM_DECL
|
|
440 && !TREE_THIS_VOLATILE (decl)
|
|
441 && TREE_READONLY (decl)
|
|
442 && DECL_INITIAL (decl) != 0
|
|
443 && TREE_CODE (DECL_INITIAL (decl)) != ERROR_MARK
|
|
444 /* This is invalid if initial value is not constant.
|
|
445 If it has either a function call, a memory reference,
|
|
446 or a variable, then re-evaluating it could give different results. */
|
|
447 && TREE_CONSTANT (DECL_INITIAL (decl))
|
|
448 /* Check for cases where this is sub-optimal, even though valid. */
|
|
449 && TREE_CODE (DECL_INITIAL (decl)) != CONSTRUCTOR)
|
|
450 return DECL_INITIAL (decl);
|
|
451 return decl;
|
|
452 }
|
|
453
|
|
454 /* Given FORMAT, set *PLOC to the source location of the format string
|
|
455 and return the format string if it is known or null otherwise. */
|
|
456
|
|
457 static const char*
|
|
458 get_format_string (tree format, location_t *ploc)
|
|
459 {
|
|
460 if (VAR_P (format))
|
|
461 {
|
|
462 /* Pull out a constant value if the front end didn't. */
|
|
463 format = decl_constant_value (format);
|
|
464 STRIP_NOPS (format);
|
|
465 }
|
|
466
|
|
467 if (integer_zerop (format))
|
|
468 {
|
|
469 /* FIXME: Diagnose null format string if it hasn't been diagnosed
|
|
470 by -Wformat (the latter diagnoses only nul pointer constants,
|
|
471 this pass can do better). */
|
|
472 return NULL;
|
|
473 }
|
|
474
|
|
475 HOST_WIDE_INT offset = 0;
|
|
476
|
|
477 if (TREE_CODE (format) == POINTER_PLUS_EXPR)
|
|
478 {
|
|
479 tree arg0 = TREE_OPERAND (format, 0);
|
|
480 tree arg1 = TREE_OPERAND (format, 1);
|
|
481 STRIP_NOPS (arg0);
|
|
482 STRIP_NOPS (arg1);
|
|
483
|
|
484 if (TREE_CODE (arg1) != INTEGER_CST)
|
|
485 return NULL;
|
|
486
|
|
487 format = arg0;
|
|
488
|
|
489 /* POINTER_PLUS_EXPR offsets are to be interpreted signed. */
|
|
490 if (!cst_and_fits_in_hwi (arg1))
|
|
491 return NULL;
|
|
492
|
|
493 offset = int_cst_value (arg1);
|
|
494 }
|
|
495
|
|
496 if (TREE_CODE (format) != ADDR_EXPR)
|
|
497 return NULL;
|
|
498
|
|
499 *ploc = EXPR_LOC_OR_LOC (format, input_location);
|
|
500
|
|
501 format = TREE_OPERAND (format, 0);
|
|
502
|
|
503 if (TREE_CODE (format) == ARRAY_REF
|
|
504 && tree_fits_shwi_p (TREE_OPERAND (format, 1))
|
|
505 && (offset += tree_to_shwi (TREE_OPERAND (format, 1))) >= 0)
|
|
506 format = TREE_OPERAND (format, 0);
|
|
507
|
|
508 if (offset < 0)
|
|
509 return NULL;
|
|
510
|
|
511 tree array_init;
|
|
512 tree array_size = NULL_TREE;
|
|
513
|
|
514 if (VAR_P (format)
|
|
515 && TREE_CODE (TREE_TYPE (format)) == ARRAY_TYPE
|
|
516 && (array_init = decl_constant_value (format)) != format
|
|
517 && TREE_CODE (array_init) == STRING_CST)
|
|
518 {
|
|
519 /* Extract the string constant initializer. Note that this may
|
|
520 include a trailing NUL character that is not in the array (e.g.
|
|
521 const char a[3] = "foo";). */
|
|
522 array_size = DECL_SIZE_UNIT (format);
|
|
523 format = array_init;
|
|
524 }
|
|
525
|
|
526 if (TREE_CODE (format) != STRING_CST)
|
|
527 return NULL;
|
|
528
|
|
529 tree type = TREE_TYPE (format);
|
|
530
|
|
531 scalar_int_mode char_mode;
|
|
532 if (!is_int_mode (TYPE_MODE (TREE_TYPE (type)), &char_mode)
|
|
533 || GET_MODE_SIZE (char_mode) != 1)
|
|
534 {
|
|
535 /* Wide format string. */
|
|
536 return NULL;
|
|
537 }
|
|
538
|
|
539 const char *fmtstr = TREE_STRING_POINTER (format);
|
|
540 unsigned fmtlen = TREE_STRING_LENGTH (format);
|
|
541
|
|
542 if (array_size)
|
|
543 {
|
|
544 /* Variable length arrays can't be initialized. */
|
|
545 gcc_assert (TREE_CODE (array_size) == INTEGER_CST);
|
|
546
|
|
547 if (tree_fits_shwi_p (array_size))
|
|
548 {
|
|
549 HOST_WIDE_INT array_size_value = tree_to_shwi (array_size);
|
|
550 if (array_size_value > 0
|
|
551 && array_size_value == (int) array_size_value
|
|
552 && fmtlen > array_size_value)
|
|
553 fmtlen = array_size_value;
|
|
554 }
|
|
555 }
|
|
556 if (offset)
|
|
557 {
|
|
558 if (offset >= fmtlen)
|
|
559 return NULL;
|
|
560
|
|
561 fmtstr += offset;
|
|
562 fmtlen -= offset;
|
|
563 }
|
|
564
|
|
565 if (fmtlen < 1 || fmtstr[--fmtlen] != 0)
|
|
566 {
|
|
567 /* FIXME: Diagnose an unterminated format string if it hasn't been
|
|
568 diagnosed by -Wformat. Similarly to a null format pointer,
|
|
569 -Wformay diagnoses only nul pointer constants, this pass can
|
|
570 do better). */
|
|
571 return NULL;
|
|
572 }
|
|
573
|
|
574 return fmtstr;
|
|
575 }
|
|
576
|
|
577 /* The format_warning_at_substring function is not used here in a way
|
|
578 that makes using attribute format viable. Suppress the warning. */
|
|
579
|
|
580 #pragma GCC diagnostic push
|
|
581 #pragma GCC diagnostic ignored "-Wsuggest-attribute=format"
|
|
582
|
|
583 /* For convenience and brevity. */
|
|
584
|
|
585 static bool
|
|
586 (* const fmtwarn) (const substring_loc &, location_t,
|
|
587 const char *, int, const char *, ...)
|
|
588 = format_warning_at_substring;
|
|
589
|
|
590 /* Format length modifiers. */
|
|
591
|
|
592 enum format_lengths
|
|
593 {
|
|
594 FMT_LEN_none,
|
|
595 FMT_LEN_hh, // char argument
|
|
596 FMT_LEN_h, // short
|
|
597 FMT_LEN_l, // long
|
|
598 FMT_LEN_ll, // long long
|
|
599 FMT_LEN_L, // long double (and GNU long long)
|
|
600 FMT_LEN_z, // size_t
|
|
601 FMT_LEN_t, // ptrdiff_t
|
|
602 FMT_LEN_j // intmax_t
|
|
603 };
|
|
604
|
|
605
|
|
606 /* Description of the result of conversion either of a single directive
|
|
607 or the whole format string. */
|
|
608
|
|
609 struct fmtresult
|
|
610 {
|
|
611 /* Construct a FMTRESULT object with all counters initialized
|
|
612 to MIN. KNOWNRANGE is set when MIN is valid. */
|
|
613 fmtresult (unsigned HOST_WIDE_INT min = HOST_WIDE_INT_MAX)
|
|
614 : argmin (), argmax (),
|
|
615 knownrange (min < HOST_WIDE_INT_MAX),
|
|
616 nullp ()
|
|
617 {
|
|
618 range.min = min;
|
|
619 range.max = min;
|
|
620 range.likely = min;
|
|
621 range.unlikely = min;
|
|
622 }
|
|
623
|
|
624 /* Construct a FMTRESULT object with MIN, MAX, and LIKELY counters.
|
|
625 KNOWNRANGE is set when both MIN and MAX are valid. */
|
|
626 fmtresult (unsigned HOST_WIDE_INT min, unsigned HOST_WIDE_INT max,
|
|
627 unsigned HOST_WIDE_INT likely = HOST_WIDE_INT_MAX)
|
|
628 : argmin (), argmax (),
|
|
629 knownrange (min < HOST_WIDE_INT_MAX && max < HOST_WIDE_INT_MAX),
|
|
630 nullp ()
|
|
631 {
|
|
632 range.min = min;
|
|
633 range.max = max;
|
|
634 range.likely = max < likely ? min : likely;
|
|
635 range.unlikely = max;
|
|
636 }
|
|
637
|
|
638 /* Adjust result upward to reflect the RANGE of values the specified
|
|
639 width or precision is known to be in. */
|
|
640 fmtresult& adjust_for_width_or_precision (const HOST_WIDE_INT[2],
|
|
641 tree = NULL_TREE,
|
|
642 unsigned = 0, unsigned = 0);
|
|
643
|
|
644 /* Return the maximum number of decimal digits a value of TYPE
|
|
645 formats as on output. */
|
|
646 static unsigned type_max_digits (tree, int);
|
|
647
|
|
648 /* The range a directive's argument is in. */
|
|
649 tree argmin, argmax;
|
|
650
|
|
651 /* The minimum and maximum number of bytes that a directive
|
|
652 results in on output for an argument in the range above. */
|
|
653 result_range range;
|
|
654
|
|
655 /* True when the range above is obtained from a known value of
|
|
656 a directive's argument or its bounds and not the result of
|
|
657 heuristics that depend on warning levels. */
|
|
658 bool knownrange;
|
|
659
|
|
660 /* True when the argument is a null pointer. */
|
|
661 bool nullp;
|
|
662 };
|
|
663
|
|
664 /* Adjust result upward to reflect the range ADJUST of values the
|
|
665 specified width or precision is known to be in. When non-null,
|
|
666 TYPE denotes the type of the directive whose result is being
|
|
667 adjusted, BASE gives the base of the directive (octal, decimal,
|
|
668 or hex), and ADJ denotes the additional adjustment to the LIKELY
|
|
669 counter that may need to be added when ADJUST is a range. */
|
|
670
|
|
671 fmtresult&
|
|
672 fmtresult::adjust_for_width_or_precision (const HOST_WIDE_INT adjust[2],
|
|
673 tree type /* = NULL_TREE */,
|
|
674 unsigned base /* = 0 */,
|
|
675 unsigned adj /* = 0 */)
|
|
676 {
|
|
677 bool minadjusted = false;
|
|
678
|
|
679 /* Adjust the minimum and likely counters. */
|
|
680 if (adjust[0] >= 0)
|
|
681 {
|
|
682 if (range.min < (unsigned HOST_WIDE_INT)adjust[0])
|
|
683 {
|
|
684 range.min = adjust[0];
|
|
685 minadjusted = true;
|
|
686 }
|
|
687
|
|
688 /* Adjust the likely counter. */
|
|
689 if (range.likely < range.min)
|
|
690 range.likely = range.min;
|
|
691 }
|
|
692 else if (adjust[0] == target_int_min ()
|
|
693 && (unsigned HOST_WIDE_INT)adjust[1] == target_int_max ())
|
|
694 knownrange = false;
|
|
695
|
|
696 /* Adjust the maximum counter. */
|
|
697 if (adjust[1] > 0)
|
|
698 {
|
|
699 if (range.max < (unsigned HOST_WIDE_INT)adjust[1])
|
|
700 {
|
|
701 range.max = adjust[1];
|
|
702
|
|
703 /* Set KNOWNRANGE if both the minimum and maximum have been
|
|
704 adjusted. Otherwise leave it at what it was before. */
|
|
705 knownrange = minadjusted;
|
|
706 }
|
|
707 }
|
|
708
|
|
709 if (warn_level > 1 && type)
|
|
710 {
|
|
711 /* For large non-constant width or precision whose range spans
|
|
712 the maximum number of digits produced by the directive for
|
|
713 any argument, set the likely number of bytes to be at most
|
|
714 the number digits plus other adjustment determined by the
|
|
715 caller (one for sign or two for the hexadecimal "0x"
|
|
716 prefix). */
|
|
717 unsigned dirdigs = type_max_digits (type, base);
|
|
718 if (adjust[0] < dirdigs && dirdigs < adjust[1]
|
|
719 && range.likely < dirdigs)
|
|
720 range.likely = dirdigs + adj;
|
|
721 }
|
|
722 else if (range.likely < (range.min ? range.min : 1))
|
|
723 {
|
|
724 /* Conservatively, set LIKELY to at least MIN but no less than
|
|
725 1 unless MAX is zero. */
|
|
726 range.likely = (range.min
|
|
727 ? range.min
|
|
728 : range.max && (range.max < HOST_WIDE_INT_MAX
|
|
729 || warn_level > 1) ? 1 : 0);
|
|
730 }
|
|
731
|
|
732 /* Finally adjust the unlikely counter to be at least as large as
|
|
733 the maximum. */
|
|
734 if (range.unlikely < range.max)
|
|
735 range.unlikely = range.max;
|
|
736
|
|
737 return *this;
|
|
738 }
|
|
739
|
|
740 /* Return the maximum number of digits a value of TYPE formats in
|
|
741 BASE on output, not counting base prefix . */
|
|
742
|
|
743 unsigned
|
|
744 fmtresult::type_max_digits (tree type, int base)
|
|
745 {
|
|
746 unsigned prec = TYPE_PRECISION (type);
|
|
747 if (base == 8)
|
|
748 return (prec + 2) / 3;
|
|
749
|
|
750 if (base == 16)
|
|
751 return prec / 4;
|
|
752
|
|
753 /* Decimal approximation: yields 3, 5, 10, and 20 for precision
|
|
754 of 8, 16, 32, and 64 bits. */
|
|
755 return prec * 301 / 1000 + 1;
|
|
756 }
|
|
757
|
|
758 static bool
|
|
759 get_int_range (tree, HOST_WIDE_INT *, HOST_WIDE_INT *, bool, HOST_WIDE_INT);
|
|
760
|
|
761 /* Description of a format directive. A directive is either a plain
|
|
762 string or a conversion specification that starts with '%'. */
|
|
763
|
|
764 struct directive
|
|
765 {
|
|
766 /* The 1-based directive number (for debugging). */
|
|
767 unsigned dirno;
|
|
768
|
|
769 /* The first character of the directive and its length. */
|
|
770 const char *beg;
|
|
771 size_t len;
|
|
772
|
|
773 /* A bitmap of flags, one for each character. */
|
|
774 unsigned flags[256 / sizeof (int)];
|
|
775
|
|
776 /* The range of values of the specified width, or -1 if not specified. */
|
|
777 HOST_WIDE_INT width[2];
|
|
778 /* The range of values of the specified precision, or -1 if not
|
|
779 specified. */
|
|
780 HOST_WIDE_INT prec[2];
|
|
781
|
|
782 /* Length modifier. */
|
|
783 format_lengths modifier;
|
|
784
|
|
785 /* Format specifier character. */
|
|
786 char specifier;
|
|
787
|
|
788 /* The argument of the directive or null when the directive doesn't
|
|
789 take one or when none is available (such as for vararg functions). */
|
|
790 tree arg;
|
|
791
|
|
792 /* Format conversion function that given a directive and an argument
|
|
793 returns the formatting result. */
|
|
794 fmtresult (*fmtfunc) (const directive &, tree);
|
|
795
|
|
796 /* Return True when a the format flag CHR has been used. */
|
|
797 bool get_flag (char chr) const
|
|
798 {
|
|
799 unsigned char c = chr & 0xff;
|
|
800 return (flags[c / (CHAR_BIT * sizeof *flags)]
|
|
801 & (1U << (c % (CHAR_BIT * sizeof *flags))));
|
|
802 }
|
|
803
|
|
804 /* Make a record of the format flag CHR having been used. */
|
|
805 void set_flag (char chr)
|
|
806 {
|
|
807 unsigned char c = chr & 0xff;
|
|
808 flags[c / (CHAR_BIT * sizeof *flags)]
|
|
809 |= (1U << (c % (CHAR_BIT * sizeof *flags)));
|
|
810 }
|
|
811
|
|
812 /* Reset the format flag CHR. */
|
|
813 void clear_flag (char chr)
|
|
814 {
|
|
815 unsigned char c = chr & 0xff;
|
|
816 flags[c / (CHAR_BIT * sizeof *flags)]
|
|
817 &= ~(1U << (c % (CHAR_BIT * sizeof *flags)));
|
|
818 }
|
|
819
|
|
820 /* Set both bounds of the width range to VAL. */
|
|
821 void set_width (HOST_WIDE_INT val)
|
|
822 {
|
|
823 width[0] = width[1] = val;
|
|
824 }
|
|
825
|
|
826 /* Set the width range according to ARG, with both bounds being
|
|
827 no less than 0. For a constant ARG set both bounds to its value
|
|
828 or 0, whichever is greater. For a non-constant ARG in some range
|
|
829 set width to its range adjusting each bound to -1 if it's less.
|
|
830 For an indeterminate ARG set width to [0, INT_MAX]. */
|
|
831 void set_width (tree arg)
|
|
832 {
|
|
833 get_int_range (arg, width, width + 1, true, 0);
|
|
834 }
|
|
835
|
|
836 /* Set both bounds of the precision range to VAL. */
|
|
837 void set_precision (HOST_WIDE_INT val)
|
|
838 {
|
|
839 prec[0] = prec[1] = val;
|
|
840 }
|
|
841
|
|
842 /* Set the precision range according to ARG, with both bounds being
|
|
843 no less than -1. For a constant ARG set both bounds to its value
|
|
844 or -1 whichever is greater. For a non-constant ARG in some range
|
|
845 set precision to its range adjusting each bound to -1 if it's less.
|
|
846 For an indeterminate ARG set precision to [-1, INT_MAX]. */
|
|
847 void set_precision (tree arg)
|
|
848 {
|
|
849 get_int_range (arg, prec, prec + 1, false, -1);
|
|
850 }
|
|
851
|
|
852 /* Return true if both width and precision are known to be
|
|
853 either constant or in some range, false otherwise. */
|
|
854 bool known_width_and_precision () const
|
|
855 {
|
|
856 return ((width[1] < 0
|
|
857 || (unsigned HOST_WIDE_INT)width[1] <= target_int_max ())
|
|
858 && (prec[1] < 0
|
|
859 || (unsigned HOST_WIDE_INT)prec[1] < target_int_max ()));
|
|
860 }
|
|
861 };
|
|
862
|
|
863 /* Return the logarithm of X in BASE. */
|
|
864
|
|
865 static int
|
|
866 ilog (unsigned HOST_WIDE_INT x, int base)
|
|
867 {
|
|
868 int res = 0;
|
|
869 do
|
|
870 {
|
|
871 ++res;
|
|
872 x /= base;
|
|
873 } while (x);
|
|
874 return res;
|
|
875 }
|
|
876
|
|
877 /* Return the number of bytes resulting from converting into a string
|
|
878 the INTEGER_CST tree node X in BASE with a minimum of PREC digits.
|
|
879 PLUS indicates whether 1 for a plus sign should be added for positive
|
|
880 numbers, and PREFIX whether the length of an octal ('O') or hexadecimal
|
|
881 ('0x') prefix should be added for nonzero numbers. Return -1 if X cannot
|
|
882 be represented. */
|
|
883
|
|
884 static HOST_WIDE_INT
|
|
885 tree_digits (tree x, int base, HOST_WIDE_INT prec, bool plus, bool prefix)
|
|
886 {
|
|
887 unsigned HOST_WIDE_INT absval;
|
|
888
|
|
889 HOST_WIDE_INT res;
|
|
890
|
|
891 if (TYPE_UNSIGNED (TREE_TYPE (x)))
|
|
892 {
|
|
893 if (tree_fits_uhwi_p (x))
|
|
894 {
|
|
895 absval = tree_to_uhwi (x);
|
|
896 res = plus;
|
|
897 }
|
|
898 else
|
|
899 return -1;
|
|
900 }
|
|
901 else
|
|
902 {
|
|
903 if (tree_fits_shwi_p (x))
|
|
904 {
|
|
905 HOST_WIDE_INT i = tree_to_shwi (x);
|
|
906 if (HOST_WIDE_INT_MIN == i)
|
|
907 {
|
|
908 /* Avoid undefined behavior due to negating a minimum. */
|
|
909 absval = HOST_WIDE_INT_MAX;
|
|
910 res = 1;
|
|
911 }
|
|
912 else if (i < 0)
|
|
913 {
|
|
914 absval = -i;
|
|
915 res = 1;
|
|
916 }
|
|
917 else
|
|
918 {
|
|
919 absval = i;
|
|
920 res = plus;
|
|
921 }
|
|
922 }
|
|
923 else
|
|
924 return -1;
|
|
925 }
|
|
926
|
|
927 int ndigs = ilog (absval, base);
|
|
928
|
|
929 res += prec < ndigs ? ndigs : prec;
|
|
930
|
|
931 /* Adjust a non-zero value for the base prefix, either hexadecimal,
|
|
932 or, unless precision has resulted in a leading zero, also octal. */
|
|
933 if (prefix && absval && (base == 16 || prec <= ndigs))
|
|
934 {
|
|
935 if (base == 8)
|
|
936 res += 1;
|
|
937 else if (base == 16)
|
|
938 res += 2;
|
|
939 }
|
|
940
|
|
941 return res;
|
|
942 }
|
|
943
|
|
944 /* Given the formatting result described by RES and NAVAIL, the number
|
|
945 of available in the destination, return the range of bytes remaining
|
|
946 in the destination. */
|
|
947
|
|
948 static inline result_range
|
|
949 bytes_remaining (unsigned HOST_WIDE_INT navail, const format_result &res)
|
|
950 {
|
|
951 result_range range;
|
|
952
|
|
953 if (HOST_WIDE_INT_MAX <= navail)
|
|
954 {
|
|
955 range.min = range.max = range.likely = range.unlikely = navail;
|
|
956 return range;
|
|
957 }
|
|
958
|
|
959 /* The lower bound of the available range is the available size
|
|
960 minus the maximum output size, and the upper bound is the size
|
|
961 minus the minimum. */
|
|
962 range.max = res.range.min < navail ? navail - res.range.min : 0;
|
|
963
|
|
964 range.likely = res.range.likely < navail ? navail - res.range.likely : 0;
|
|
965
|
|
966 if (res.range.max < HOST_WIDE_INT_MAX)
|
|
967 range.min = res.range.max < navail ? navail - res.range.max : 0;
|
|
968 else
|
|
969 range.min = range.likely;
|
|
970
|
|
971 range.unlikely = (res.range.unlikely < navail
|
|
972 ? navail - res.range.unlikely : 0);
|
|
973
|
|
974 return range;
|
|
975 }
|
|
976
|
|
977 /* Description of a call to a formatted function. */
|
|
978
|
|
979 struct pass_sprintf_length::call_info
|
|
980 {
|
|
981 /* Function call statement. */
|
|
982 gimple *callstmt;
|
|
983
|
|
984 /* Function called. */
|
|
985 tree func;
|
|
986
|
|
987 /* Called built-in function code. */
|
|
988 built_in_function fncode;
|
|
989
|
|
990 /* Format argument and format string extracted from it. */
|
|
991 tree format;
|
|
992 const char *fmtstr;
|
|
993
|
|
994 /* The location of the format argument. */
|
|
995 location_t fmtloc;
|
|
996
|
|
997 /* The destination object size for __builtin___xxx_chk functions
|
|
998 typically determined by __builtin_object_size, or -1 if unknown. */
|
|
999 unsigned HOST_WIDE_INT objsize;
|
|
1000
|
|
1001 /* Number of the first variable argument. */
|
|
1002 unsigned HOST_WIDE_INT argidx;
|
|
1003
|
|
1004 /* True for functions like snprintf that specify the size of
|
|
1005 the destination, false for others like sprintf that don't. */
|
|
1006 bool bounded;
|
|
1007
|
|
1008 /* True for bounded functions like snprintf that specify a zero-size
|
|
1009 buffer as a request to compute the size of output without actually
|
|
1010 writing any. NOWRITE is cleared in response to the %n directive
|
|
1011 which has side-effects similar to writing output. */
|
|
1012 bool nowrite;
|
|
1013
|
|
1014 /* Return true if the called function's return value is used. */
|
|
1015 bool retval_used () const
|
|
1016 {
|
|
1017 return gimple_get_lhs (callstmt);
|
|
1018 }
|
|
1019
|
|
1020 /* Return the warning option corresponding to the called function. */
|
|
1021 int warnopt () const
|
|
1022 {
|
|
1023 return bounded ? OPT_Wformat_truncation_ : OPT_Wformat_overflow_;
|
|
1024 }
|
|
1025 };
|
|
1026
|
|
1027 /* Return the result of formatting a no-op directive (such as '%n'). */
|
|
1028
|
|
1029 static fmtresult
|
|
1030 format_none (const directive &, tree)
|
|
1031 {
|
|
1032 fmtresult res (0);
|
|
1033 return res;
|
|
1034 }
|
|
1035
|
|
1036 /* Return the result of formatting the '%%' directive. */
|
|
1037
|
|
1038 static fmtresult
|
|
1039 format_percent (const directive &, tree)
|
|
1040 {
|
|
1041 fmtresult res (1);
|
|
1042 return res;
|
|
1043 }
|
|
1044
|
|
1045
|
|
1046 /* Compute intmax_type_node and uintmax_type_node similarly to how
|
|
1047 tree.c builds size_type_node. */
|
|
1048
|
|
1049 static void
|
|
1050 build_intmax_type_nodes (tree *pintmax, tree *puintmax)
|
|
1051 {
|
|
1052 if (strcmp (UINTMAX_TYPE, "unsigned int") == 0)
|
|
1053 {
|
|
1054 *pintmax = integer_type_node;
|
|
1055 *puintmax = unsigned_type_node;
|
|
1056 }
|
|
1057 else if (strcmp (UINTMAX_TYPE, "long unsigned int") == 0)
|
|
1058 {
|
|
1059 *pintmax = long_integer_type_node;
|
|
1060 *puintmax = long_unsigned_type_node;
|
|
1061 }
|
|
1062 else if (strcmp (UINTMAX_TYPE, "long long unsigned int") == 0)
|
|
1063 {
|
|
1064 *pintmax = long_long_integer_type_node;
|
|
1065 *puintmax = long_long_unsigned_type_node;
|
|
1066 }
|
|
1067 else
|
|
1068 {
|
|
1069 for (int i = 0; i < NUM_INT_N_ENTS; i++)
|
|
1070 if (int_n_enabled_p[i])
|
|
1071 {
|
|
1072 char name[50];
|
|
1073 sprintf (name, "__int%d unsigned", int_n_data[i].bitsize);
|
|
1074
|
|
1075 if (strcmp (name, UINTMAX_TYPE) == 0)
|
|
1076 {
|
|
1077 *pintmax = int_n_trees[i].signed_type;
|
|
1078 *puintmax = int_n_trees[i].unsigned_type;
|
|
1079 return;
|
|
1080 }
|
|
1081 }
|
|
1082 gcc_unreachable ();
|
|
1083 }
|
|
1084 }
|
|
1085
|
|
1086 /* Determine the range [*PMIN, *PMAX] that the expression ARG is
|
|
1087 in and that is representable in type int.
|
|
1088 Return true when the range is a subrange of that of int.
|
|
1089 When ARG is null it is as if it had the full range of int.
|
|
1090 When ABSOLUTE is true the range reflects the absolute value of
|
|
1091 the argument. When ABSOLUTE is false, negative bounds of
|
|
1092 the determined range are replaced with NEGBOUND. */
|
|
1093
|
|
1094 static bool
|
|
1095 get_int_range (tree arg, HOST_WIDE_INT *pmin, HOST_WIDE_INT *pmax,
|
|
1096 bool absolute, HOST_WIDE_INT negbound)
|
|
1097 {
|
|
1098 /* The type of the result. */
|
|
1099 const_tree type = integer_type_node;
|
|
1100
|
|
1101 bool knownrange = false;
|
|
1102
|
|
1103 if (!arg)
|
|
1104 {
|
|
1105 *pmin = tree_to_shwi (TYPE_MIN_VALUE (type));
|
|
1106 *pmax = tree_to_shwi (TYPE_MAX_VALUE (type));
|
|
1107 }
|
|
1108 else if (TREE_CODE (arg) == INTEGER_CST
|
|
1109 && TYPE_PRECISION (TREE_TYPE (arg)) <= TYPE_PRECISION (type))
|
|
1110 {
|
|
1111 /* For a constant argument return its value adjusted as specified
|
|
1112 by NEGATIVE and NEGBOUND and return true to indicate that the
|
|
1113 result is known. */
|
|
1114 *pmin = tree_fits_shwi_p (arg) ? tree_to_shwi (arg) : tree_to_uhwi (arg);
|
|
1115 *pmax = *pmin;
|
|
1116 knownrange = true;
|
|
1117 }
|
|
1118 else
|
|
1119 {
|
|
1120 /* True if the argument's range cannot be determined. */
|
|
1121 bool unknown = true;
|
|
1122
|
|
1123 tree argtype = TREE_TYPE (arg);
|
|
1124
|
|
1125 /* Ignore invalid arguments with greater precision that that
|
|
1126 of the expected type (e.g., in sprintf("%*i", 12LL, i)).
|
|
1127 They will have been detected and diagnosed by -Wformat and
|
|
1128 so it's not important to complicate this code to try to deal
|
|
1129 with them again. */
|
|
1130 if (TREE_CODE (arg) == SSA_NAME
|
|
1131 && INTEGRAL_TYPE_P (argtype)
|
|
1132 && TYPE_PRECISION (argtype) <= TYPE_PRECISION (type))
|
|
1133 {
|
|
1134 /* Try to determine the range of values of the integer argument. */
|
|
1135 wide_int min, max;
|
|
1136 enum value_range_type range_type = get_range_info (arg, &min, &max);
|
|
1137 if (range_type == VR_RANGE)
|
|
1138 {
|
|
1139 HOST_WIDE_INT type_min
|
|
1140 = (TYPE_UNSIGNED (argtype)
|
|
1141 ? tree_to_uhwi (TYPE_MIN_VALUE (argtype))
|
|
1142 : tree_to_shwi (TYPE_MIN_VALUE (argtype)));
|
|
1143
|
|
1144 HOST_WIDE_INT type_max = tree_to_uhwi (TYPE_MAX_VALUE (argtype));
|
|
1145
|
|
1146 *pmin = min.to_shwi ();
|
|
1147 *pmax = max.to_shwi ();
|
|
1148
|
|
1149 if (*pmin < *pmax)
|
|
1150 {
|
|
1151 /* Return true if the adjusted range is a subrange of
|
|
1152 the full range of the argument's type. *PMAX may
|
|
1153 be less than *PMIN when the argument is unsigned
|
|
1154 and its upper bound is in excess of TYPE_MAX. In
|
|
1155 that (invalid) case disregard the range and use that
|
|
1156 of the expected type instead. */
|
|
1157 knownrange = type_min < *pmin || *pmax < type_max;
|
|
1158
|
|
1159 unknown = false;
|
|
1160 }
|
|
1161 }
|
|
1162 }
|
|
1163
|
|
1164 /* Handle an argument with an unknown range as if none had been
|
|
1165 provided. */
|
|
1166 if (unknown)
|
|
1167 return get_int_range (NULL_TREE, pmin, pmax, absolute, negbound);
|
|
1168 }
|
|
1169
|
|
1170 /* Adjust each bound as specified by ABSOLUTE and NEGBOUND. */
|
|
1171 if (absolute)
|
|
1172 {
|
|
1173 if (*pmin < 0)
|
|
1174 {
|
|
1175 if (*pmin == *pmax)
|
|
1176 *pmin = *pmax = -*pmin;
|
|
1177 else
|
|
1178 {
|
|
1179 /* Make sure signed overlow is avoided. */
|
|
1180 gcc_assert (*pmin != HOST_WIDE_INT_MIN);
|
|
1181
|
|
1182 HOST_WIDE_INT tmp = -*pmin;
|
|
1183 *pmin = 0;
|
|
1184 if (*pmax < tmp)
|
|
1185 *pmax = tmp;
|
|
1186 }
|
|
1187 }
|
|
1188 }
|
|
1189 else if (*pmin < negbound)
|
|
1190 *pmin = negbound;
|
|
1191
|
|
1192 return knownrange;
|
|
1193 }
|
|
1194
|
|
1195 /* With the range [*ARGMIN, *ARGMAX] of an integer directive's actual
|
|
1196 argument, due to the conversion from either *ARGMIN or *ARGMAX to
|
|
1197 the type of the directive's formal argument it's possible for both
|
|
1198 to result in the same number of bytes or a range of bytes that's
|
|
1199 less than the number of bytes that would result from formatting
|
|
1200 some other value in the range [*ARGMIN, *ARGMAX]. This can be
|
|
1201 determined by checking for the actual argument being in the range
|
|
1202 of the type of the directive. If it isn't it must be assumed to
|
|
1203 take on the full range of the directive's type.
|
|
1204 Return true when the range has been adjusted to the full range
|
|
1205 of DIRTYPE, and false otherwise. */
|
|
1206
|
|
1207 static bool
|
|
1208 adjust_range_for_overflow (tree dirtype, tree *argmin, tree *argmax)
|
|
1209 {
|
|
1210 tree argtype = TREE_TYPE (*argmin);
|
|
1211 unsigned argprec = TYPE_PRECISION (argtype);
|
|
1212 unsigned dirprec = TYPE_PRECISION (dirtype);
|
|
1213
|
|
1214 /* If the actual argument and the directive's argument have the same
|
|
1215 precision and sign there can be no overflow and so there is nothing
|
|
1216 to adjust. */
|
|
1217 if (argprec == dirprec && TYPE_SIGN (argtype) == TYPE_SIGN (dirtype))
|
|
1218 return false;
|
|
1219
|
|
1220 /* The logic below was inspired/lifted from the CONVERT_EXPR_CODE_P
|
|
1221 branch in the extract_range_from_unary_expr function in tree-vrp.c. */
|
|
1222
|
|
1223 if (TREE_CODE (*argmin) == INTEGER_CST
|
|
1224 && TREE_CODE (*argmax) == INTEGER_CST
|
|
1225 && (dirprec >= argprec
|
|
1226 || integer_zerop (int_const_binop (RSHIFT_EXPR,
|
|
1227 int_const_binop (MINUS_EXPR,
|
|
1228 *argmax,
|
|
1229 *argmin),
|
|
1230 size_int (dirprec)))))
|
|
1231 {
|
|
1232 *argmin = force_fit_type (dirtype, wi::to_widest (*argmin), 0, false);
|
|
1233 *argmax = force_fit_type (dirtype, wi::to_widest (*argmax), 0, false);
|
|
1234
|
|
1235 /* If *ARGMIN is still less than *ARGMAX the conversion above
|
|
1236 is safe. Otherwise, it has overflowed and would be unsafe. */
|
|
1237 if (tree_int_cst_le (*argmin, *argmax))
|
|
1238 return false;
|
|
1239 }
|
|
1240
|
|
1241 *argmin = TYPE_MIN_VALUE (dirtype);
|
|
1242 *argmax = TYPE_MAX_VALUE (dirtype);
|
|
1243 return true;
|
|
1244 }
|
|
1245
|
|
1246 /* Return a range representing the minimum and maximum number of bytes
|
|
1247 that the format directive DIR will output for any argument given
|
|
1248 the WIDTH and PRECISION (extracted from DIR). This function is
|
|
1249 used when the directive argument or its value isn't known. */
|
|
1250
|
|
1251 static fmtresult
|
|
1252 format_integer (const directive &dir, tree arg)
|
|
1253 {
|
|
1254 tree intmax_type_node;
|
|
1255 tree uintmax_type_node;
|
|
1256
|
|
1257 /* Base to format the number in. */
|
|
1258 int base;
|
|
1259
|
|
1260 /* True when a conversion is preceded by a prefix indicating the base
|
|
1261 of the argument (octal or hexadecimal). */
|
|
1262 bool maybebase = dir.get_flag ('#');
|
|
1263
|
|
1264 /* True when a signed conversion is preceded by a sign or space. */
|
|
1265 bool maybesign = false;
|
|
1266
|
|
1267 /* True for signed conversions (i.e., 'd' and 'i'). */
|
|
1268 bool sign = false;
|
|
1269
|
|
1270 switch (dir.specifier)
|
|
1271 {
|
|
1272 case 'd':
|
|
1273 case 'i':
|
|
1274 /* Space and '+' are only meaningful for signed conversions. */
|
|
1275 maybesign = dir.get_flag (' ') | dir.get_flag ('+');
|
|
1276 sign = true;
|
|
1277 base = 10;
|
|
1278 break;
|
|
1279 case 'u':
|
|
1280 base = 10;
|
|
1281 break;
|
|
1282 case 'o':
|
|
1283 base = 8;
|
|
1284 break;
|
|
1285 case 'X':
|
|
1286 case 'x':
|
|
1287 base = 16;
|
|
1288 break;
|
|
1289 default:
|
|
1290 gcc_unreachable ();
|
|
1291 }
|
|
1292
|
|
1293 /* The type of the "formal" argument expected by the directive. */
|
|
1294 tree dirtype = NULL_TREE;
|
|
1295
|
|
1296 /* Determine the expected type of the argument from the length
|
|
1297 modifier. */
|
|
1298 switch (dir.modifier)
|
|
1299 {
|
|
1300 case FMT_LEN_none:
|
|
1301 if (dir.specifier == 'p')
|
|
1302 dirtype = ptr_type_node;
|
|
1303 else
|
|
1304 dirtype = sign ? integer_type_node : unsigned_type_node;
|
|
1305 break;
|
|
1306
|
|
1307 case FMT_LEN_h:
|
|
1308 dirtype = sign ? short_integer_type_node : short_unsigned_type_node;
|
|
1309 break;
|
|
1310
|
|
1311 case FMT_LEN_hh:
|
|
1312 dirtype = sign ? signed_char_type_node : unsigned_char_type_node;
|
|
1313 break;
|
|
1314
|
|
1315 case FMT_LEN_l:
|
|
1316 dirtype = sign ? long_integer_type_node : long_unsigned_type_node;
|
|
1317 break;
|
|
1318
|
|
1319 case FMT_LEN_L:
|
|
1320 case FMT_LEN_ll:
|
|
1321 dirtype = (sign
|
|
1322 ? long_long_integer_type_node
|
|
1323 : long_long_unsigned_type_node);
|
|
1324 break;
|
|
1325
|
|
1326 case FMT_LEN_z:
|
|
1327 dirtype = signed_or_unsigned_type_for (!sign, size_type_node);
|
|
1328 break;
|
|
1329
|
|
1330 case FMT_LEN_t:
|
|
1331 dirtype = signed_or_unsigned_type_for (!sign, ptrdiff_type_node);
|
|
1332 break;
|
|
1333
|
|
1334 case FMT_LEN_j:
|
|
1335 build_intmax_type_nodes (&intmax_type_node, &uintmax_type_node);
|
|
1336 dirtype = sign ? intmax_type_node : uintmax_type_node;
|
|
1337 break;
|
|
1338
|
|
1339 default:
|
|
1340 return fmtresult ();
|
|
1341 }
|
|
1342
|
|
1343 /* The type of the argument to the directive, either deduced from
|
|
1344 the actual non-constant argument if one is known, or from
|
|
1345 the directive itself when none has been provided because it's
|
|
1346 a va_list. */
|
|
1347 tree argtype = NULL_TREE;
|
|
1348
|
|
1349 if (!arg)
|
|
1350 {
|
|
1351 /* When the argument has not been provided, use the type of
|
|
1352 the directive's argument as an approximation. This will
|
|
1353 result in false positives for directives like %i with
|
|
1354 arguments with smaller precision (such as short or char). */
|
|
1355 argtype = dirtype;
|
|
1356 }
|
|
1357 else if (TREE_CODE (arg) == INTEGER_CST)
|
|
1358 {
|
|
1359 /* When a constant argument has been provided use its value
|
|
1360 rather than type to determine the length of the output. */
|
|
1361 fmtresult res;
|
|
1362
|
|
1363 if ((dir.prec[0] <= 0 && dir.prec[1] >= 0) && integer_zerop (arg))
|
|
1364 {
|
|
1365 /* As a special case, a precision of zero with a zero argument
|
|
1366 results in zero bytes except in base 8 when the '#' flag is
|
|
1367 specified, and for signed conversions in base 8 and 10 when
|
|
1368 either the space or '+' flag has been specified and it results
|
|
1369 in just one byte (with width having the normal effect). This
|
|
1370 must extend to the case of a specified precision with
|
|
1371 an unknown value because it can be zero. */
|
|
1372 res.range.min = ((base == 8 && dir.get_flag ('#')) || maybesign);
|
|
1373 if (res.range.min == 0 && dir.prec[0] != dir.prec[1])
|
|
1374 {
|
|
1375 res.range.max = 1;
|
|
1376 res.range.likely = 1;
|
|
1377 }
|
|
1378 else
|
|
1379 {
|
|
1380 res.range.max = res.range.min;
|
|
1381 res.range.likely = res.range.min;
|
|
1382 }
|
|
1383 }
|
|
1384 else
|
|
1385 {
|
|
1386 /* Convert the argument to the type of the directive. */
|
|
1387 arg = fold_convert (dirtype, arg);
|
|
1388
|
|
1389 res.range.min = tree_digits (arg, base, dir.prec[0],
|
|
1390 maybesign, maybebase);
|
|
1391 if (dir.prec[0] == dir.prec[1])
|
|
1392 res.range.max = res.range.min;
|
|
1393 else
|
|
1394 res.range.max = tree_digits (arg, base, dir.prec[1],
|
|
1395 maybesign, maybebase);
|
|
1396 res.range.likely = res.range.min;
|
|
1397 res.knownrange = true;
|
|
1398 }
|
|
1399
|
|
1400 res.range.unlikely = res.range.max;
|
|
1401
|
|
1402 /* Bump up the counters if WIDTH is greater than LEN. */
|
|
1403 res.adjust_for_width_or_precision (dir.width, dirtype, base,
|
|
1404 (sign | maybebase) + (base == 16));
|
|
1405 /* Bump up the counters again if PRECision is greater still. */
|
|
1406 res.adjust_for_width_or_precision (dir.prec, dirtype, base,
|
|
1407 (sign | maybebase) + (base == 16));
|
|
1408
|
|
1409 return res;
|
|
1410 }
|
|
1411 else if (INTEGRAL_TYPE_P (TREE_TYPE (arg))
|
|
1412 || TREE_CODE (TREE_TYPE (arg)) == POINTER_TYPE)
|
|
1413 /* Determine the type of the provided non-constant argument. */
|
|
1414 argtype = TREE_TYPE (arg);
|
|
1415 else
|
|
1416 /* Don't bother with invalid arguments since they likely would
|
|
1417 have already been diagnosed, and disable any further checking
|
|
1418 of the format string by returning [-1, -1]. */
|
|
1419 return fmtresult ();
|
|
1420
|
|
1421 fmtresult res;
|
|
1422
|
|
1423 /* Using either the range the non-constant argument is in, or its
|
|
1424 type (either "formal" or actual), create a range of values that
|
|
1425 constrain the length of output given the warning level. */
|
|
1426 tree argmin = NULL_TREE;
|
|
1427 tree argmax = NULL_TREE;
|
|
1428
|
|
1429 if (arg
|
|
1430 && TREE_CODE (arg) == SSA_NAME
|
|
1431 && INTEGRAL_TYPE_P (argtype))
|
|
1432 {
|
|
1433 /* Try to determine the range of values of the integer argument
|
|
1434 (range information is not available for pointers). */
|
|
1435 wide_int min, max;
|
|
1436 enum value_range_type range_type = get_range_info (arg, &min, &max);
|
|
1437 if (range_type == VR_RANGE)
|
|
1438 {
|
|
1439 argmin = wide_int_to_tree (argtype, min);
|
|
1440 argmax = wide_int_to_tree (argtype, max);
|
|
1441
|
|
1442 /* Set KNOWNRANGE if the argument is in a known subrange
|
|
1443 of the directive's type and neither width nor precision
|
|
1444 is unknown. (KNOWNRANGE may be reset below). */
|
|
1445 res.knownrange
|
|
1446 = ((!tree_int_cst_equal (TYPE_MIN_VALUE (dirtype), argmin)
|
|
1447 || !tree_int_cst_equal (TYPE_MAX_VALUE (dirtype), argmax))
|
|
1448 && dir.known_width_and_precision ());
|
|
1449
|
|
1450 res.argmin = argmin;
|
|
1451 res.argmax = argmax;
|
|
1452 }
|
|
1453 else if (range_type == VR_ANTI_RANGE)
|
|
1454 {
|
|
1455 /* Handle anti-ranges if/when bug 71690 is resolved. */
|
|
1456 }
|
|
1457 else if (range_type == VR_VARYING)
|
|
1458 {
|
|
1459 /* The argument here may be the result of promoting the actual
|
|
1460 argument to int. Try to determine the type of the actual
|
|
1461 argument before promotion and narrow down its range that
|
|
1462 way. */
|
|
1463 gimple *def = SSA_NAME_DEF_STMT (arg);
|
|
1464 if (is_gimple_assign (def))
|
|
1465 {
|
|
1466 tree_code code = gimple_assign_rhs_code (def);
|
|
1467 if (code == INTEGER_CST)
|
|
1468 {
|
|
1469 arg = gimple_assign_rhs1 (def);
|
|
1470 return format_integer (dir, arg);
|
|
1471 }
|
|
1472
|
|
1473 if (code == NOP_EXPR)
|
|
1474 {
|
|
1475 tree type = TREE_TYPE (gimple_assign_rhs1 (def));
|
|
1476 if (INTEGRAL_TYPE_P (type)
|
|
1477 || TREE_CODE (type) == POINTER_TYPE)
|
|
1478 argtype = type;
|
|
1479 }
|
|
1480 }
|
|
1481 }
|
|
1482 }
|
|
1483
|
|
1484 if (!argmin)
|
|
1485 {
|
|
1486 if (TREE_CODE (argtype) == POINTER_TYPE)
|
|
1487 {
|
|
1488 argmin = build_int_cst (pointer_sized_int_node, 0);
|
|
1489 argmax = build_all_ones_cst (pointer_sized_int_node);
|
|
1490 }
|
|
1491 else
|
|
1492 {
|
|
1493 argmin = TYPE_MIN_VALUE (argtype);
|
|
1494 argmax = TYPE_MAX_VALUE (argtype);
|
|
1495 }
|
|
1496 }
|
|
1497
|
|
1498 /* Clear KNOWNRANGE if the range has been adjusted to the maximum
|
|
1499 of the directive. If it has been cleared then since ARGMIN and/or
|
|
1500 ARGMAX have been adjusted also adjust the corresponding ARGMIN and
|
|
1501 ARGMAX in the result to include in diagnostics. */
|
|
1502 if (adjust_range_for_overflow (dirtype, &argmin, &argmax))
|
|
1503 {
|
|
1504 res.knownrange = false;
|
|
1505 res.argmin = argmin;
|
|
1506 res.argmax = argmax;
|
|
1507 }
|
|
1508
|
|
1509 /* Recursively compute the minimum and maximum from the known range. */
|
|
1510 if (TYPE_UNSIGNED (dirtype) || tree_int_cst_sgn (argmin) >= 0)
|
|
1511 {
|
|
1512 /* For unsigned conversions/directives or signed when
|
|
1513 the minimum is positive, use the minimum and maximum to compute
|
|
1514 the shortest and longest output, respectively. */
|
|
1515 res.range.min = format_integer (dir, argmin).range.min;
|
|
1516 res.range.max = format_integer (dir, argmax).range.max;
|
|
1517 }
|
|
1518 else if (tree_int_cst_sgn (argmax) < 0)
|
|
1519 {
|
|
1520 /* For signed conversions/directives if maximum is negative,
|
|
1521 use the minimum as the longest output and maximum as the
|
|
1522 shortest output. */
|
|
1523 res.range.min = format_integer (dir, argmax).range.min;
|
|
1524 res.range.max = format_integer (dir, argmin).range.max;
|
|
1525 }
|
|
1526 else
|
|
1527 {
|
|
1528 /* Otherwise, 0 is inside of the range and minimum negative. Use 0
|
|
1529 as the shortest output and for the longest output compute the
|
|
1530 length of the output of both minimum and maximum and pick the
|
|
1531 longer. */
|
|
1532 unsigned HOST_WIDE_INT max1 = format_integer (dir, argmin).range.max;
|
|
1533 unsigned HOST_WIDE_INT max2 = format_integer (dir, argmax).range.max;
|
|
1534 res.range.min = format_integer (dir, integer_zero_node).range.min;
|
|
1535 res.range.max = MAX (max1, max2);
|
|
1536 }
|
|
1537
|
|
1538 /* If the range is known, use the maximum as the likely length. */
|
|
1539 if (res.knownrange)
|
|
1540 res.range.likely = res.range.max;
|
|
1541 else
|
|
1542 {
|
|
1543 /* Otherwise, use the minimum. Except for the case where for %#x or
|
|
1544 %#o the minimum is just for a single value in the range (0) and
|
|
1545 for all other values it is something longer, like 0x1 or 01.
|
|
1546 Use the length for value 1 in that case instead as the likely
|
|
1547 length. */
|
|
1548 res.range.likely = res.range.min;
|
|
1549 if (maybebase
|
|
1550 && base != 10
|
|
1551 && (tree_int_cst_sgn (argmin) < 0 || tree_int_cst_sgn (argmax) > 0))
|
|
1552 {
|
|
1553 if (res.range.min == 1)
|
|
1554 res.range.likely += base == 8 ? 1 : 2;
|
|
1555 else if (res.range.min == 2
|
|
1556 && base == 16
|
|
1557 && (dir.width[0] == 2 || dir.prec[0] == 2))
|
|
1558 ++res.range.likely;
|
|
1559 }
|
|
1560 }
|
|
1561
|
|
1562 res.range.unlikely = res.range.max;
|
|
1563 res.adjust_for_width_or_precision (dir.width, dirtype, base,
|
|
1564 (sign | maybebase) + (base == 16));
|
|
1565 res.adjust_for_width_or_precision (dir.prec, dirtype, base,
|
|
1566 (sign | maybebase) + (base == 16));
|
|
1567
|
|
1568 return res;
|
|
1569 }
|
|
1570
|
|
1571 /* Return the number of bytes that a format directive consisting of FLAGS,
|
|
1572 PRECision, format SPECification, and MPFR rounding specifier RNDSPEC,
|
|
1573 would result for argument X under ideal conditions (i.e., if PREC
|
|
1574 weren't excessive). MPFR 3.1 allocates large amounts of memory for
|
|
1575 values of PREC with large magnitude and can fail (see MPFR bug #21056).
|
|
1576 This function works around those problems. */
|
|
1577
|
|
1578 static unsigned HOST_WIDE_INT
|
|
1579 get_mpfr_format_length (mpfr_ptr x, const char *flags, HOST_WIDE_INT prec,
|
|
1580 char spec, char rndspec)
|
|
1581 {
|
|
1582 char fmtstr[40];
|
|
1583
|
|
1584 HOST_WIDE_INT len = strlen (flags);
|
|
1585
|
|
1586 fmtstr[0] = '%';
|
|
1587 memcpy (fmtstr + 1, flags, len);
|
|
1588 memcpy (fmtstr + 1 + len, ".*R", 3);
|
|
1589 fmtstr[len + 4] = rndspec;
|
|
1590 fmtstr[len + 5] = spec;
|
|
1591 fmtstr[len + 6] = '\0';
|
|
1592
|
|
1593 spec = TOUPPER (spec);
|
|
1594 if (spec == 'E' || spec == 'F')
|
|
1595 {
|
|
1596 /* For %e, specify the precision explicitly since mpfr_sprintf
|
|
1597 does its own thing just to be different (see MPFR bug 21088). */
|
|
1598 if (prec < 0)
|
|
1599 prec = 6;
|
|
1600 }
|
|
1601 else
|
|
1602 {
|
|
1603 /* Avoid passing negative precisions with larger magnitude to MPFR
|
|
1604 to avoid exposing its bugs. (A negative precision is supposed
|
|
1605 to be ignored.) */
|
|
1606 if (prec < 0)
|
|
1607 prec = -1;
|
|
1608 }
|
|
1609
|
|
1610 HOST_WIDE_INT p = prec;
|
|
1611
|
|
1612 if (spec == 'G' && !strchr (flags, '#'))
|
|
1613 {
|
|
1614 /* For G/g without the pound flag, precision gives the maximum number
|
|
1615 of significant digits which is bounded by LDBL_MAX_10_EXP, or, for
|
|
1616 a 128 bit IEEE extended precision, 4932. Using twice as much here
|
|
1617 should be more than sufficient for any real format. */
|
|
1618 if ((IEEE_MAX_10_EXP * 2) < prec)
|
|
1619 prec = IEEE_MAX_10_EXP * 2;
|
|
1620 p = prec;
|
|
1621 }
|
|
1622 else
|
|
1623 {
|
|
1624 /* Cap precision arbitrarily at 1KB and add the difference
|
|
1625 (if any) to the MPFR result. */
|
|
1626 if (prec > 1024)
|
|
1627 p = 1024;
|
|
1628 }
|
|
1629
|
|
1630 len = mpfr_snprintf (NULL, 0, fmtstr, (int)p, x);
|
|
1631
|
|
1632 /* Handle the unlikely (impossible?) error by returning more than
|
|
1633 the maximum dictated by the function's return type. */
|
|
1634 if (len < 0)
|
|
1635 return target_dir_max () + 1;
|
|
1636
|
|
1637 /* Adjust the return value by the difference. */
|
|
1638 if (p < prec)
|
|
1639 len += prec - p;
|
|
1640
|
|
1641 return len;
|
|
1642 }
|
|
1643
|
|
1644 /* Return the number of bytes to format using the format specifier
|
|
1645 SPEC and the precision PREC the largest value in the real floating
|
|
1646 TYPE. */
|
|
1647
|
|
1648 static unsigned HOST_WIDE_INT
|
|
1649 format_floating_max (tree type, char spec, HOST_WIDE_INT prec)
|
|
1650 {
|
|
1651 machine_mode mode = TYPE_MODE (type);
|
|
1652
|
|
1653 /* IBM Extended mode. */
|
|
1654 if (MODE_COMPOSITE_P (mode))
|
|
1655 mode = DFmode;
|
|
1656
|
|
1657 /* Get the real type format desription for the target. */
|
|
1658 const real_format *rfmt = REAL_MODE_FORMAT (mode);
|
|
1659 REAL_VALUE_TYPE rv;
|
|
1660
|
|
1661 real_maxval (&rv, 0, mode);
|
|
1662
|
|
1663 /* Convert the GCC real value representation with the precision
|
|
1664 of the real type to the mpfr_t format with the GCC default
|
|
1665 round-to-nearest mode. */
|
|
1666 mpfr_t x;
|
|
1667 mpfr_init2 (x, rfmt->p);
|
|
1668 mpfr_from_real (x, &rv, GMP_RNDN);
|
|
1669
|
|
1670 /* Return a value one greater to account for the leading minus sign. */
|
|
1671 unsigned HOST_WIDE_INT r
|
|
1672 = 1 + get_mpfr_format_length (x, "", prec, spec, 'D');
|
|
1673 mpfr_clear (x);
|
|
1674 return r;
|
|
1675 }
|
|
1676
|
|
1677 /* Return a range representing the minimum and maximum number of bytes
|
|
1678 that the directive DIR will output for any argument. PREC gives
|
|
1679 the adjusted precision range to account for negative precisions
|
|
1680 meaning the default 6. This function is used when the directive
|
|
1681 argument or its value isn't known. */
|
|
1682
|
|
1683 static fmtresult
|
|
1684 format_floating (const directive &dir, const HOST_WIDE_INT prec[2])
|
|
1685 {
|
|
1686 tree type;
|
|
1687
|
|
1688 switch (dir.modifier)
|
|
1689 {
|
|
1690 case FMT_LEN_l:
|
|
1691 case FMT_LEN_none:
|
|
1692 type = double_type_node;
|
|
1693 break;
|
|
1694
|
|
1695 case FMT_LEN_L:
|
|
1696 type = long_double_type_node;
|
|
1697 break;
|
|
1698
|
|
1699 case FMT_LEN_ll:
|
|
1700 type = long_double_type_node;
|
|
1701 break;
|
|
1702
|
|
1703 default:
|
|
1704 return fmtresult ();
|
|
1705 }
|
|
1706
|
|
1707 /* The minimum and maximum number of bytes produced by the directive. */
|
|
1708 fmtresult res;
|
|
1709
|
|
1710 /* The minimum output as determined by flags. It's always at least 1.
|
|
1711 When plus or space are set the output is preceded by either a sign
|
|
1712 or a space. */
|
|
1713 unsigned flagmin = (1 /* for the first digit */
|
|
1714 + (dir.get_flag ('+') | dir.get_flag (' ')));
|
|
1715
|
|
1716 /* When the pound flag is set the decimal point is included in output
|
|
1717 regardless of precision. Whether or not a decimal point is included
|
|
1718 otherwise depends on the specification and precision. */
|
|
1719 bool radix = dir.get_flag ('#');
|
|
1720
|
|
1721 switch (dir.specifier)
|
|
1722 {
|
|
1723 case 'A':
|
|
1724 case 'a':
|
|
1725 {
|
|
1726 HOST_WIDE_INT minprec = 6 + !radix /* decimal point */;
|
|
1727 if (dir.prec[0] <= 0)
|
|
1728 minprec = 0;
|
|
1729 else if (dir.prec[0] > 0)
|
|
1730 minprec = dir.prec[0] + !radix /* decimal point */;
|
|
1731
|
|
1732 res.range.min = (2 /* 0x */
|
|
1733 + flagmin
|
|
1734 + radix
|
|
1735 + minprec
|
|
1736 + 3 /* p+0 */);
|
|
1737
|
|
1738 res.range.max = format_floating_max (type, 'a', prec[1]);
|
|
1739 res.range.likely = res.range.min;
|
|
1740
|
|
1741 /* The unlikely maximum accounts for the longest multibyte
|
|
1742 decimal point character. */
|
|
1743 res.range.unlikely = res.range.max;
|
|
1744 if (dir.prec[1] > 0)
|
|
1745 res.range.unlikely += target_mb_len_max () - 1;
|
|
1746
|
|
1747 break;
|
|
1748 }
|
|
1749
|
|
1750 case 'E':
|
|
1751 case 'e':
|
|
1752 {
|
|
1753 /* Minimum output attributable to precision and, when it's
|
|
1754 non-zero, decimal point. */
|
|
1755 HOST_WIDE_INT minprec = prec[0] ? prec[0] + !radix : 0;
|
|
1756
|
|
1757 /* The minimum output is "[-+]1.234567e+00" regardless
|
|
1758 of the value of the actual argument. */
|
|
1759 res.range.min = (flagmin
|
|
1760 + radix
|
|
1761 + minprec
|
|
1762 + 2 /* e+ */ + 2);
|
|
1763
|
|
1764 res.range.max = format_floating_max (type, 'e', prec[1]);
|
|
1765 res.range.likely = res.range.min;
|
|
1766
|
|
1767 /* The unlikely maximum accounts for the longest multibyte
|
|
1768 decimal point character. */
|
|
1769 if (dir.prec[0] != dir.prec[1]
|
|
1770 || dir.prec[0] == -1 || dir.prec[0] > 0)
|
|
1771 res.range.unlikely = res.range.max + target_mb_len_max () -1;
|
|
1772 else
|
|
1773 res.range.unlikely = res.range.max;
|
|
1774 break;
|
|
1775 }
|
|
1776
|
|
1777 case 'F':
|
|
1778 case 'f':
|
|
1779 {
|
|
1780 /* Minimum output attributable to precision and, when it's non-zero,
|
|
1781 decimal point. */
|
|
1782 HOST_WIDE_INT minprec = prec[0] ? prec[0] + !radix : 0;
|
|
1783
|
|
1784 /* The lower bound when precision isn't specified is 8 bytes
|
|
1785 ("1.23456" since precision is taken to be 6). When precision
|
|
1786 is zero, the lower bound is 1 byte (e.g., "1"). Otherwise,
|
|
1787 when precision is greater than zero, then the lower bound
|
|
1788 is 2 plus precision (plus flags). */
|
|
1789 res.range.min = flagmin + radix + minprec;
|
|
1790
|
|
1791 /* Compute the upper bound for -TYPE_MAX. */
|
|
1792 res.range.max = format_floating_max (type, 'f', prec[1]);
|
|
1793
|
|
1794 /* The minimum output with unknown precision is a single byte
|
|
1795 (e.g., "0") but the more likely output is 3 bytes ("0.0"). */
|
|
1796 if (dir.prec[0] < 0 && dir.prec[1] > 0)
|
|
1797 res.range.likely = 3;
|
|
1798 else
|
|
1799 res.range.likely = res.range.min;
|
|
1800
|
|
1801 /* The unlikely maximum accounts for the longest multibyte
|
|
1802 decimal point character. */
|
|
1803 if (dir.prec[0] != dir.prec[1]
|
|
1804 || dir.prec[0] == -1 || dir.prec[0] > 0)
|
|
1805 res.range.unlikely = res.range.max + target_mb_len_max () - 1;
|
|
1806 break;
|
|
1807 }
|
|
1808
|
|
1809 case 'G':
|
|
1810 case 'g':
|
|
1811 {
|
|
1812 /* The %g output depends on precision and the exponent of
|
|
1813 the argument. Since the value of the argument isn't known
|
|
1814 the lower bound on the range of bytes (not counting flags
|
|
1815 or width) is 1 plus radix (i.e., either "0" or "0." for
|
|
1816 "%g" and "%#g", respectively, with a zero argument). */
|
|
1817 res.range.min = flagmin + radix;
|
|
1818
|
|
1819 char spec = 'g';
|
|
1820 HOST_WIDE_INT maxprec = dir.prec[1];
|
|
1821 if (radix && maxprec)
|
|
1822 {
|
|
1823 /* When the pound flag (radix) is set, trailing zeros aren't
|
|
1824 trimmed and so the longest output is the same as for %e,
|
|
1825 except with precision minus 1 (as specified in C11). */
|
|
1826 spec = 'e';
|
|
1827 if (maxprec > 0)
|
|
1828 --maxprec;
|
|
1829 else if (maxprec < 0)
|
|
1830 maxprec = 5;
|
|
1831 }
|
|
1832 else
|
|
1833 maxprec = prec[1];
|
|
1834
|
|
1835 res.range.max = format_floating_max (type, spec, maxprec);
|
|
1836
|
|
1837 /* The likely output is either the maximum computed above
|
|
1838 minus 1 (assuming the maximum is positive) when precision
|
|
1839 is known (or unspecified), or the same minimum as for %e
|
|
1840 (which is computed for a non-negative argument). Unlike
|
|
1841 for the other specifiers above the likely output isn't
|
|
1842 the minimum because for %g that's 1 which is unlikely. */
|
|
1843 if (dir.prec[1] < 0
|
|
1844 || (unsigned HOST_WIDE_INT)dir.prec[1] < target_int_max ())
|
|
1845 res.range.likely = res.range.max - 1;
|
|
1846 else
|
|
1847 {
|
|
1848 HOST_WIDE_INT minprec = 6 + !radix /* decimal point */;
|
|
1849 res.range.likely = (flagmin
|
|
1850 + radix
|
|
1851 + minprec
|
|
1852 + 2 /* e+ */ + 2);
|
|
1853 }
|
|
1854
|
|
1855 /* The unlikely maximum accounts for the longest multibyte
|
|
1856 decimal point character. */
|
|
1857 res.range.unlikely = res.range.max + target_mb_len_max () - 1;
|
|
1858 break;
|
|
1859 }
|
|
1860
|
|
1861 default:
|
|
1862 return fmtresult ();
|
|
1863 }
|
|
1864
|
|
1865 /* Bump up the byte counters if WIDTH is greater. */
|
|
1866 res.adjust_for_width_or_precision (dir.width);
|
|
1867 return res;
|
|
1868 }
|
|
1869
|
|
1870 /* Return a range representing the minimum and maximum number of bytes
|
|
1871 that the directive DIR will write on output for the floating argument
|
|
1872 ARG. */
|
|
1873
|
|
1874 static fmtresult
|
|
1875 format_floating (const directive &dir, tree arg)
|
|
1876 {
|
|
1877 HOST_WIDE_INT prec[] = { dir.prec[0], dir.prec[1] };
|
|
1878
|
|
1879 /* For an indeterminate precision the lower bound must be assumed
|
|
1880 to be zero. */
|
|
1881 if (TOUPPER (dir.specifier) == 'A')
|
|
1882 {
|
|
1883 /* Get the number of fractional decimal digits needed to represent
|
|
1884 the argument without a loss of accuracy. */
|
|
1885 tree type = arg ? TREE_TYPE (arg) :
|
|
1886 (dir.modifier == FMT_LEN_L || dir.modifier == FMT_LEN_ll
|
|
1887 ? long_double_type_node : double_type_node);
|
|
1888
|
|
1889 unsigned fmtprec
|
|
1890 = REAL_MODE_FORMAT (TYPE_MODE (type))->p;
|
|
1891
|
|
1892 /* The precision of the IEEE 754 double format is 53.
|
|
1893 The precision of all other GCC binary double formats
|
|
1894 is 56 or less. */
|
|
1895 unsigned maxprec = fmtprec <= 56 ? 13 : 15;
|
|
1896
|
|
1897 /* For %a, leave the minimum precision unspecified to let
|
|
1898 MFPR trim trailing zeros (as it and many other systems
|
|
1899 including Glibc happen to do) and set the maximum
|
|
1900 precision to reflect what it would be with trailing zeros
|
|
1901 present (as Solaris and derived systems do). */
|
|
1902 if (dir.prec[1] < 0)
|
|
1903 {
|
|
1904 /* Both bounds are negative implies that precision has
|
|
1905 not been specified. */
|
|
1906 prec[0] = maxprec;
|
|
1907 prec[1] = -1;
|
|
1908 }
|
|
1909 else if (dir.prec[0] < 0)
|
|
1910 {
|
|
1911 /* With a negative lower bound and a non-negative upper
|
|
1912 bound set the minimum precision to zero and the maximum
|
|
1913 to the greater of the maximum precision (i.e., with
|
|
1914 trailing zeros present) and the specified upper bound. */
|
|
1915 prec[0] = 0;
|
|
1916 prec[1] = dir.prec[1] < maxprec ? maxprec : dir.prec[1];
|
|
1917 }
|
|
1918 }
|
|
1919 else if (dir.prec[0] < 0)
|
|
1920 {
|
|
1921 if (dir.prec[1] < 0)
|
|
1922 {
|
|
1923 /* A precision in a strictly negative range is ignored and
|
|
1924 the default of 6 is used instead. */
|
|
1925 prec[0] = prec[1] = 6;
|
|
1926 }
|
|
1927 else
|
|
1928 {
|
|
1929 /* For a precision in a partly negative range, the lower bound
|
|
1930 must be assumed to be zero and the new upper bound is the
|
|
1931 greater of 6 (the default precision used when the specified
|
|
1932 precision is negative) and the upper bound of the specified
|
|
1933 range. */
|
|
1934 prec[0] = 0;
|
|
1935 prec[1] = dir.prec[1] < 6 ? 6 : dir.prec[1];
|
|
1936 }
|
|
1937 }
|
|
1938
|
|
1939 if (!arg || TREE_CODE (arg) != REAL_CST)
|
|
1940 return format_floating (dir, prec);
|
|
1941
|
|
1942 /* The minimum and maximum number of bytes produced by the directive. */
|
|
1943 fmtresult res;
|
|
1944
|
|
1945 /* Get the real type format desription for the target. */
|
|
1946 const REAL_VALUE_TYPE *rvp = TREE_REAL_CST_PTR (arg);
|
|
1947 const real_format *rfmt = REAL_MODE_FORMAT (TYPE_MODE (TREE_TYPE (arg)));
|
|
1948
|
|
1949 char fmtstr [40];
|
|
1950 char *pfmt = fmtstr;
|
|
1951
|
|
1952 /* Append flags. */
|
|
1953 for (const char *pf = "-+ #0"; *pf; ++pf)
|
|
1954 if (dir.get_flag (*pf))
|
|
1955 *pfmt++ = *pf;
|
|
1956
|
|
1957 *pfmt = '\0';
|
|
1958
|
|
1959 {
|
|
1960 /* Set up an array to easily iterate over. */
|
|
1961 unsigned HOST_WIDE_INT* const minmax[] = {
|
|
1962 &res.range.min, &res.range.max
|
|
1963 };
|
|
1964
|
|
1965 for (int i = 0; i != sizeof minmax / sizeof *minmax; ++i)
|
|
1966 {
|
|
1967 /* Convert the GCC real value representation with the precision
|
|
1968 of the real type to the mpfr_t format rounding down in the
|
|
1969 first iteration that computes the minimm and up in the second
|
|
1970 that computes the maximum. This order is arbibtrary because
|
|
1971 rounding in either direction can result in longer output. */
|
|
1972 mpfr_t mpfrval;
|
|
1973 mpfr_init2 (mpfrval, rfmt->p);
|
|
1974 mpfr_from_real (mpfrval, rvp, i ? GMP_RNDU : GMP_RNDD);
|
|
1975
|
|
1976 /* Use the MPFR rounding specifier to round down in the first
|
|
1977 iteration and then up. In most but not all cases this will
|
|
1978 result in the same number of bytes. */
|
|
1979 char rndspec = "DU"[i];
|
|
1980
|
|
1981 /* Format it and store the result in the corresponding member
|
|
1982 of the result struct. */
|
|
1983 *minmax[i] = get_mpfr_format_length (mpfrval, fmtstr, prec[i],
|
|
1984 dir.specifier, rndspec);
|
|
1985 mpfr_clear (mpfrval);
|
|
1986 }
|
|
1987 }
|
|
1988
|
|
1989 /* Make sure the minimum is less than the maximum (MPFR rounding
|
|
1990 in the call to mpfr_snprintf can result in the reverse. */
|
|
1991 if (res.range.max < res.range.min)
|
|
1992 {
|
|
1993 unsigned HOST_WIDE_INT tmp = res.range.min;
|
|
1994 res.range.min = res.range.max;
|
|
1995 res.range.max = tmp;
|
|
1996 }
|
|
1997
|
|
1998 /* The range is known unless either width or precision is unknown. */
|
|
1999 res.knownrange = dir.known_width_and_precision ();
|
|
2000
|
|
2001 /* For the same floating point constant, unless width or precision
|
|
2002 is unknown, use the longer output as the likely maximum since
|
|
2003 with round to nearest either is equally likely. Otheriwse, when
|
|
2004 precision is unknown, use the greater of the minimum and 3 as
|
|
2005 the likely output (for "0.0" since zero precision is unlikely). */
|
|
2006 if (res.knownrange)
|
|
2007 res.range.likely = res.range.max;
|
|
2008 else if (res.range.min < 3
|
|
2009 && dir.prec[0] < 0
|
|
2010 && (unsigned HOST_WIDE_INT)dir.prec[1] == target_int_max ())
|
|
2011 res.range.likely = 3;
|
|
2012 else
|
|
2013 res.range.likely = res.range.min;
|
|
2014
|
|
2015 res.range.unlikely = res.range.max;
|
|
2016
|
|
2017 if (res.range.max > 2 && (prec[0] != 0 || prec[1] != 0))
|
|
2018 {
|
|
2019 /* Unless the precision is zero output longer than 2 bytes may
|
|
2020 include the decimal point which must be a single character
|
|
2021 up to MB_LEN_MAX in length. This is overly conservative
|
|
2022 since in some conversions some constants result in no decimal
|
|
2023 point (e.g., in %g). */
|
|
2024 res.range.unlikely += target_mb_len_max () - 1;
|
|
2025 }
|
|
2026
|
|
2027 res.adjust_for_width_or_precision (dir.width);
|
|
2028 return res;
|
|
2029 }
|
|
2030
|
|
2031 /* Return a FMTRESULT struct set to the lengths of the shortest and longest
|
|
2032 strings referenced by the expression STR, or (-1, -1) when not known.
|
|
2033 Used by the format_string function below. */
|
|
2034
|
|
2035 static fmtresult
|
|
2036 get_string_length (tree str)
|
|
2037 {
|
|
2038 if (!str)
|
|
2039 return fmtresult ();
|
|
2040
|
|
2041 if (tree slen = c_strlen (str, 1))
|
|
2042 {
|
|
2043 /* Simply return the length of the string. */
|
|
2044 fmtresult res (tree_to_shwi (slen));
|
|
2045 return res;
|
|
2046 }
|
|
2047
|
|
2048 /* Determine the length of the shortest and longest string referenced
|
|
2049 by STR. Strings of unknown lengths are bounded by the sizes of
|
|
2050 arrays that subexpressions of STR may refer to. Pointers that
|
|
2051 aren't known to point any such arrays result in LENRANGE[1] set
|
|
2052 to SIZE_MAX. */
|
|
2053 tree lenrange[2];
|
|
2054 bool flexarray = get_range_strlen (str, lenrange);
|
|
2055
|
|
2056 if (lenrange [0] || lenrange [1])
|
|
2057 {
|
|
2058 HOST_WIDE_INT min
|
|
2059 = (tree_fits_uhwi_p (lenrange[0])
|
|
2060 ? tree_to_uhwi (lenrange[0])
|
|
2061 : 0);
|
|
2062
|
|
2063 HOST_WIDE_INT max
|
|
2064 = (tree_fits_uhwi_p (lenrange[1])
|
|
2065 ? tree_to_uhwi (lenrange[1])
|
|
2066 : HOST_WIDE_INT_M1U);
|
|
2067
|
|
2068 /* get_range_strlen() returns the target value of SIZE_MAX for
|
|
2069 strings of unknown length. Bump it up to HOST_WIDE_INT_M1U
|
|
2070 which may be bigger. */
|
|
2071 if ((unsigned HOST_WIDE_INT)min == target_size_max ())
|
|
2072 min = HOST_WIDE_INT_M1U;
|
|
2073 if ((unsigned HOST_WIDE_INT)max == target_size_max ())
|
|
2074 max = HOST_WIDE_INT_M1U;
|
|
2075
|
|
2076 fmtresult res (min, max);
|
|
2077
|
|
2078 /* Set RES.KNOWNRANGE to true if and only if all strings referenced
|
|
2079 by STR are known to be bounded (though not necessarily by their
|
|
2080 actual length but perhaps by their maximum possible length). */
|
|
2081 if (res.range.max < target_int_max ())
|
|
2082 {
|
|
2083 res.knownrange = true;
|
|
2084 /* When the the length of the longest string is known and not
|
|
2085 excessive use it as the likely length of the string(s). */
|
|
2086 res.range.likely = res.range.max;
|
|
2087 }
|
|
2088 else
|
|
2089 {
|
|
2090 /* When the upper bound is unknown (it can be zero or excessive)
|
|
2091 set the likely length to the greater of 1 and the length of
|
|
2092 the shortest string and reset the lower bound to zero. */
|
|
2093 res.range.likely = res.range.min ? res.range.min : warn_level > 1;
|
|
2094 res.range.min = 0;
|
|
2095 }
|
|
2096
|
|
2097 /* If the range of string length has been estimated from the size
|
|
2098 of an array at the end of a struct assume that it's longer than
|
|
2099 the array bound says it is in case it's used as a poor man's
|
|
2100 flexible array member, such as in struct S { char a[4]; }; */
|
|
2101 res.range.unlikely = flexarray ? HOST_WIDE_INT_MAX : res.range.max;
|
|
2102
|
|
2103 return res;
|
|
2104 }
|
|
2105
|
|
2106 return get_string_length (NULL_TREE);
|
|
2107 }
|
|
2108
|
|
2109 /* Return the minimum and maximum number of characters formatted
|
|
2110 by the '%c' format directives and its wide character form for
|
|
2111 the argument ARG. ARG can be null (for functions such as
|
|
2112 vsprinf). */
|
|
2113
|
|
2114 static fmtresult
|
|
2115 format_character (const directive &dir, tree arg)
|
|
2116 {
|
|
2117 fmtresult res;
|
|
2118
|
|
2119 res.knownrange = true;
|
|
2120
|
|
2121 if (dir.modifier == FMT_LEN_l)
|
|
2122 {
|
|
2123 /* A wide character can result in as few as zero bytes. */
|
|
2124 res.range.min = 0;
|
|
2125
|
|
2126 HOST_WIDE_INT min, max;
|
|
2127 if (get_int_range (arg, &min, &max, false, 0))
|
|
2128 {
|
|
2129 if (min == 0 && max == 0)
|
|
2130 {
|
|
2131 /* The NUL wide character results in no bytes. */
|
|
2132 res.range.max = 0;
|
|
2133 res.range.likely = 0;
|
|
2134 res.range.unlikely = 0;
|
|
2135 }
|
|
2136 else if (min > 0 && min < 128)
|
|
2137 {
|
|
2138 /* A wide character in the ASCII range most likely results
|
|
2139 in a single byte, and only unlikely in up to MB_LEN_MAX. */
|
|
2140 res.range.max = 1;
|
|
2141 res.range.likely = 1;
|
|
2142 res.range.unlikely = target_mb_len_max ();
|
|
2143 }
|
|
2144 else
|
|
2145 {
|
|
2146 /* A wide character outside the ASCII range likely results
|
|
2147 in up to two bytes, and only unlikely in up to MB_LEN_MAX. */
|
|
2148 res.range.max = target_mb_len_max ();
|
|
2149 res.range.likely = 2;
|
|
2150 res.range.unlikely = res.range.max;
|
|
2151 }
|
|
2152 }
|
|
2153 else
|
|
2154 {
|
|
2155 /* An unknown wide character is treated the same as a wide
|
|
2156 character outside the ASCII range. */
|
|
2157 res.range.max = target_mb_len_max ();
|
|
2158 res.range.likely = 2;
|
|
2159 res.range.unlikely = res.range.max;
|
|
2160 }
|
|
2161 }
|
|
2162 else
|
|
2163 {
|
|
2164 /* A plain '%c' directive. Its ouput is exactly 1. */
|
|
2165 res.range.min = res.range.max = 1;
|
|
2166 res.range.likely = res.range.unlikely = 1;
|
|
2167 res.knownrange = true;
|
|
2168 }
|
|
2169
|
|
2170 /* Bump up the byte counters if WIDTH is greater. */
|
|
2171 return res.adjust_for_width_or_precision (dir.width);
|
|
2172 }
|
|
2173
|
|
2174 /* Return the minimum and maximum number of characters formatted
|
|
2175 by the '%s' format directive and its wide character form for
|
|
2176 the argument ARG. ARG can be null (for functions such as
|
|
2177 vsprinf). */
|
|
2178
|
|
2179 static fmtresult
|
|
2180 format_string (const directive &dir, tree arg)
|
|
2181 {
|
|
2182 fmtresult res;
|
|
2183
|
|
2184 /* Compute the range the argument's length can be in. */
|
|
2185 fmtresult slen = get_string_length (arg);
|
|
2186 if (slen.range.min == slen.range.max
|
|
2187 && slen.range.min < HOST_WIDE_INT_MAX)
|
|
2188 {
|
|
2189 /* The argument is either a string constant or it refers
|
|
2190 to one of a number of strings of the same length. */
|
|
2191
|
|
2192 /* A '%s' directive with a string argument with constant length. */
|
|
2193 res.range = slen.range;
|
|
2194
|
|
2195 if (dir.modifier == FMT_LEN_l)
|
|
2196 {
|
|
2197 /* In the worst case the length of output of a wide string S
|
|
2198 is bounded by MB_LEN_MAX * wcslen (S). */
|
|
2199 res.range.max *= target_mb_len_max ();
|
|
2200 res.range.unlikely = res.range.max;
|
|
2201 /* It's likely that the the total length is not more that
|
|
2202 2 * wcslen (S).*/
|
|
2203 res.range.likely = res.range.min * 2;
|
|
2204
|
|
2205 if (dir.prec[1] >= 0
|
|
2206 && (unsigned HOST_WIDE_INT)dir.prec[1] < res.range.max)
|
|
2207 {
|
|
2208 res.range.max = dir.prec[1];
|
|
2209 res.range.likely = dir.prec[1];
|
|
2210 res.range.unlikely = dir.prec[1];
|
|
2211 }
|
|
2212
|
|
2213 if (dir.prec[0] < 0 && dir.prec[1] > -1)
|
|
2214 res.range.min = 0;
|
|
2215 else if (dir.prec[0] >= 0)
|
|
2216 res.range.likely = dir.prec[0];
|
|
2217
|
|
2218 /* Even a non-empty wide character string need not convert into
|
|
2219 any bytes. */
|
|
2220 res.range.min = 0;
|
|
2221 }
|
|
2222 else
|
|
2223 {
|
|
2224 res.knownrange = true;
|
|
2225
|
|
2226 if (dir.prec[0] < 0 && dir.prec[1] > -1)
|
|
2227 res.range.min = 0;
|
|
2228 else if ((unsigned HOST_WIDE_INT)dir.prec[0] < res.range.min)
|
|
2229 res.range.min = dir.prec[0];
|
|
2230
|
|
2231 if ((unsigned HOST_WIDE_INT)dir.prec[1] < res.range.max)
|
|
2232 {
|
|
2233 res.range.max = dir.prec[1];
|
|
2234 res.range.likely = dir.prec[1];
|
|
2235 res.range.unlikely = dir.prec[1];
|
|
2236 }
|
|
2237 }
|
|
2238 }
|
|
2239 else if (arg && integer_zerop (arg))
|
|
2240 {
|
|
2241 /* Handle null pointer argument. */
|
|
2242
|
|
2243 fmtresult res (0);
|
|
2244 res.nullp = true;
|
|
2245 return res;
|
|
2246 }
|
|
2247 else
|
|
2248 {
|
|
2249 /* For a '%s' and '%ls' directive with a non-constant string (either
|
|
2250 one of a number of strings of known length or an unknown string)
|
|
2251 the minimum number of characters is lesser of PRECISION[0] and
|
|
2252 the length of the shortest known string or zero, and the maximum
|
|
2253 is the lessser of the length of the longest known string or
|
|
2254 PTRDIFF_MAX and PRECISION[1]. The likely length is either
|
|
2255 the minimum at level 1 and the greater of the minimum and 1
|
|
2256 at level 2. This result is adjust upward for width (if it's
|
|
2257 specified). */
|
|
2258
|
|
2259 if (dir.modifier == FMT_LEN_l)
|
|
2260 {
|
|
2261 /* A wide character converts to as few as zero bytes. */
|
|
2262 slen.range.min = 0;
|
|
2263 if (slen.range.max < target_int_max ())
|
|
2264 slen.range.max *= target_mb_len_max ();
|
|
2265
|
|
2266 if (slen.range.likely < target_int_max ())
|
|
2267 slen.range.likely *= 2;
|
|
2268
|
|
2269 if (slen.range.likely < target_int_max ())
|
|
2270 slen.range.unlikely *= target_mb_len_max ();
|
|
2271 }
|
|
2272
|
|
2273 res.range = slen.range;
|
|
2274
|
|
2275 if (dir.prec[0] >= 0)
|
|
2276 {
|
|
2277 /* Adjust the minimum to zero if the string length is unknown,
|
|
2278 or at most the lower bound of the precision otherwise. */
|
|
2279 if (slen.range.min >= target_int_max ())
|
|
2280 res.range.min = 0;
|
|
2281 else if ((unsigned HOST_WIDE_INT)dir.prec[0] < slen.range.min)
|
|
2282 res.range.min = dir.prec[0];
|
|
2283
|
|
2284 /* Make both maxima no greater than the upper bound of precision. */
|
|
2285 if ((unsigned HOST_WIDE_INT)dir.prec[1] < slen.range.max
|
|
2286 || slen.range.max >= target_int_max ())
|
|
2287 {
|
|
2288 res.range.max = dir.prec[1];
|
|
2289 res.range.unlikely = dir.prec[1];
|
|
2290 }
|
|
2291
|
|
2292 /* If precision is constant, set the likely counter to the lesser
|
|
2293 of it and the maximum string length. Otherwise, if the lower
|
|
2294 bound of precision is greater than zero, set the likely counter
|
|
2295 to the minimum. Otherwise set it to zero or one based on
|
|
2296 the warning level. */
|
|
2297 if (dir.prec[0] == dir.prec[1])
|
|
2298 res.range.likely
|
|
2299 = ((unsigned HOST_WIDE_INT)dir.prec[0] < slen.range.max
|
|
2300 ? dir.prec[0] : slen.range.max);
|
|
2301 else if (dir.prec[0] > 0)
|
|
2302 res.range.likely = res.range.min;
|
|
2303 else
|
|
2304 res.range.likely = warn_level > 1;
|
|
2305 }
|
|
2306 else if (dir.prec[1] >= 0)
|
|
2307 {
|
|
2308 res.range.min = 0;
|
|
2309 if ((unsigned HOST_WIDE_INT)dir.prec[1] < slen.range.max)
|
|
2310 res.range.max = dir.prec[1];
|
|
2311 res.range.likely = dir.prec[1] ? warn_level > 1 : 0;
|
|
2312 }
|
|
2313 else if (slen.range.min >= target_int_max ())
|
|
2314 {
|
|
2315 res.range.min = 0;
|
|
2316 res.range.max = HOST_WIDE_INT_MAX;
|
|
2317 /* At level 1 strings of unknown length are assumed to be
|
|
2318 empty, while at level 1 they are assumed to be one byte
|
|
2319 long. */
|
|
2320 res.range.likely = warn_level > 1;
|
|
2321 }
|
|
2322 else
|
|
2323 {
|
|
2324 /* A string of unknown length unconstrained by precision is
|
|
2325 assumed to be empty at level 1 and just one character long
|
|
2326 at higher levels. */
|
|
2327 if (res.range.likely >= target_int_max ())
|
|
2328 res.range.likely = warn_level > 1;
|
|
2329 }
|
|
2330
|
|
2331 res.range.unlikely = res.range.max;
|
|
2332 }
|
|
2333
|
|
2334 /* Bump up the byte counters if WIDTH is greater. */
|
|
2335 return res.adjust_for_width_or_precision (dir.width);
|
|
2336 }
|
|
2337
|
|
2338 /* Format plain string (part of the format string itself). */
|
|
2339
|
|
2340 static fmtresult
|
|
2341 format_plain (const directive &dir, tree)
|
|
2342 {
|
|
2343 fmtresult res (dir.len);
|
|
2344 return res;
|
|
2345 }
|
|
2346
|
|
2347 /* Return true if the RESULT of a directive in a call describe by INFO
|
|
2348 should be diagnosed given the AVAILable space in the destination. */
|
|
2349
|
|
2350 static bool
|
|
2351 should_warn_p (const pass_sprintf_length::call_info &info,
|
|
2352 const result_range &avail, const result_range &result)
|
|
2353 {
|
|
2354 if (result.max <= avail.min)
|
|
2355 {
|
|
2356 /* The least amount of space remaining in the destination is big
|
|
2357 enough for the longest output. */
|
|
2358 return false;
|
|
2359 }
|
|
2360
|
|
2361 if (info.bounded)
|
|
2362 {
|
|
2363 if (warn_format_trunc == 1 && result.min <= avail.max
|
|
2364 && info.retval_used ())
|
|
2365 {
|
|
2366 /* The likely amount of space remaining in the destination is big
|
|
2367 enough for the least output and the return value is used. */
|
|
2368 return false;
|
|
2369 }
|
|
2370
|
|
2371 if (warn_format_trunc == 1 && result.likely <= avail.likely
|
|
2372 && !info.retval_used ())
|
|
2373 {
|
|
2374 /* The likely amount of space remaining in the destination is big
|
|
2375 enough for the likely output and the return value is unused. */
|
|
2376 return false;
|
|
2377 }
|
|
2378
|
|
2379 if (warn_format_trunc == 2
|
|
2380 && result.likely <= avail.min
|
|
2381 && (result.max <= avail.min
|
|
2382 || result.max > HOST_WIDE_INT_MAX))
|
|
2383 {
|
|
2384 /* The minimum amount of space remaining in the destination is big
|
|
2385 enough for the longest output. */
|
|
2386 return false;
|
|
2387 }
|
|
2388 }
|
|
2389 else
|
|
2390 {
|
|
2391 if (warn_level == 1 && result.likely <= avail.likely)
|
|
2392 {
|
|
2393 /* The likely amount of space remaining in the destination is big
|
|
2394 enough for the likely output. */
|
|
2395 return false;
|
|
2396 }
|
|
2397
|
|
2398 if (warn_level == 2
|
|
2399 && result.likely <= avail.min
|
|
2400 && (result.max <= avail.min
|
|
2401 || result.max > HOST_WIDE_INT_MAX))
|
|
2402 {
|
|
2403 /* The minimum amount of space remaining in the destination is big
|
|
2404 enough for the longest output. */
|
|
2405 return false;
|
|
2406 }
|
|
2407 }
|
|
2408
|
|
2409 return true;
|
|
2410 }
|
|
2411
|
|
2412 /* At format string location describe by DIRLOC in a call described
|
|
2413 by INFO, issue a warning for a directive DIR whose output may be
|
|
2414 in excess of the available space AVAIL_RANGE in the destination
|
|
2415 given the formatting result FMTRES. This function does nothing
|
|
2416 except decide whether to issue a warning for a possible write
|
|
2417 past the end or truncation and, if so, format the warning.
|
|
2418 Return true if a warning has been issued. */
|
|
2419
|
|
2420 static bool
|
|
2421 maybe_warn (substring_loc &dirloc, location_t argloc,
|
|
2422 const pass_sprintf_length::call_info &info,
|
|
2423 const result_range &avail_range, const result_range &res,
|
|
2424 const directive &dir)
|
|
2425 {
|
|
2426 if (!should_warn_p (info, avail_range, res))
|
|
2427 return false;
|
|
2428
|
|
2429 /* A warning will definitely be issued below. */
|
|
2430
|
|
2431 /* The maximum byte count to reference in the warning. Larger counts
|
|
2432 imply that the upper bound is unknown (and could be anywhere between
|
|
2433 RES.MIN + 1 and SIZE_MAX / 2) are printed as "N or more bytes" rather
|
|
2434 than "between N and X" where X is some huge number. */
|
|
2435 unsigned HOST_WIDE_INT maxbytes = target_dir_max ();
|
|
2436
|
|
2437 /* True when there is enough room in the destination for the least
|
|
2438 amount of a directive's output but not enough for its likely or
|
|
2439 maximum output. */
|
|
2440 bool maybe = (res.min <= avail_range.max
|
|
2441 && (avail_range.min < res.likely
|
|
2442 || (res.max < HOST_WIDE_INT_MAX
|
|
2443 && avail_range.min < res.max)));
|
|
2444
|
|
2445 /* Buffer for the directive in the host character set (used when
|
|
2446 the source character set is different). */
|
|
2447 char hostdir[32];
|
|
2448
|
|
2449 if (avail_range.min == avail_range.max)
|
|
2450 {
|
|
2451 /* The size of the destination region is exact. */
|
|
2452 unsigned HOST_WIDE_INT navail = avail_range.max;
|
|
2453
|
|
2454 if (target_to_host (*dir.beg) != '%')
|
|
2455 {
|
|
2456 /* For plain character directives (i.e., the format string itself)
|
|
2457 but not others, point the caret at the first character that's
|
|
2458 past the end of the destination. */
|
|
2459 dirloc.set_caret_index (dirloc.get_caret_idx () + navail);
|
|
2460 }
|
|
2461
|
|
2462 if (*dir.beg == '\0')
|
|
2463 {
|
|
2464 /* This is the terminating nul. */
|
|
2465 gcc_assert (res.min == 1 && res.min == res.max);
|
|
2466
|
|
2467 const char *fmtstr
|
|
2468 = (info.bounded
|
|
2469 ? (maybe
|
|
2470 ? G_("%qE output may be truncated before the last format "
|
|
2471 "character")
|
|
2472 : G_("%qE output truncated before the last format character"))
|
|
2473 : (maybe
|
|
2474 ? G_("%qE may write a terminating nul past the end "
|
|
2475 "of the destination")
|
|
2476 : G_("%qE writing a terminating nul past the end "
|
|
2477 "of the destination")));
|
|
2478
|
|
2479 return fmtwarn (dirloc, UNKNOWN_LOCATION, NULL, info.warnopt (),
|
|
2480 fmtstr, info.func);
|
|
2481 }
|
|
2482
|
|
2483 if (res.min == res.max)
|
|
2484 {
|
|
2485 const char* fmtstr
|
|
2486 = (res.min == 1
|
|
2487 ? (info.bounded
|
|
2488 ? (maybe
|
|
2489 ? G_("%<%.*s%> directive output may be truncated writing "
|
|
2490 "%wu byte into a region of size %wu")
|
|
2491 : G_("%<%.*s%> directive output truncated writing "
|
|
2492 "%wu byte into a region of size %wu"))
|
|
2493 : G_("%<%.*s%> directive writing %wu byte "
|
|
2494 "into a region of size %wu"))
|
|
2495 : (info.bounded
|
|
2496 ? (maybe
|
|
2497 ? G_("%<%.*s%> directive output may be truncated writing "
|
|
2498 "%wu bytes into a region of size %wu")
|
|
2499 : G_("%<%.*s%> directive output truncated writing "
|
|
2500 "%wu bytes into a region of size %wu"))
|
|
2501 : G_("%<%.*s%> directive writing %wu bytes "
|
|
2502 "into a region of size %wu")));
|
|
2503 return fmtwarn (dirloc, argloc, NULL,
|
|
2504 info.warnopt (), fmtstr, dir.len,
|
|
2505 target_to_host (hostdir, sizeof hostdir, dir.beg),
|
|
2506 res.min, navail);
|
|
2507 }
|
|
2508
|
|
2509 if (res.min == 0 && res.max < maxbytes)
|
|
2510 {
|
|
2511 const char* fmtstr
|
|
2512 = (info.bounded
|
|
2513 ? (maybe
|
|
2514 ? G_("%<%.*s%> directive output may be truncated writing "
|
|
2515 "up to %wu bytes into a region of size %wu")
|
|
2516 : G_("%<%.*s%> directive output truncated writing "
|
|
2517 "up to %wu bytes into a region of size %wu"))
|
|
2518 : G_("%<%.*s%> directive writing up to %wu bytes "
|
|
2519 "into a region of size %wu"));
|
|
2520 return fmtwarn (dirloc, argloc, NULL,
|
|
2521 info.warnopt (), fmtstr, dir.len,
|
|
2522 target_to_host (hostdir, sizeof hostdir, dir.beg),
|
|
2523 res.max, navail);
|
|
2524 }
|
|
2525
|
|
2526 if (res.min == 0 && maxbytes <= res.max)
|
|
2527 {
|
|
2528 /* This is a special case to avoid issuing the potentially
|
|
2529 confusing warning:
|
|
2530 writing 0 or more bytes into a region of size 0. */
|
|
2531 const char* fmtstr
|
|
2532 = (info.bounded
|
|
2533 ? (maybe
|
|
2534 ? G_("%<%.*s%> directive output may be truncated writing "
|
|
2535 "likely %wu or more bytes into a region of size %wu")
|
|
2536 : G_("%<%.*s%> directive output truncated writing "
|
|
2537 "likely %wu or more bytes into a region of size %wu"))
|
|
2538 : G_("%<%.*s%> directive writing likely %wu or more bytes "
|
|
2539 "into a region of size %wu"));
|
|
2540 return fmtwarn (dirloc, argloc, NULL,
|
|
2541 info.warnopt (), fmtstr, dir.len,
|
|
2542 target_to_host (hostdir, sizeof hostdir, dir.beg),
|
|
2543 res.likely, navail);
|
|
2544 }
|
|
2545
|
|
2546 if (res.max < maxbytes)
|
|
2547 {
|
|
2548 const char* fmtstr
|
|
2549 = (info.bounded
|
|
2550 ? (maybe
|
|
2551 ? G_("%<%.*s%> directive output may be truncated writing "
|
|
2552 "between %wu and %wu bytes into a region of size %wu")
|
|
2553 : G_("%<%.*s%> directive output truncated writing "
|
|
2554 "between %wu and %wu bytes into a region of size %wu"))
|
|
2555 : G_("%<%.*s%> directive writing between %wu and "
|
|
2556 "%wu bytes into a region of size %wu"));
|
|
2557 return fmtwarn (dirloc, argloc, NULL,
|
|
2558 info.warnopt (), fmtstr, dir.len,
|
|
2559 target_to_host (hostdir, sizeof hostdir, dir.beg),
|
|
2560 res.min, res.max, navail);
|
|
2561 }
|
|
2562
|
|
2563 const char* fmtstr
|
|
2564 = (info.bounded
|
|
2565 ? (maybe
|
|
2566 ? G_("%<%.*s%> directive output may be truncated writing "
|
|
2567 "%wu or more bytes into a region of size %wu")
|
|
2568 : G_("%<%.*s%> directive output truncated writing "
|
|
2569 "%wu or more bytes into a region of size %wu"))
|
|
2570 : G_("%<%.*s%> directive writing %wu or more bytes "
|
|
2571 "into a region of size %wu"));
|
|
2572 return fmtwarn (dirloc, argloc, NULL,
|
|
2573 info.warnopt (), fmtstr, dir.len,
|
|
2574 target_to_host (hostdir, sizeof hostdir, dir.beg),
|
|
2575 res.min, navail);
|
|
2576 }
|
|
2577
|
|
2578 /* The size of the destination region is a range. */
|
|
2579
|
|
2580 if (target_to_host (*dir.beg) != '%')
|
|
2581 {
|
|
2582 unsigned HOST_WIDE_INT navail = avail_range.max;
|
|
2583
|
|
2584 /* For plain character directives (i.e., the format string itself)
|
|
2585 but not others, point the caret at the first character that's
|
|
2586 past the end of the destination. */
|
|
2587 dirloc.set_caret_index (dirloc.get_caret_idx () + navail);
|
|
2588 }
|
|
2589
|
|
2590 if (*dir.beg == '\0')
|
|
2591 {
|
|
2592 gcc_assert (res.min == 1 && res.min == res.max);
|
|
2593
|
|
2594 const char *fmtstr
|
|
2595 = (info.bounded
|
|
2596 ? (maybe
|
|
2597 ? G_("%qE output may be truncated before the last format "
|
|
2598 "character")
|
|
2599 : G_("%qE output truncated before the last format character"))
|
|
2600 : (maybe
|
|
2601 ? G_("%qE may write a terminating nul past the end "
|
|
2602 "of the destination")
|
|
2603 : G_("%qE writing a terminating nul past the end "
|
|
2604 "of the destination")));
|
|
2605
|
|
2606 return fmtwarn (dirloc, UNKNOWN_LOCATION, NULL, info.warnopt (), fmtstr,
|
|
2607 info.func);
|
|
2608 }
|
|
2609
|
|
2610 if (res.min == res.max)
|
|
2611 {
|
|
2612 const char* fmtstr
|
|
2613 = (res.min == 1
|
|
2614 ? (info.bounded
|
|
2615 ? (maybe
|
|
2616 ? G_("%<%.*s%> directive output may be truncated writing "
|
|
2617 "%wu byte into a region of size between %wu and %wu")
|
|
2618 : G_("%<%.*s%> directive output truncated writing "
|
|
2619 "%wu byte into a region of size between %wu and %wu"))
|
|
2620 : G_("%<%.*s%> directive writing %wu byte "
|
|
2621 "into a region of size between %wu and %wu"))
|
|
2622 : (info.bounded
|
|
2623 ? (maybe
|
|
2624 ? G_("%<%.*s%> directive output may be truncated writing "
|
|
2625 "%wu bytes into a region of size between %wu and %wu")
|
|
2626 : G_("%<%.*s%> directive output truncated writing "
|
|
2627 "%wu bytes into a region of size between %wu and %wu"))
|
|
2628 : G_("%<%.*s%> directive writing %wu bytes "
|
|
2629 "into a region of size between %wu and %wu")));
|
|
2630
|
|
2631 return fmtwarn (dirloc, argloc, NULL,
|
|
2632 info.warnopt (), fmtstr, dir.len,
|
|
2633 target_to_host (hostdir, sizeof hostdir, dir.beg),
|
|
2634 res.min, avail_range.min, avail_range.max);
|
|
2635 }
|
|
2636
|
|
2637 if (res.min == 0 && res.max < maxbytes)
|
|
2638 {
|
|
2639 const char* fmtstr
|
|
2640 = (info.bounded
|
|
2641 ? (maybe
|
|
2642 ? G_("%<%.*s%> directive output may be truncated writing "
|
|
2643 "up to %wu bytes into a region of size between "
|
|
2644 "%wu and %wu")
|
|
2645 : G_("%<%.*s%> directive output truncated writing "
|
|
2646 "up to %wu bytes into a region of size between "
|
|
2647 "%wu and %wu"))
|
|
2648 : G_("%<%.*s%> directive writing up to %wu bytes "
|
|
2649 "into a region of size between %wu and %wu"));
|
|
2650 return fmtwarn (dirloc, argloc, NULL,
|
|
2651 info.warnopt (), fmtstr, dir.len,
|
|
2652 target_to_host (hostdir, sizeof hostdir, dir.beg),
|
|
2653 res.max, avail_range.min, avail_range.max);
|
|
2654 }
|
|
2655
|
|
2656 if (res.min == 0 && maxbytes <= res.max)
|
|
2657 {
|
|
2658 /* This is a special case to avoid issuing the potentially confusing
|
|
2659 warning:
|
|
2660 writing 0 or more bytes into a region of size between 0 and N. */
|
|
2661 const char* fmtstr
|
|
2662 = (info.bounded
|
|
2663 ? (maybe
|
|
2664 ? G_("%<%.*s%> directive output may be truncated writing "
|
|
2665 "likely %wu or more bytes into a region of size between "
|
|
2666 "%wu and %wu")
|
|
2667 : G_("%<%.*s%> directive output truncated writing likely "
|
|
2668 "%wu or more bytes into a region of size between "
|
|
2669 "%wu and %wu"))
|
|
2670 : G_("%<%.*s%> directive writing likely %wu or more bytes "
|
|
2671 "into a region of size between %wu and %wu"));
|
|
2672 return fmtwarn (dirloc, argloc, NULL,
|
|
2673 info.warnopt (), fmtstr, dir.len,
|
|
2674 target_to_host (hostdir, sizeof hostdir, dir.beg),
|
|
2675 res.likely, avail_range.min, avail_range.max);
|
|
2676 }
|
|
2677
|
|
2678 if (res.max < maxbytes)
|
|
2679 {
|
|
2680 const char* fmtstr
|
|
2681 = (info.bounded
|
|
2682 ? (maybe
|
|
2683 ? G_("%<%.*s%> directive output may be truncated writing "
|
|
2684 "between %wu and %wu bytes into a region of size "
|
|
2685 "between %wu and %wu")
|
|
2686 : G_("%<%.*s%> directive output truncated writing "
|
|
2687 "between %wu and %wu bytes into a region of size "
|
|
2688 "between %wu and %wu"))
|
|
2689 : G_("%<%.*s%> directive writing between %wu and "
|
|
2690 "%wu bytes into a region of size between %wu and %wu"));
|
|
2691 return fmtwarn (dirloc, argloc, NULL,
|
|
2692 info.warnopt (), fmtstr, dir.len,
|
|
2693 target_to_host (hostdir, sizeof hostdir, dir.beg),
|
|
2694 res.min, res.max, avail_range.min, avail_range.max);
|
|
2695 }
|
|
2696
|
|
2697 const char* fmtstr
|
|
2698 = (info.bounded
|
|
2699 ? (maybe
|
|
2700 ? G_("%<%.*s%> directive output may be truncated writing "
|
|
2701 "%wu or more bytes into a region of size between "
|
|
2702 "%wu and %wu")
|
|
2703 : G_("%<%.*s%> directive output truncated writing "
|
|
2704 "%wu or more bytes into a region of size between "
|
|
2705 "%wu and %wu"))
|
|
2706 : G_("%<%.*s%> directive writing %wu or more bytes "
|
|
2707 "into a region of size between %wu and %wu"));
|
|
2708 return fmtwarn (dirloc, argloc, NULL,
|
|
2709 info.warnopt (), fmtstr, dir.len,
|
|
2710 target_to_host (hostdir, sizeof hostdir, dir.beg),
|
|
2711 res.min, avail_range.min, avail_range.max);
|
|
2712 }
|
|
2713
|
|
2714 /* Compute the length of the output resulting from the directive DIR
|
|
2715 in a call described by INFO and update the overall result of the call
|
|
2716 in *RES. Return true if the directive has been handled. */
|
|
2717
|
|
2718 static bool
|
|
2719 format_directive (const pass_sprintf_length::call_info &info,
|
|
2720 format_result *res, const directive &dir)
|
|
2721 {
|
|
2722 /* Offset of the beginning of the directive from the beginning
|
|
2723 of the format string. */
|
|
2724 size_t offset = dir.beg - info.fmtstr;
|
|
2725 size_t start = offset;
|
|
2726 size_t length = offset + dir.len - !!dir.len;
|
|
2727
|
|
2728 /* Create a location for the whole directive from the % to the format
|
|
2729 specifier. */
|
|
2730 substring_loc dirloc (info.fmtloc, TREE_TYPE (info.format),
|
|
2731 offset, start, length);
|
|
2732
|
|
2733 /* Also get the location of the argument if possible.
|
|
2734 This doesn't work for integer literals or function calls. */
|
|
2735 location_t argloc = UNKNOWN_LOCATION;
|
|
2736 if (dir.arg)
|
|
2737 argloc = EXPR_LOCATION (dir.arg);
|
|
2738
|
|
2739 /* Bail when there is no function to compute the output length,
|
|
2740 or when minimum length checking has been disabled. */
|
|
2741 if (!dir.fmtfunc || res->range.min >= HOST_WIDE_INT_MAX)
|
|
2742 return false;
|
|
2743
|
|
2744 /* Compute the range of lengths of the formatted output. */
|
|
2745 fmtresult fmtres = dir.fmtfunc (dir, dir.arg);
|
|
2746
|
|
2747 /* Record whether the output of all directives is known to be
|
|
2748 bounded by some maximum, implying that their arguments are
|
|
2749 either known exactly or determined to be in a known range
|
|
2750 or, for strings, limited by the upper bounds of the arrays
|
|
2751 they refer to. */
|
|
2752 res->knownrange &= fmtres.knownrange;
|
|
2753
|
|
2754 if (!fmtres.knownrange)
|
|
2755 {
|
|
2756 /* Only when the range is known, check it against the host value
|
|
2757 of INT_MAX + (the number of bytes of the "%.*Lf" directive with
|
|
2758 INT_MAX precision, which is the longest possible output of any
|
|
2759 single directive). That's the largest valid byte count (though
|
|
2760 not valid call to a printf-like function because it can never
|
|
2761 return such a count). Otherwise, the range doesn't correspond
|
|
2762 to known values of the argument. */
|
|
2763 if (fmtres.range.max > target_dir_max ())
|
|
2764 {
|
|
2765 /* Normalize the MAX counter to avoid having to deal with it
|
|
2766 later. The counter can be less than HOST_WIDE_INT_M1U
|
|
2767 when compiling for an ILP32 target on an LP64 host. */
|
|
2768 fmtres.range.max = HOST_WIDE_INT_M1U;
|
|
2769 /* Disable exact and maximum length checking after a failure
|
|
2770 to determine the maximum number of characters (for example
|
|
2771 for wide characters or wide character strings) but continue
|
|
2772 tracking the minimum number of characters. */
|
|
2773 res->range.max = HOST_WIDE_INT_M1U;
|
|
2774 }
|
|
2775
|
|
2776 if (fmtres.range.min > target_dir_max ())
|
|
2777 {
|
|
2778 /* Disable exact length checking after a failure to determine
|
|
2779 even the minimum number of characters (it shouldn't happen
|
|
2780 except in an error) but keep tracking the minimum and maximum
|
|
2781 number of characters. */
|
|
2782 return true;
|
|
2783 }
|
|
2784 }
|
|
2785
|
|
2786 /* Buffer for the directive in the host character set (used when
|
|
2787 the source character set is different). */
|
|
2788 char hostdir[32];
|
|
2789
|
|
2790 int dirlen = dir.len;
|
|
2791
|
|
2792 if (fmtres.nullp)
|
|
2793 {
|
|
2794 fmtwarn (dirloc, argloc, NULL, info.warnopt (),
|
|
2795 "%<%.*s%> directive argument is null",
|
|
2796 dirlen, target_to_host (hostdir, sizeof hostdir, dir.beg));
|
|
2797
|
|
2798 /* Don't bother processing the rest of the format string. */
|
|
2799 res->warned = true;
|
|
2800 res->range.min = HOST_WIDE_INT_M1U;
|
|
2801 res->range.max = HOST_WIDE_INT_M1U;
|
|
2802 return false;
|
|
2803 }
|
|
2804
|
|
2805 /* Compute the number of available bytes in the destination. There
|
|
2806 must always be at least one byte of space for the terminating
|
|
2807 NUL that's appended after the format string has been processed. */
|
|
2808 result_range avail_range = bytes_remaining (info.objsize, *res);
|
|
2809
|
|
2810 bool warned = res->warned;
|
|
2811
|
|
2812 if (!warned)
|
|
2813 warned = maybe_warn (dirloc, argloc, info, avail_range,
|
|
2814 fmtres.range, dir);
|
|
2815
|
|
2816 /* Bump up the total maximum if it isn't too big. */
|
|
2817 if (res->range.max < HOST_WIDE_INT_MAX
|
|
2818 && fmtres.range.max < HOST_WIDE_INT_MAX)
|
|
2819 res->range.max += fmtres.range.max;
|
|
2820
|
|
2821 /* Raise the total unlikely maximum by the larger of the maximum
|
|
2822 and the unlikely maximum. */
|
|
2823 unsigned HOST_WIDE_INT save = res->range.unlikely;
|
|
2824 if (fmtres.range.max < fmtres.range.unlikely)
|
|
2825 res->range.unlikely += fmtres.range.unlikely;
|
|
2826 else
|
|
2827 res->range.unlikely += fmtres.range.max;
|
|
2828
|
|
2829 if (res->range.unlikely < save)
|
|
2830 res->range.unlikely = HOST_WIDE_INT_M1U;
|
|
2831
|
|
2832 res->range.min += fmtres.range.min;
|
|
2833 res->range.likely += fmtres.range.likely;
|
|
2834
|
|
2835 /* Has the minimum directive output length exceeded the maximum
|
|
2836 of 4095 bytes required to be supported? */
|
|
2837 bool minunder4k = fmtres.range.min < 4096;
|
|
2838 bool maxunder4k = fmtres.range.max < 4096;
|
|
2839 /* Clear UNDER4K in the overall result if the maximum has exceeded
|
|
2840 the 4k (this is necessary to avoid the return valuye optimization
|
|
2841 that may not be safe in the maximum case). */
|
|
2842 if (!maxunder4k)
|
|
2843 res->under4k = false;
|
|
2844
|
|
2845 if (!warned
|
|
2846 /* Only warn at level 2. */
|
|
2847 && 1 < warn_level
|
|
2848 && (!minunder4k
|
|
2849 || (!maxunder4k && fmtres.range.max < HOST_WIDE_INT_MAX)))
|
|
2850 {
|
|
2851 /* The directive output may be longer than the maximum required
|
|
2852 to be handled by an implementation according to 7.21.6.1, p15
|
|
2853 of C11. Warn on this only at level 2 but remember this and
|
|
2854 prevent folding the return value when done. This allows for
|
|
2855 the possibility of the actual libc call failing due to ENOMEM
|
|
2856 (like Glibc does under some conditions). */
|
|
2857
|
|
2858 if (fmtres.range.min == fmtres.range.max)
|
|
2859 warned = fmtwarn (dirloc, argloc, NULL,
|
|
2860 info.warnopt (),
|
|
2861 "%<%.*s%> directive output of %wu bytes exceeds "
|
|
2862 "minimum required size of 4095",
|
|
2863 dirlen,
|
|
2864 target_to_host (hostdir, sizeof hostdir, dir.beg),
|
|
2865 fmtres.range.min);
|
|
2866 else
|
|
2867 {
|
|
2868 const char *fmtstr
|
|
2869 = (minunder4k
|
|
2870 ? G_("%<%.*s%> directive output between %wu and %wu "
|
|
2871 "bytes may exceed minimum required size of 4095")
|
|
2872 : G_("%<%.*s%> directive output between %wu and %wu "
|
|
2873 "bytes exceeds minimum required size of 4095"));
|
|
2874
|
|
2875 warned = fmtwarn (dirloc, argloc, NULL,
|
|
2876 info.warnopt (), fmtstr, dirlen,
|
|
2877 target_to_host (hostdir, sizeof hostdir, dir.beg),
|
|
2878 fmtres.range.min, fmtres.range.max);
|
|
2879 }
|
|
2880 }
|
|
2881
|
|
2882 /* Has the likely and maximum directive output exceeded INT_MAX? */
|
|
2883 bool likelyximax = *dir.beg && res->range.likely > target_int_max ();
|
|
2884 /* Don't consider the maximum to be in excess when it's the result
|
|
2885 of a string of unknown length (i.e., whose maximum has been set
|
|
2886 to be greater than or equal to HOST_WIDE_INT_MAX. */
|
|
2887 bool maxximax = (*dir.beg
|
|
2888 && res->range.max > target_int_max ()
|
|
2889 && res->range.max < HOST_WIDE_INT_MAX);
|
|
2890
|
|
2891 if (!warned
|
|
2892 /* Warn for the likely output size at level 1. */
|
|
2893 && (likelyximax
|
|
2894 /* But only warn for the maximum at level 2. */
|
|
2895 || (1 < warn_level
|
|
2896 && maxximax
|
|
2897 && fmtres.range.max < HOST_WIDE_INT_MAX)))
|
|
2898 {
|
|
2899 /* The directive output causes the total length of output
|
|
2900 to exceed INT_MAX bytes. */
|
|
2901
|
|
2902 if (fmtres.range.min == fmtres.range.max)
|
|
2903 warned = fmtwarn (dirloc, argloc, NULL, info.warnopt (),
|
|
2904 "%<%.*s%> directive output of %wu bytes causes "
|
|
2905 "result to exceed %<INT_MAX%>",
|
|
2906 dirlen,
|
|
2907 target_to_host (hostdir, sizeof hostdir, dir.beg),
|
|
2908 fmtres.range.min);
|
|
2909 else
|
|
2910 {
|
|
2911 const char *fmtstr
|
|
2912 = (fmtres.range.min > target_int_max ()
|
|
2913 ? G_ ("%<%.*s%> directive output between %wu and %wu "
|
|
2914 "bytes causes result to exceed %<INT_MAX%>")
|
|
2915 : G_ ("%<%.*s%> directive output between %wu and %wu "
|
|
2916 "bytes may cause result to exceed %<INT_MAX%>"));
|
|
2917 warned = fmtwarn (dirloc, argloc, NULL,
|
|
2918 info.warnopt (), fmtstr, dirlen,
|
|
2919 target_to_host (hostdir, sizeof hostdir, dir.beg),
|
|
2920 fmtres.range.min, fmtres.range.max);
|
|
2921 }
|
|
2922 }
|
|
2923
|
|
2924 if (warned && fmtres.range.min < fmtres.range.likely
|
|
2925 && fmtres.range.likely < fmtres.range.max)
|
|
2926 {
|
|
2927 inform (info.fmtloc,
|
|
2928 (1 == fmtres.range.likely
|
|
2929 ? G_("assuming directive output of %wu byte")
|
|
2930 : G_("assuming directive output of %wu bytes")),
|
|
2931 fmtres.range.likely);
|
|
2932 }
|
|
2933
|
|
2934 if (warned && fmtres.argmin)
|
|
2935 {
|
|
2936 if (fmtres.argmin == fmtres.argmax)
|
|
2937 inform (info.fmtloc, "directive argument %qE", fmtres.argmin);
|
|
2938 else if (fmtres.knownrange)
|
|
2939 inform (info.fmtloc, "directive argument in the range [%E, %E]",
|
|
2940 fmtres.argmin, fmtres.argmax);
|
|
2941 else
|
|
2942 inform (info.fmtloc,
|
|
2943 "using the range [%E, %E] for directive argument",
|
|
2944 fmtres.argmin, fmtres.argmax);
|
|
2945 }
|
|
2946
|
|
2947 res->warned |= warned;
|
|
2948
|
|
2949 if (!dir.beg[0] && res->warned && info.objsize < HOST_WIDE_INT_MAX)
|
|
2950 {
|
|
2951 /* If a warning has been issued for buffer overflow or truncation
|
|
2952 (but not otherwise) help the user figure out how big a buffer
|
|
2953 they need. */
|
|
2954
|
|
2955 location_t callloc = gimple_location (info.callstmt);
|
|
2956
|
|
2957 unsigned HOST_WIDE_INT min = res->range.min;
|
|
2958 unsigned HOST_WIDE_INT max = res->range.max;
|
|
2959
|
|
2960 if (min == max)
|
|
2961 inform (callloc,
|
|
2962 (min == 1
|
|
2963 ? G_("%qE output %wu byte into a destination of size %wu")
|
|
2964 : G_("%qE output %wu bytes into a destination of size %wu")),
|
|
2965 info.func, min, info.objsize);
|
|
2966 else if (max < HOST_WIDE_INT_MAX)
|
|
2967 inform (callloc,
|
|
2968 "%qE output between %wu and %wu bytes into "
|
|
2969 "a destination of size %wu",
|
|
2970 info.func, min, max, info.objsize);
|
|
2971 else if (min < res->range.likely && res->range.likely < max)
|
|
2972 inform (callloc,
|
|
2973 "%qE output %wu or more bytes (assuming %wu) into "
|
|
2974 "a destination of size %wu",
|
|
2975 info.func, min, res->range.likely, info.objsize);
|
|
2976 else
|
|
2977 inform (callloc,
|
|
2978 "%qE output %wu or more bytes into a destination of size %wu",
|
|
2979 info.func, min, info.objsize);
|
|
2980 }
|
|
2981
|
|
2982 if (dump_file && *dir.beg)
|
|
2983 {
|
|
2984 fprintf (dump_file, " Result: %lli, %lli, %lli, %lli "
|
|
2985 "(%lli, %lli, %lli, %lli)\n",
|
|
2986 (long long)fmtres.range.min,
|
|
2987 (long long)fmtres.range.likely,
|
|
2988 (long long)fmtres.range.max,
|
|
2989 (long long)fmtres.range.unlikely,
|
|
2990 (long long)res->range.min,
|
|
2991 (long long)res->range.likely,
|
|
2992 (long long)res->range.max,
|
|
2993 (long long)res->range.unlikely);
|
|
2994 }
|
|
2995
|
|
2996 return true;
|
|
2997 }
|
|
2998
|
|
2999 #pragma GCC diagnostic pop
|
|
3000
|
|
3001 /* Parse a format directive in function call described by INFO starting
|
|
3002 at STR and populate DIR structure. Bump up *ARGNO by the number of
|
|
3003 arguments extracted for the directive. Return the length of
|
|
3004 the directive. */
|
|
3005
|
|
3006 static size_t
|
|
3007 parse_directive (pass_sprintf_length::call_info &info,
|
|
3008 directive &dir, format_result *res,
|
|
3009 const char *str, unsigned *argno)
|
|
3010 {
|
|
3011 const char *pcnt = strchr (str, target_percent);
|
|
3012 dir.beg = str;
|
|
3013
|
|
3014 if (size_t len = pcnt ? pcnt - str : *str ? strlen (str) : 1)
|
|
3015 {
|
|
3016 /* This directive is either a plain string or the terminating nul
|
|
3017 (which isn't really a directive but it simplifies things to
|
|
3018 handle it as if it were). */
|
|
3019 dir.len = len;
|
|
3020 dir.fmtfunc = format_plain;
|
|
3021
|
|
3022 if (dump_file)
|
|
3023 {
|
|
3024 fprintf (dump_file, " Directive %u at offset %llu: \"%.*s\", "
|
|
3025 "length = %llu\n",
|
|
3026 dir.dirno,
|
|
3027 (unsigned long long)(size_t)(dir.beg - info.fmtstr),
|
|
3028 (int)dir.len, dir.beg, (unsigned long long)dir.len);
|
|
3029 }
|
|
3030
|
|
3031 return len - !*str;
|
|
3032 }
|
|
3033
|
|
3034 const char *pf = pcnt + 1;
|
|
3035
|
|
3036 /* POSIX numbered argument index or zero when none. */
|
|
3037 HOST_WIDE_INT dollar = 0;
|
|
3038
|
|
3039 /* With and precision. -1 when not specified, HOST_WIDE_INT_MIN
|
|
3040 when given by a va_list argument, and a non-negative value
|
|
3041 when specified in the format string itself. */
|
|
3042 HOST_WIDE_INT width = -1;
|
|
3043 HOST_WIDE_INT precision = -1;
|
|
3044
|
|
3045 /* Pointers to the beginning of the width and precision decimal
|
|
3046 string (if any) within the directive. */
|
|
3047 const char *pwidth = 0;
|
|
3048 const char *pprec = 0;
|
|
3049
|
|
3050 /* When the value of the decimal string that specifies width or
|
|
3051 precision is out of range, points to the digit that causes
|
|
3052 the value to exceed the limit. */
|
|
3053 const char *werange = NULL;
|
|
3054 const char *perange = NULL;
|
|
3055
|
|
3056 /* Width specified via the asterisk. Need not be INTEGER_CST.
|
|
3057 For vararg functions set to void_node. */
|
|
3058 tree star_width = NULL_TREE;
|
|
3059
|
|
3060 /* Width specified via the asterisk. Need not be INTEGER_CST.
|
|
3061 For vararg functions set to void_node. */
|
|
3062 tree star_precision = NULL_TREE;
|
|
3063
|
|
3064 if (ISDIGIT (target_to_host (*pf)))
|
|
3065 {
|
|
3066 /* This could be either a POSIX positional argument, the '0'
|
|
3067 flag, or a width, depending on what follows. Store it as
|
|
3068 width and sort it out later after the next character has
|
|
3069 been seen. */
|
|
3070 pwidth = pf;
|
|
3071 width = target_strtol10 (&pf, &werange);
|
|
3072 }
|
|
3073 else if (target_to_host (*pf) == '*')
|
|
3074 {
|
|
3075 /* Similarly to the block above, this could be either a POSIX
|
|
3076 positional argument or a width, depending on what follows. */
|
|
3077 if (*argno < gimple_call_num_args (info.callstmt))
|
|
3078 star_width = gimple_call_arg (info.callstmt, (*argno)++);
|
|
3079 else
|
|
3080 star_width = void_node;
|
|
3081 ++pf;
|
|
3082 }
|
|
3083
|
|
3084 if (target_to_host (*pf) == '$')
|
|
3085 {
|
|
3086 /* Handle the POSIX dollar sign which references the 1-based
|
|
3087 positional argument number. */
|
|
3088 if (width != -1)
|
|
3089 dollar = width + info.argidx;
|
|
3090 else if (star_width
|
|
3091 && TREE_CODE (star_width) == INTEGER_CST
|
|
3092 && (TYPE_PRECISION (TREE_TYPE (star_width))
|
|
3093 <= TYPE_PRECISION (integer_type_node)))
|
|
3094 dollar = width + tree_to_shwi (star_width);
|
|
3095
|
|
3096 /* Bail when the numbered argument is out of range (it will
|
|
3097 have already been diagnosed by -Wformat). */
|
|
3098 if (dollar == 0
|
|
3099 || dollar == (int)info.argidx
|
|
3100 || dollar > gimple_call_num_args (info.callstmt))
|
|
3101 return false;
|
|
3102
|
|
3103 --dollar;
|
|
3104
|
|
3105 star_width = NULL_TREE;
|
|
3106 width = -1;
|
|
3107 ++pf;
|
|
3108 }
|
|
3109
|
|
3110 if (dollar || !star_width)
|
|
3111 {
|
|
3112 if (width != -1)
|
|
3113 {
|
|
3114 if (width == 0)
|
|
3115 {
|
|
3116 /* The '0' that has been interpreted as a width above is
|
|
3117 actually a flag. Reset HAVE_WIDTH, set the '0' flag,
|
|
3118 and continue processing other flags. */
|
|
3119 width = -1;
|
|
3120 dir.set_flag ('0');
|
|
3121 }
|
|
3122 else if (!dollar)
|
|
3123 {
|
|
3124 /* (Non-zero) width has been seen. The next character
|
|
3125 is either a period or a digit. */
|
|
3126 goto start_precision;
|
|
3127 }
|
|
3128 }
|
|
3129 /* When either '$' has been seen, or width has not been seen,
|
|
3130 the next field is the optional flags followed by an optional
|
|
3131 width. */
|
|
3132 for ( ; ; ) {
|
|
3133 switch (target_to_host (*pf))
|
|
3134 {
|
|
3135 case ' ':
|
|
3136 case '0':
|
|
3137 case '+':
|
|
3138 case '-':
|
|
3139 case '#':
|
|
3140 dir.set_flag (target_to_host (*pf++));
|
|
3141 break;
|
|
3142
|
|
3143 default:
|
|
3144 goto start_width;
|
|
3145 }
|
|
3146 }
|
|
3147
|
|
3148 start_width:
|
|
3149 if (ISDIGIT (target_to_host (*pf)))
|
|
3150 {
|
|
3151 werange = 0;
|
|
3152 pwidth = pf;
|
|
3153 width = target_strtol10 (&pf, &werange);
|
|
3154 }
|
|
3155 else if (target_to_host (*pf) == '*')
|
|
3156 {
|
|
3157 if (*argno < gimple_call_num_args (info.callstmt))
|
|
3158 star_width = gimple_call_arg (info.callstmt, (*argno)++);
|
|
3159 else
|
|
3160 {
|
|
3161 /* This is (likely) a va_list. It could also be an invalid
|
|
3162 call with insufficient arguments. */
|
|
3163 star_width = void_node;
|
|
3164 }
|
|
3165 ++pf;
|
|
3166 }
|
|
3167 else if (target_to_host (*pf) == '\'')
|
|
3168 {
|
|
3169 /* The POSIX apostrophe indicating a numeric grouping
|
|
3170 in the current locale. Even though it's possible to
|
|
3171 estimate the upper bound on the size of the output
|
|
3172 based on the number of digits it probably isn't worth
|
|
3173 continuing. */
|
|
3174 return 0;
|
|
3175 }
|
|
3176 }
|
|
3177
|
|
3178 start_precision:
|
|
3179 if (target_to_host (*pf) == '.')
|
|
3180 {
|
|
3181 ++pf;
|
|
3182
|
|
3183 if (ISDIGIT (target_to_host (*pf)))
|
|
3184 {
|
|
3185 pprec = pf;
|
|
3186 precision = target_strtol10 (&pf, &perange);
|
|
3187 }
|
|
3188 else if (target_to_host (*pf) == '*')
|
|
3189 {
|
|
3190 if (*argno < gimple_call_num_args (info.callstmt))
|
|
3191 star_precision = gimple_call_arg (info.callstmt, (*argno)++);
|
|
3192 else
|
|
3193 {
|
|
3194 /* This is (likely) a va_list. It could also be an invalid
|
|
3195 call with insufficient arguments. */
|
|
3196 star_precision = void_node;
|
|
3197 }
|
|
3198 ++pf;
|
|
3199 }
|
|
3200 else
|
|
3201 {
|
|
3202 /* The decimal precision or the asterisk are optional.
|
|
3203 When neither is dirified it's taken to be zero. */
|
|
3204 precision = 0;
|
|
3205 }
|
|
3206 }
|
|
3207
|
|
3208 switch (target_to_host (*pf))
|
|
3209 {
|
|
3210 case 'h':
|
|
3211 if (target_to_host (pf[1]) == 'h')
|
|
3212 {
|
|
3213 ++pf;
|
|
3214 dir.modifier = FMT_LEN_hh;
|
|
3215 }
|
|
3216 else
|
|
3217 dir.modifier = FMT_LEN_h;
|
|
3218 ++pf;
|
|
3219 break;
|
|
3220
|
|
3221 case 'j':
|
|
3222 dir.modifier = FMT_LEN_j;
|
|
3223 ++pf;
|
|
3224 break;
|
|
3225
|
|
3226 case 'L':
|
|
3227 dir.modifier = FMT_LEN_L;
|
|
3228 ++pf;
|
|
3229 break;
|
|
3230
|
|
3231 case 'l':
|
|
3232 if (target_to_host (pf[1]) == 'l')
|
|
3233 {
|
|
3234 ++pf;
|
|
3235 dir.modifier = FMT_LEN_ll;
|
|
3236 }
|
|
3237 else
|
|
3238 dir.modifier = FMT_LEN_l;
|
|
3239 ++pf;
|
|
3240 break;
|
|
3241
|
|
3242 case 't':
|
|
3243 dir.modifier = FMT_LEN_t;
|
|
3244 ++pf;
|
|
3245 break;
|
|
3246
|
|
3247 case 'z':
|
|
3248 dir.modifier = FMT_LEN_z;
|
|
3249 ++pf;
|
|
3250 break;
|
|
3251 }
|
|
3252
|
|
3253 switch (target_to_host (*pf))
|
|
3254 {
|
|
3255 /* Handle a sole '%' character the same as "%%" but since it's
|
|
3256 undefined prevent the result from being folded. */
|
|
3257 case '\0':
|
|
3258 --pf;
|
|
3259 res->range.min = res->range.max = HOST_WIDE_INT_M1U;
|
|
3260 /* FALLTHRU */
|
|
3261 case '%':
|
|
3262 dir.fmtfunc = format_percent;
|
|
3263 break;
|
|
3264
|
|
3265 case 'a':
|
|
3266 case 'A':
|
|
3267 case 'e':
|
|
3268 case 'E':
|
|
3269 case 'f':
|
|
3270 case 'F':
|
|
3271 case 'g':
|
|
3272 case 'G':
|
|
3273 res->floating = true;
|
|
3274 dir.fmtfunc = format_floating;
|
|
3275 break;
|
|
3276
|
|
3277 case 'd':
|
|
3278 case 'i':
|
|
3279 case 'o':
|
|
3280 case 'u':
|
|
3281 case 'x':
|
|
3282 case 'X':
|
|
3283 dir.fmtfunc = format_integer;
|
|
3284 break;
|
|
3285
|
|
3286 case 'p':
|
|
3287 /* The %p output is implementation-defined. It's possible
|
|
3288 to determine this format but due to extensions (edirially
|
|
3289 those of the Linux kernel -- see bug 78512) the first %p
|
|
3290 in the format string disables any further processing. */
|
|
3291 return false;
|
|
3292
|
|
3293 case 'n':
|
|
3294 /* %n has side-effects even when nothing is actually printed to
|
|
3295 any buffer. */
|
|
3296 info.nowrite = false;
|
|
3297 dir.fmtfunc = format_none;
|
|
3298 break;
|
|
3299
|
|
3300 case 'c':
|
|
3301 dir.fmtfunc = format_character;
|
|
3302 break;
|
|
3303
|
|
3304 case 'S':
|
|
3305 case 's':
|
|
3306 dir.fmtfunc = format_string;
|
|
3307 break;
|
|
3308
|
|
3309 default:
|
|
3310 /* Unknown conversion specification. */
|
|
3311 return 0;
|
|
3312 }
|
|
3313
|
|
3314 dir.specifier = target_to_host (*pf++);
|
|
3315
|
|
3316 /* Store the length of the format directive. */
|
|
3317 dir.len = pf - pcnt;
|
|
3318
|
|
3319 /* Buffer for the directive in the host character set (used when
|
|
3320 the source character set is different). */
|
|
3321 char hostdir[32];
|
|
3322
|
|
3323 if (star_width)
|
|
3324 {
|
|
3325 if (INTEGRAL_TYPE_P (TREE_TYPE (star_width)))
|
|
3326 dir.set_width (star_width);
|
|
3327 else
|
|
3328 {
|
|
3329 /* Width specified by a va_list takes on the range [0, -INT_MIN]
|
|
3330 (width is the absolute value of that specified). */
|
|
3331 dir.width[0] = 0;
|
|
3332 dir.width[1] = target_int_max () + 1;
|
|
3333 }
|
|
3334 }
|
|
3335 else
|
|
3336 {
|
|
3337 if (width == LONG_MAX && werange)
|
|
3338 {
|
|
3339 size_t begin = dir.beg - info.fmtstr + (pwidth - pcnt);
|
|
3340 size_t caret = begin + (werange - pcnt);
|
|
3341 size_t end = pf - info.fmtstr - 1;
|
|
3342
|
|
3343 /* Create a location for the width part of the directive,
|
|
3344 pointing the caret at the first out-of-range digit. */
|
|
3345 substring_loc dirloc (info.fmtloc, TREE_TYPE (info.format),
|
|
3346 caret, begin, end);
|
|
3347
|
|
3348 fmtwarn (dirloc, UNKNOWN_LOCATION, NULL,
|
|
3349 info.warnopt (), "%<%.*s%> directive width out of range",
|
|
3350 dir.len, target_to_host (hostdir, sizeof hostdir, dir.beg));
|
|
3351 }
|
|
3352
|
|
3353 dir.set_width (width);
|
|
3354 }
|
|
3355
|
|
3356 if (star_precision)
|
|
3357 {
|
|
3358 if (INTEGRAL_TYPE_P (TREE_TYPE (star_precision)))
|
|
3359 dir.set_precision (star_precision);
|
|
3360 else
|
|
3361 {
|
|
3362 /* Precision specified by a va_list takes on the range [-1, INT_MAX]
|
|
3363 (unlike width, negative precision is ignored). */
|
|
3364 dir.prec[0] = -1;
|
|
3365 dir.prec[1] = target_int_max ();
|
|
3366 }
|
|
3367 }
|
|
3368 else
|
|
3369 {
|
|
3370 if (precision == LONG_MAX && perange)
|
|
3371 {
|
|
3372 size_t begin = dir.beg - info.fmtstr + (pprec - pcnt) - 1;
|
|
3373 size_t caret = dir.beg - info.fmtstr + (perange - pcnt) - 1;
|
|
3374 size_t end = pf - info.fmtstr - 2;
|
|
3375
|
|
3376 /* Create a location for the precision part of the directive,
|
|
3377 including the leading period, pointing the caret at the first
|
|
3378 out-of-range digit . */
|
|
3379 substring_loc dirloc (info.fmtloc, TREE_TYPE (info.format),
|
|
3380 caret, begin, end);
|
|
3381
|
|
3382 fmtwarn (dirloc, UNKNOWN_LOCATION, NULL,
|
|
3383 info.warnopt (), "%<%.*s%> directive precision out of range",
|
|
3384 dir.len, target_to_host (hostdir, sizeof hostdir, dir.beg));
|
|
3385 }
|
|
3386
|
|
3387 dir.set_precision (precision);
|
|
3388 }
|
|
3389
|
|
3390 /* Extract the argument if the directive takes one and if it's
|
|
3391 available (e.g., the function doesn't take a va_list). Treat
|
|
3392 missing arguments the same as va_list, even though they will
|
|
3393 have likely already been diagnosed by -Wformat. */
|
|
3394 if (dir.specifier != '%'
|
|
3395 && *argno < gimple_call_num_args (info.callstmt))
|
|
3396 dir.arg = gimple_call_arg (info.callstmt, dollar ? dollar : (*argno)++);
|
|
3397
|
|
3398 if (dump_file)
|
|
3399 {
|
|
3400 fprintf (dump_file, " Directive %u at offset %llu: \"%.*s\"",
|
|
3401 dir.dirno, (unsigned long long)(size_t)(dir.beg - info.fmtstr),
|
|
3402 (int)dir.len, dir.beg);
|
|
3403 if (star_width)
|
|
3404 {
|
|
3405 if (dir.width[0] == dir.width[1])
|
|
3406 fprintf (dump_file, ", width = %lli", (long long)dir.width[0]);
|
|
3407 else
|
|
3408 fprintf (dump_file, ", width in range [%lli, %lli]",
|
|
3409 (long long)dir.width[0], (long long)dir.width[1]);
|
|
3410 }
|
|
3411
|
|
3412 if (star_precision)
|
|
3413 {
|
|
3414 if (dir.prec[0] == dir.prec[1])
|
|
3415 fprintf (dump_file, ", precision = %lli", (long long)dir.prec[0]);
|
|
3416 else
|
|
3417 fprintf (dump_file, ", precision in range [%lli, %lli]",
|
|
3418 (long long)dir.prec[0], (long long)dir.prec[1]);
|
|
3419 }
|
|
3420 fputc ('\n', dump_file);
|
|
3421 }
|
|
3422
|
|
3423 return dir.len;
|
|
3424 }
|
|
3425
|
|
3426 /* Compute the length of the output resulting from the call to a formatted
|
|
3427 output function described by INFO and store the result of the call in
|
|
3428 *RES. Issue warnings for detected past the end writes. Return true
|
|
3429 if the complete format string has been processed and *RES can be relied
|
|
3430 on, false otherwise (e.g., when a unknown or unhandled directive was seen
|
|
3431 that caused the processing to be terminated early). */
|
|
3432
|
|
3433 bool
|
|
3434 pass_sprintf_length::compute_format_length (call_info &info,
|
|
3435 format_result *res)
|
|
3436 {
|
|
3437 if (dump_file)
|
|
3438 {
|
|
3439 location_t callloc = gimple_location (info.callstmt);
|
|
3440 fprintf (dump_file, "%s:%i: ",
|
|
3441 LOCATION_FILE (callloc), LOCATION_LINE (callloc));
|
|
3442 print_generic_expr (dump_file, info.func, dump_flags);
|
|
3443
|
|
3444 fprintf (dump_file, ": objsize = %llu, fmtstr = \"%s\"\n",
|
|
3445 (unsigned long long)info.objsize, info.fmtstr);
|
|
3446 }
|
|
3447
|
|
3448 /* Reset the minimum and maximum byte counters. */
|
|
3449 res->range.min = res->range.max = 0;
|
|
3450
|
|
3451 /* No directive has been seen yet so the length of output is bounded
|
|
3452 by the known range [0, 0] (with no conversion producing more than
|
|
3453 4K bytes) until determined otherwise. */
|
|
3454 res->knownrange = true;
|
|
3455 res->under4k = true;
|
|
3456 res->floating = false;
|
|
3457 res->warned = false;
|
|
3458
|
|
3459 /* 1-based directive counter. */
|
|
3460 unsigned dirno = 1;
|
|
3461
|
|
3462 /* The variadic argument counter. */
|
|
3463 unsigned argno = info.argidx;
|
|
3464
|
|
3465 for (const char *pf = info.fmtstr; ; ++dirno)
|
|
3466 {
|
|
3467 directive dir = directive ();
|
|
3468 dir.dirno = dirno;
|
|
3469
|
|
3470 size_t n = parse_directive (info, dir, res, pf, &argno);
|
|
3471
|
|
3472 /* Return failure if the format function fails. */
|
|
3473 if (!format_directive (info, res, dir))
|
|
3474 return false;
|
|
3475
|
|
3476 /* Return success the directive is zero bytes long and it's
|
|
3477 the last think in the format string (i.e., it's the terminating
|
|
3478 nul, which isn't really a directive but handling it as one makes
|
|
3479 things simpler). */
|
|
3480 if (!n)
|
|
3481 return *pf == '\0';
|
|
3482
|
|
3483 pf += n;
|
|
3484 }
|
|
3485
|
|
3486 /* The complete format string was processed (with or without warnings). */
|
|
3487 return true;
|
|
3488 }
|
|
3489
|
|
3490 /* Return the size of the object referenced by the expression DEST if
|
|
3491 available, or -1 otherwise. */
|
|
3492
|
|
3493 static unsigned HOST_WIDE_INT
|
|
3494 get_destination_size (tree dest)
|
|
3495 {
|
|
3496 /* Initialize object size info before trying to compute it. */
|
|
3497 init_object_sizes ();
|
|
3498
|
|
3499 /* Use __builtin_object_size to determine the size of the destination
|
|
3500 object. When optimizing, determine the smallest object (such as
|
|
3501 a member array as opposed to the whole enclosing object), otherwise
|
|
3502 use type-zero object size to determine the size of the enclosing
|
|
3503 object (the function fails without optimization in this type). */
|
|
3504 int ost = optimize > 0;
|
|
3505 unsigned HOST_WIDE_INT size;
|
|
3506 if (compute_builtin_object_size (dest, ost, &size))
|
|
3507 return size;
|
|
3508
|
|
3509 return HOST_WIDE_INT_M1U;
|
|
3510 }
|
|
3511
|
|
3512 /* Return true if the call described by INFO with result RES safe to
|
|
3513 optimize (i.e., no undefined behavior), and set RETVAL to the range
|
|
3514 of its return values. */
|
|
3515
|
|
3516 static bool
|
|
3517 is_call_safe (const pass_sprintf_length::call_info &info,
|
|
3518 const format_result &res, bool under4k,
|
|
3519 unsigned HOST_WIDE_INT retval[2])
|
|
3520 {
|
|
3521 if (under4k && !res.under4k)
|
|
3522 return false;
|
|
3523
|
|
3524 /* The minimum return value. */
|
|
3525 retval[0] = res.range.min;
|
|
3526
|
|
3527 /* The maximum return value is in most cases bounded by RES.RANGE.MAX
|
|
3528 but in cases involving multibyte characters could be as large as
|
|
3529 RES.RANGE.UNLIKELY. */
|
|
3530 retval[1]
|
|
3531 = res.range.unlikely < res.range.max ? res.range.max : res.range.unlikely;
|
|
3532
|
|
3533 /* Adjust the number of bytes which includes the terminating nul
|
|
3534 to reflect the return value of the function which does not.
|
|
3535 Because the valid range of the function is [INT_MIN, INT_MAX],
|
|
3536 a valid range before the adjustment below is [0, INT_MAX + 1]
|
|
3537 (the functions only return negative values on error or undefined
|
|
3538 behavior). */
|
|
3539 if (retval[0] <= target_int_max () + 1)
|
|
3540 --retval[0];
|
|
3541 if (retval[1] <= target_int_max () + 1)
|
|
3542 --retval[1];
|
|
3543
|
|
3544 /* Avoid the return value optimization when the behavior of the call
|
|
3545 is undefined either because any directive may have produced 4K or
|
|
3546 more of output, or the return value exceeds INT_MAX, or because
|
|
3547 the output overflows the destination object (but leave it enabled
|
|
3548 when the function is bounded because then the behavior is well-
|
|
3549 defined). */
|
|
3550 if (retval[0] == retval[1]
|
|
3551 && (info.bounded || retval[0] < info.objsize)
|
|
3552 && retval[0] <= target_int_max ())
|
|
3553 return true;
|
|
3554
|
|
3555 if ((info.bounded || retval[1] < info.objsize)
|
|
3556 && (retval[0] < target_int_max ()
|
|
3557 && retval[1] < target_int_max ()))
|
|
3558 return true;
|
|
3559
|
|
3560 if (!under4k && (info.bounded || retval[0] < info.objsize))
|
|
3561 return true;
|
|
3562
|
|
3563 return false;
|
|
3564 }
|
|
3565
|
|
3566 /* Given a suitable result RES of a call to a formatted output function
|
|
3567 described by INFO, substitute the result for the return value of
|
|
3568 the call. The result is suitable if the number of bytes it represents
|
|
3569 is known and exact. A result that isn't suitable for substitution may
|
|
3570 have its range set to the range of return values, if that is known.
|
|
3571 Return true if the call is removed and gsi_next should not be performed
|
|
3572 in the caller. */
|
|
3573
|
|
3574 static bool
|
|
3575 try_substitute_return_value (gimple_stmt_iterator *gsi,
|
|
3576 const pass_sprintf_length::call_info &info,
|
|
3577 const format_result &res)
|
|
3578 {
|
|
3579 tree lhs = gimple_get_lhs (info.callstmt);
|
|
3580
|
|
3581 /* Set to true when the entire call has been removed. */
|
|
3582 bool removed = false;
|
|
3583
|
|
3584 /* The minimum and maximum return value. */
|
|
3585 unsigned HOST_WIDE_INT retval[2];
|
|
3586 bool safe = is_call_safe (info, res, true, retval);
|
|
3587
|
|
3588 if (safe
|
|
3589 && retval[0] == retval[1]
|
|
3590 /* Not prepared to handle possibly throwing calls here; they shouldn't
|
|
3591 appear in non-artificial testcases, except when the __*_chk routines
|
|
3592 are badly declared. */
|
|
3593 && !stmt_ends_bb_p (info.callstmt))
|
|
3594 {
|
|
3595 tree cst = build_int_cst (integer_type_node, retval[0]);
|
|
3596
|
|
3597 if (lhs == NULL_TREE
|
|
3598 && info.nowrite)
|
|
3599 {
|
|
3600 /* Remove the call to the bounded function with a zero size
|
|
3601 (e.g., snprintf(0, 0, "%i", 123)) if there is no lhs. */
|
|
3602 unlink_stmt_vdef (info.callstmt);
|
|
3603 gsi_remove (gsi, true);
|
|
3604 removed = true;
|
|
3605 }
|
|
3606 else if (info.nowrite)
|
|
3607 {
|
|
3608 /* Replace the call to the bounded function with a zero size
|
|
3609 (e.g., snprintf(0, 0, "%i", 123) with the constant result
|
|
3610 of the function. */
|
|
3611 if (!update_call_from_tree (gsi, cst))
|
|
3612 gimplify_and_update_call_from_tree (gsi, cst);
|
|
3613 gimple *callstmt = gsi_stmt (*gsi);
|
|
3614 update_stmt (callstmt);
|
|
3615 }
|
|
3616 else if (lhs)
|
|
3617 {
|
|
3618 /* Replace the left-hand side of the call with the constant
|
|
3619 result of the formatted function. */
|
|
3620 gimple_call_set_lhs (info.callstmt, NULL_TREE);
|
|
3621 gimple *g = gimple_build_assign (lhs, cst);
|
|
3622 gsi_insert_after (gsi, g, GSI_NEW_STMT);
|
|
3623 update_stmt (info.callstmt);
|
|
3624 }
|
|
3625
|
|
3626 if (dump_file)
|
|
3627 {
|
|
3628 if (removed)
|
|
3629 fprintf (dump_file, " Removing call statement.");
|
|
3630 else
|
|
3631 {
|
|
3632 fprintf (dump_file, " Substituting ");
|
|
3633 print_generic_expr (dump_file, cst, dump_flags);
|
|
3634 fprintf (dump_file, " for %s.\n",
|
|
3635 info.nowrite ? "statement" : "return value");
|
|
3636 }
|
|
3637 }
|
|
3638 }
|
|
3639 else if (lhs)
|
|
3640 {
|
|
3641 bool setrange = false;
|
|
3642
|
|
3643 if (safe
|
|
3644 && (info.bounded || retval[1] < info.objsize)
|
|
3645 && (retval[0] < target_int_max ()
|
|
3646 && retval[1] < target_int_max ()))
|
|
3647 {
|
|
3648 /* If the result is in a valid range bounded by the size of
|
|
3649 the destination set it so that it can be used for subsequent
|
|
3650 optimizations. */
|
|
3651 int prec = TYPE_PRECISION (integer_type_node);
|
|
3652
|
|
3653 wide_int min = wi::shwi (retval[0], prec);
|
|
3654 wide_int max = wi::shwi (retval[1], prec);
|
|
3655 set_range_info (lhs, VR_RANGE, min, max);
|
|
3656
|
|
3657 setrange = true;
|
|
3658 }
|
|
3659
|
|
3660 if (dump_file)
|
|
3661 {
|
|
3662 const char *inbounds
|
|
3663 = (retval[0] < info.objsize
|
|
3664 ? (retval[1] < info.objsize
|
|
3665 ? "in" : "potentially out-of")
|
|
3666 : "out-of");
|
|
3667
|
|
3668 const char *what = setrange ? "Setting" : "Discarding";
|
|
3669 if (retval[0] != retval[1])
|
|
3670 fprintf (dump_file,
|
|
3671 " %s %s-bounds return value range [%llu, %llu].\n",
|
|
3672 what, inbounds,
|
|
3673 (unsigned long long)retval[0],
|
|
3674 (unsigned long long)retval[1]);
|
|
3675 else
|
|
3676 fprintf (dump_file, " %s %s-bounds return value %llu.\n",
|
|
3677 what, inbounds, (unsigned long long)retval[0]);
|
|
3678 }
|
|
3679 }
|
|
3680
|
|
3681 if (dump_file)
|
|
3682 fputc ('\n', dump_file);
|
|
3683
|
|
3684 return removed;
|
|
3685 }
|
|
3686
|
|
3687 /* Try to simplify a s{,n}printf call described by INFO with result
|
|
3688 RES by replacing it with a simpler and presumably more efficient
|
|
3689 call (such as strcpy). */
|
|
3690
|
|
3691 static bool
|
|
3692 try_simplify_call (gimple_stmt_iterator *gsi,
|
|
3693 const pass_sprintf_length::call_info &info,
|
|
3694 const format_result &res)
|
|
3695 {
|
|
3696 unsigned HOST_WIDE_INT dummy[2];
|
|
3697 if (!is_call_safe (info, res, info.retval_used (), dummy))
|
|
3698 return false;
|
|
3699
|
|
3700 switch (info.fncode)
|
|
3701 {
|
|
3702 case BUILT_IN_SNPRINTF:
|
|
3703 return gimple_fold_builtin_snprintf (gsi);
|
|
3704
|
|
3705 case BUILT_IN_SPRINTF:
|
|
3706 return gimple_fold_builtin_sprintf (gsi);
|
|
3707
|
|
3708 default:
|
|
3709 ;
|
|
3710 }
|
|
3711
|
|
3712 return false;
|
|
3713 }
|
|
3714
|
|
3715 /* Determine if a GIMPLE CALL is to one of the sprintf-like built-in
|
|
3716 functions and if so, handle it. Return true if the call is removed
|
|
3717 and gsi_next should not be performed in the caller. */
|
|
3718
|
|
3719 bool
|
|
3720 pass_sprintf_length::handle_gimple_call (gimple_stmt_iterator *gsi)
|
|
3721 {
|
|
3722 call_info info = call_info ();
|
|
3723
|
|
3724 info.callstmt = gsi_stmt (*gsi);
|
|
3725 if (!gimple_call_builtin_p (info.callstmt, BUILT_IN_NORMAL))
|
|
3726 return false;
|
|
3727
|
|
3728 info.func = gimple_call_fndecl (info.callstmt);
|
|
3729 info.fncode = DECL_FUNCTION_CODE (info.func);
|
|
3730
|
|
3731 /* The size of the destination as in snprintf(dest, size, ...). */
|
|
3732 unsigned HOST_WIDE_INT dstsize = HOST_WIDE_INT_M1U;
|
|
3733
|
|
3734 /* The size of the destination determined by __builtin_object_size. */
|
|
3735 unsigned HOST_WIDE_INT objsize = HOST_WIDE_INT_M1U;
|
|
3736
|
|
3737 /* Buffer size argument number (snprintf and vsnprintf). */
|
|
3738 unsigned HOST_WIDE_INT idx_dstsize = HOST_WIDE_INT_M1U;
|
|
3739
|
|
3740 /* Object size argument number (snprintf_chk and vsnprintf_chk). */
|
|
3741 unsigned HOST_WIDE_INT idx_objsize = HOST_WIDE_INT_M1U;
|
|
3742
|
|
3743 /* Format string argument number (valid for all functions). */
|
|
3744 unsigned idx_format;
|
|
3745
|
|
3746 switch (info.fncode)
|
|
3747 {
|
|
3748 case BUILT_IN_SPRINTF:
|
|
3749 // Signature:
|
|
3750 // __builtin_sprintf (dst, format, ...)
|
|
3751 idx_format = 1;
|
|
3752 info.argidx = 2;
|
|
3753 break;
|
|
3754
|
|
3755 case BUILT_IN_SPRINTF_CHK:
|
|
3756 // Signature:
|
|
3757 // __builtin___sprintf_chk (dst, ost, objsize, format, ...)
|
|
3758 idx_objsize = 2;
|
|
3759 idx_format = 3;
|
|
3760 info.argidx = 4;
|
|
3761 break;
|
|
3762
|
|
3763 case BUILT_IN_SNPRINTF:
|
|
3764 // Signature:
|
|
3765 // __builtin_snprintf (dst, size, format, ...)
|
|
3766 idx_dstsize = 1;
|
|
3767 idx_format = 2;
|
|
3768 info.argidx = 3;
|
|
3769 info.bounded = true;
|
|
3770 break;
|
|
3771
|
|
3772 case BUILT_IN_SNPRINTF_CHK:
|
|
3773 // Signature:
|
|
3774 // __builtin___snprintf_chk (dst, size, ost, objsize, format, ...)
|
|
3775 idx_dstsize = 1;
|
|
3776 idx_objsize = 3;
|
|
3777 idx_format = 4;
|
|
3778 info.argidx = 5;
|
|
3779 info.bounded = true;
|
|
3780 break;
|
|
3781
|
|
3782 case BUILT_IN_VSNPRINTF:
|
|
3783 // Signature:
|
|
3784 // __builtin_vsprintf (dst, size, format, va)
|
|
3785 idx_dstsize = 1;
|
|
3786 idx_format = 2;
|
|
3787 info.argidx = -1;
|
|
3788 info.bounded = true;
|
|
3789 break;
|
|
3790
|
|
3791 case BUILT_IN_VSNPRINTF_CHK:
|
|
3792 // Signature:
|
|
3793 // __builtin___vsnprintf_chk (dst, size, ost, objsize, format, va)
|
|
3794 idx_dstsize = 1;
|
|
3795 idx_objsize = 3;
|
|
3796 idx_format = 4;
|
|
3797 info.argidx = -1;
|
|
3798 info.bounded = true;
|
|
3799 break;
|
|
3800
|
|
3801 case BUILT_IN_VSPRINTF:
|
|
3802 // Signature:
|
|
3803 // __builtin_vsprintf (dst, format, va)
|
|
3804 idx_format = 1;
|
|
3805 info.argidx = -1;
|
|
3806 break;
|
|
3807
|
|
3808 case BUILT_IN_VSPRINTF_CHK:
|
|
3809 // Signature:
|
|
3810 // __builtin___vsprintf_chk (dst, ost, objsize, format, va)
|
|
3811 idx_format = 3;
|
|
3812 idx_objsize = 2;
|
|
3813 info.argidx = -1;
|
|
3814 break;
|
|
3815
|
|
3816 default:
|
|
3817 return false;
|
|
3818 }
|
|
3819
|
|
3820 /* Set the global warning level for this function. */
|
|
3821 warn_level = info.bounded ? warn_format_trunc : warn_format_overflow;
|
|
3822
|
|
3823 /* The first argument is a pointer to the destination. */
|
|
3824 tree dstptr = gimple_call_arg (info.callstmt, 0);
|
|
3825
|
|
3826 info.format = gimple_call_arg (info.callstmt, idx_format);
|
|
3827
|
|
3828 /* True when the destination size is constant as opposed to the lower
|
|
3829 or upper bound of a range. */
|
|
3830 bool dstsize_cst_p = true;
|
|
3831
|
|
3832 if (idx_dstsize == HOST_WIDE_INT_M1U)
|
|
3833 {
|
|
3834 /* For non-bounded functions like sprintf, determine the size
|
|
3835 of the destination from the object or pointer passed to it
|
|
3836 as the first argument. */
|
|
3837 dstsize = get_destination_size (dstptr);
|
|
3838 }
|
|
3839 else if (tree size = gimple_call_arg (info.callstmt, idx_dstsize))
|
|
3840 {
|
|
3841 /* For bounded functions try to get the size argument. */
|
|
3842
|
|
3843 if (TREE_CODE (size) == INTEGER_CST)
|
|
3844 {
|
|
3845 dstsize = tree_to_uhwi (size);
|
|
3846 /* No object can be larger than SIZE_MAX bytes (half the address
|
|
3847 space) on the target.
|
|
3848 The functions are defined only for output of at most INT_MAX
|
|
3849 bytes. Specifying a bound in excess of that limit effectively
|
|
3850 defeats the bounds checking (and on some implementations such
|
|
3851 as Solaris cause the function to fail with EINVAL). */
|
|
3852 if (dstsize > target_size_max () / 2)
|
|
3853 {
|
|
3854 /* Avoid warning if -Wstringop-overflow is specified since
|
|
3855 it also warns for the same thing though only for the
|
|
3856 checking built-ins. */
|
|
3857 if ((idx_objsize == HOST_WIDE_INT_M1U
|
|
3858 || !warn_stringop_overflow))
|
|
3859 warning_at (gimple_location (info.callstmt), info.warnopt (),
|
|
3860 "specified bound %wu exceeds maximum object size "
|
|
3861 "%wu",
|
|
3862 dstsize, target_size_max () / 2);
|
|
3863 }
|
|
3864 else if (dstsize > target_int_max ())
|
|
3865 warning_at (gimple_location (info.callstmt), info.warnopt (),
|
|
3866 "specified bound %wu exceeds %<INT_MAX%>",
|
|
3867 dstsize);
|
|
3868 }
|
|
3869 else if (TREE_CODE (size) == SSA_NAME)
|
|
3870 {
|
|
3871 /* Try to determine the range of values of the argument
|
|
3872 and use the greater of the two at level 1 and the smaller
|
|
3873 of them at level 2. */
|
|
3874 wide_int min, max;
|
|
3875 enum value_range_type range_type
|
|
3876 = get_range_info (size, &min, &max);
|
|
3877 if (range_type == VR_RANGE)
|
|
3878 {
|
|
3879 dstsize
|
|
3880 = (warn_level < 2
|
|
3881 ? wi::fits_uhwi_p (max) ? max.to_uhwi () : max.to_shwi ()
|
|
3882 : wi::fits_uhwi_p (min) ? min.to_uhwi () : min.to_shwi ());
|
|
3883 }
|
|
3884
|
|
3885 /* The destination size is not constant. If the function is
|
|
3886 bounded (e.g., snprintf) a lower bound of zero doesn't
|
|
3887 necessarily imply it can be eliminated. */
|
|
3888 dstsize_cst_p = false;
|
|
3889 }
|
|
3890 }
|
|
3891
|
|
3892 if (idx_objsize != HOST_WIDE_INT_M1U)
|
|
3893 if (tree size = gimple_call_arg (info.callstmt, idx_objsize))
|
|
3894 if (tree_fits_uhwi_p (size))
|
|
3895 objsize = tree_to_uhwi (size);
|
|
3896
|
|
3897 if (info.bounded && !dstsize)
|
|
3898 {
|
|
3899 /* As a special case, when the explicitly specified destination
|
|
3900 size argument (to a bounded function like snprintf) is zero
|
|
3901 it is a request to determine the number of bytes on output
|
|
3902 without actually producing any. Pretend the size is
|
|
3903 unlimited in this case. */
|
|
3904 info.objsize = HOST_WIDE_INT_MAX;
|
|
3905 info.nowrite = dstsize_cst_p;
|
|
3906 }
|
|
3907 else
|
|
3908 {
|
|
3909 /* For calls to non-bounded functions or to those of bounded
|
|
3910 functions with a non-zero size, warn if the destination
|
|
3911 pointer is null. */
|
|
3912 if (integer_zerop (dstptr))
|
|
3913 {
|
|
3914 /* This is diagnosed with -Wformat only when the null is a constant
|
|
3915 pointer. The warning here diagnoses instances where the pointer
|
|
3916 is not constant. */
|
|
3917 location_t loc = gimple_location (info.callstmt);
|
|
3918 warning_at (EXPR_LOC_OR_LOC (dstptr, loc),
|
|
3919 info.warnopt (), "null destination pointer");
|
|
3920 return false;
|
|
3921 }
|
|
3922
|
|
3923 /* Set the object size to the smaller of the two arguments
|
|
3924 of both have been specified and they're not equal. */
|
|
3925 info.objsize = dstsize < objsize ? dstsize : objsize;
|
|
3926
|
|
3927 if (info.bounded
|
|
3928 && dstsize < target_size_max () / 2 && objsize < dstsize
|
|
3929 /* Avoid warning if -Wstringop-overflow is specified since
|
|
3930 it also warns for the same thing though only for the
|
|
3931 checking built-ins. */
|
|
3932 && (idx_objsize == HOST_WIDE_INT_M1U
|
|
3933 || !warn_stringop_overflow))
|
|
3934 {
|
|
3935 warning_at (gimple_location (info.callstmt), info.warnopt (),
|
|
3936 "specified bound %wu exceeds the size %wu "
|
|
3937 "of the destination object", dstsize, objsize);
|
|
3938 }
|
|
3939 }
|
|
3940
|
|
3941 if (integer_zerop (info.format))
|
|
3942 {
|
|
3943 /* This is diagnosed with -Wformat only when the null is a constant
|
|
3944 pointer. The warning here diagnoses instances where the pointer
|
|
3945 is not constant. */
|
|
3946 location_t loc = gimple_location (info.callstmt);
|
|
3947 warning_at (EXPR_LOC_OR_LOC (info.format, loc),
|
|
3948 info.warnopt (), "null format string");
|
|
3949 return false;
|
|
3950 }
|
|
3951
|
|
3952 info.fmtstr = get_format_string (info.format, &info.fmtloc);
|
|
3953 if (!info.fmtstr)
|
|
3954 return false;
|
|
3955
|
|
3956 /* The result is the number of bytes output by the formatted function,
|
|
3957 including the terminating NUL. */
|
|
3958 format_result res = format_result ();
|
|
3959
|
|
3960 bool success = compute_format_length (info, &res);
|
|
3961
|
|
3962 /* When optimizing and the printf return value optimization is enabled,
|
|
3963 attempt to substitute the computed result for the return value of
|
|
3964 the call. Avoid this optimization when -frounding-math is in effect
|
|
3965 and the format string contains a floating point directive. */
|
|
3966 bool call_removed = false;
|
|
3967 if (success && optimize > 0)
|
|
3968 {
|
|
3969 /* Save a copy of the iterator pointing at the call. The iterator
|
|
3970 may change to point past the call in try_substitute_return_value
|
|
3971 but the original value is needed in try_simplify_call. */
|
|
3972 gimple_stmt_iterator gsi_call = *gsi;
|
|
3973
|
|
3974 if (flag_printf_return_value
|
|
3975 && (!flag_rounding_math || !res.floating))
|
|
3976 call_removed = try_substitute_return_value (gsi, info, res);
|
|
3977
|
|
3978 if (!call_removed)
|
|
3979 try_simplify_call (&gsi_call, info, res);
|
|
3980 }
|
|
3981
|
|
3982 return call_removed;
|
|
3983 }
|
|
3984
|
|
3985 /* Execute the pass for function FUN. */
|
|
3986
|
|
3987 unsigned int
|
|
3988 pass_sprintf_length::execute (function *fun)
|
|
3989 {
|
|
3990 init_target_to_host_charmap ();
|
|
3991
|
|
3992 basic_block bb;
|
|
3993 FOR_EACH_BB_FN (bb, fun)
|
|
3994 {
|
|
3995 for (gimple_stmt_iterator si = gsi_start_bb (bb); !gsi_end_p (si); )
|
|
3996 {
|
|
3997 /* Iterate over statements, looking for function calls. */
|
|
3998 gimple *stmt = gsi_stmt (si);
|
|
3999
|
|
4000 if (is_gimple_call (stmt) && handle_gimple_call (&si))
|
|
4001 /* If handle_gimple_call returns true, the iterator is
|
|
4002 already pointing to the next statement. */
|
|
4003 continue;
|
|
4004
|
|
4005 gsi_next (&si);
|
|
4006 }
|
|
4007 }
|
|
4008
|
|
4009 /* Clean up object size info. */
|
|
4010 fini_object_sizes ();
|
|
4011
|
|
4012 return 0;
|
|
4013 }
|
|
4014
|
|
4015 } /* Unnamed namespace. */
|
|
4016
|
|
4017 /* Return a pointer to a pass object newly constructed from the context
|
|
4018 CTXT. */
|
|
4019
|
|
4020 gimple_opt_pass *
|
|
4021 make_pass_sprintf_length (gcc::context *ctxt)
|
|
4022 {
|
|
4023 return new pass_sprintf_length (ctxt);
|
|
4024 }
|