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