1 /* Check calls to formatted I/O functions (-Wformat). 2 Copyright (C) 1992-2022 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 "c-target.h" 25 #include "c-common.h" 26 #include "alloc-pool.h" 27 #include "stringpool.h" 28 #include "c-objc.h" 29 #include "intl.h" 30 #include "langhooks.h" 31 #include "c-format.h" 32 #include "diagnostic.h" 33 #include "substring-locations.h" 34 #include "selftest.h" 35 #include "selftest-diagnostic.h" 36 #include "builtins.h" 37 #include "attribs.h" 38 #include "gcc-rich-location.h" 39 40 /* Handle attributes associated with format checking. */ 41 42 /* This must be in the same order as format_types, except for 43 format_type_error. Target-specific format types do not have 44 matching enum values. */ 45 enum format_type { printf_format_type, asm_fprintf_format_type, 46 gcc_diag_format_type, gcc_tdiag_format_type, 47 gcc_cdiag_format_type, 48 gcc_cxxdiag_format_type, gcc_gfc_format_type, 49 gcc_dump_printf_format_type, 50 gcc_objc_string_format_type, 51 format_type_error = -1}; 52 53 struct function_format_info 54 { 55 enum format_type format_type; /* type of format (printf, scanf, etc.) */ 56 /* IS_RAW is relevant only for GCC diagnostic format functions. 57 It is set for "raw" formatting functions like pp_printf that 58 are not intended to produce complete diagnostics according to 59 GCC guidelines, and clear for others like error and warning 60 whose format string is checked for proper quoting and spelling. */ 61 bool is_raw; 62 unsigned HOST_WIDE_INT format_num; /* number of format argument */ 63 unsigned HOST_WIDE_INT first_arg_num; /* number of first arg (zero for varargs) */ 64 }; 65 66 /* Initialized in init_dynamic_diag_info. */ 67 static GTY(()) tree local_tree_type_node; 68 static GTY(()) tree local_event_ptr_node; 69 static GTY(()) tree local_gimple_ptr_node; 70 static GTY(()) tree local_cgraph_node_ptr_node; 71 static GTY(()) tree locus; 72 73 static bool decode_format_attr (const_tree, tree, tree, function_format_info *, 74 bool); 75 static format_type decode_format_type (const char *, bool * = NULL); 76 77 static bool check_format_string (const_tree argument, 78 unsigned HOST_WIDE_INT format_num, 79 int flags, bool *no_add_attrs, 80 int expected_format_type); 81 static tree get_constant (const_tree fntype, const_tree atname, tree expr, 82 int argno, unsigned HOST_WIDE_INT *value, 83 int flags, bool validated_p); 84 static const char *convert_format_name_to_system_name (const char *attr_name); 85 86 static int first_target_format_type; 87 static const char *format_name (int format_num); 88 static int format_flags (int format_num); 89 90 /* Emit a warning as per format_warning_va, but construct the substring_loc 91 for the character at offset (CHAR_IDX - 1) within a string constant 92 FORMAT_STRING_CST at FMT_STRING_LOC. */ 93 94 ATTRIBUTE_GCC_DIAG (5,6) 95 static bool 96 format_warning_at_char (location_t fmt_string_loc, tree format_string_cst, 97 int char_idx, int opt, const char *gmsgid, ...) 98 { 99 va_list ap; 100 va_start (ap, gmsgid); 101 tree string_type = TREE_TYPE (format_string_cst); 102 103 /* The callers are of the form: 104 format_warning (format_string_loc, format_string_cst, 105 format_chars - orig_format_chars, 106 where format_chars has already been incremented, so that 107 CHAR_IDX is one character beyond where the warning should 108 be emitted. Fix it. */ 109 char_idx -= 1; 110 111 substring_loc fmt_loc (fmt_string_loc, string_type, char_idx, char_idx, 112 char_idx); 113 format_string_diagnostic_t diag (fmt_loc, NULL, UNKNOWN_LOCATION, NULL, 114 NULL); 115 bool warned = diag.emit_warning_va (opt, gmsgid, &ap); 116 va_end (ap); 117 118 return warned; 119 } 120 121 122 /* Emit a warning as per format_warning_va, but construct the substring_loc 123 for the substring at offset (POS1, POS2 - 1) within a string constant 124 FORMAT_STRING_CST at FMT_STRING_LOC. */ 125 126 ATTRIBUTE_GCC_DIAG (6,7) 127 static bool 128 format_warning_substr (location_t fmt_string_loc, tree format_string_cst, 129 int pos1, int pos2, int opt, const char *gmsgid, ...) 130 { 131 va_list ap; 132 va_start (ap, gmsgid); 133 tree string_type = TREE_TYPE (format_string_cst); 134 135 pos2 -= 1; 136 137 substring_loc fmt_loc (fmt_string_loc, string_type, pos1, pos1, pos2); 138 format_string_diagnostic_t diag (fmt_loc, NULL, UNKNOWN_LOCATION, NULL, 139 NULL); 140 bool warned = diag.emit_warning_va (opt, gmsgid, &ap); 141 va_end (ap); 142 143 return warned; 144 } 145 146 147 /* Check that we have a pointer to a string suitable for use as a format. 148 The default is to check for a char type. 149 For objective-c dialects, this is extended to include references to string 150 objects validated by objc_string_ref_type_p (). 151 Targets may also provide a string object type that can be used within c and 152 c++ and shared with their respective objective-c dialects. In this case the 153 reference to a format string is checked for validity via a hook. 154 155 The function returns true if strref points to any string type valid for the 156 language dialect and target. */ 157 158 bool 159 valid_format_string_type_p (tree strref) 160 { 161 return (strref != NULL 162 && TREE_CODE (strref) == POINTER_TYPE 163 && (TYPE_MAIN_VARIANT (TREE_TYPE (strref)) == char_type_node 164 || objc_string_ref_type_p (strref) 165 || (*targetcm.string_object_ref_type_p) ((const_tree) strref))); 166 } 167 168 /* Handle a "format_arg" attribute; arguments as in 169 struct attribute_spec.handler. */ 170 tree 171 handle_format_arg_attribute (tree *node, tree atname, 172 tree args, int flags, bool *no_add_attrs) 173 { 174 tree type = *node; 175 /* Note that TREE_VALUE (args) is changed in place below. */ 176 tree *format_num_expr = &TREE_VALUE (args); 177 unsigned HOST_WIDE_INT format_num = 0; 178 179 if (tree val = get_constant (type, atname, *format_num_expr, 0, &format_num, 180 0, false)) 181 *format_num_expr = val; 182 else 183 { 184 *no_add_attrs = true; 185 return NULL_TREE; 186 } 187 188 if (prototype_p (type)) 189 { 190 /* The format arg can be any string reference valid for the language and 191 target. We cannot be more specific in this case. */ 192 if (!check_format_string (type, format_num, flags, no_add_attrs, -1)) 193 return NULL_TREE; 194 } 195 196 if (!valid_format_string_type_p (TREE_TYPE (type))) 197 { 198 if (!(flags & (int) ATTR_FLAG_BUILT_IN)) 199 error ("function does not return string type"); 200 *no_add_attrs = true; 201 return NULL_TREE; 202 } 203 204 return NULL_TREE; 205 } 206 207 /* Verify that the format_num argument is actually a string reference suitable, 208 for the language dialect and target (in case the format attribute is in 209 error). When we know the specific reference type expected, this is also 210 checked. */ 211 static bool 212 check_format_string (const_tree fntype, unsigned HOST_WIDE_INT format_num, 213 int flags, bool *no_add_attrs, int expected_format_type) 214 { 215 unsigned HOST_WIDE_INT i; 216 bool is_objc_sref, is_target_sref, is_char_ref; 217 tree ref; 218 int fmt_flags; 219 function_args_iterator iter; 220 221 i = 1; 222 FOREACH_FUNCTION_ARGS (fntype, ref, iter) 223 { 224 if (i == format_num) 225 break; 226 i++; 227 } 228 229 if (!ref 230 || !valid_format_string_type_p (ref)) 231 { 232 if (!(flags & (int) ATTR_FLAG_BUILT_IN)) 233 error ("format string argument is not a string type"); 234 *no_add_attrs = true; 235 return false; 236 } 237 238 /* We only know that we want a suitable string reference. */ 239 if (expected_format_type < 0) 240 return true; 241 242 /* Now check that the arg matches the expected type. */ 243 is_char_ref = 244 (TYPE_MAIN_VARIANT (TREE_TYPE (ref)) == char_type_node); 245 246 fmt_flags = format_flags (expected_format_type); 247 is_objc_sref = is_target_sref = false; 248 if (!is_char_ref) 249 is_objc_sref = objc_string_ref_type_p (ref); 250 251 if (!(fmt_flags & FMT_FLAG_PARSE_ARG_CONVERT_EXTERNAL)) 252 { 253 if (is_char_ref) 254 return true; /* OK, we expected a char and found one. */ 255 else 256 { 257 /* We expected a char but found an extended string type. */ 258 if (is_objc_sref) 259 error ("found a %qs reference but the format argument should" 260 " be a string", format_name (gcc_objc_string_format_type)); 261 else 262 error ("found a %qT but the format argument should be a string", 263 ref); 264 *no_add_attrs = true; 265 return false; 266 } 267 } 268 269 /* We expect a string object type as the format arg. */ 270 if (is_char_ref) 271 { 272 error ("format argument should be a %qs reference but" 273 " a string was found", format_name (expected_format_type)); 274 *no_add_attrs = true; 275 return false; 276 } 277 278 /* We will assert that objective-c will support either its own string type 279 or the target-supplied variant. */ 280 if (!is_objc_sref) 281 is_target_sref = (*targetcm.string_object_ref_type_p) ((const_tree) ref); 282 283 if (expected_format_type == (int) gcc_objc_string_format_type 284 && (is_objc_sref || is_target_sref)) 285 return true; 286 287 /* We will allow a target string ref to match only itself. */ 288 if (first_target_format_type 289 && expected_format_type >= first_target_format_type 290 && is_target_sref) 291 return true; 292 else 293 { 294 error ("format argument should be a %qs reference", 295 format_name (expected_format_type)); 296 *no_add_attrs = true; 297 return false; 298 } 299 } 300 301 /* Under the control of FLAGS, verify EXPR is a valid constant that 302 refers to a positional argument ARGNO having a string type (char* 303 or, for targets like Darwin, a pointer to struct CFString) to 304 a function type FNTYPE declared with attribute ATNAME. 305 If valid, store the constant's integer value in *VALUE and return 306 the value. 307 If VALIDATED_P is true assert the validation is successful. 308 Returns the converted constant value on success, null otherwise. */ 309 310 static tree 311 get_constant (const_tree fntype, const_tree atname, tree expr, int argno, 312 unsigned HOST_WIDE_INT *value, int flags, bool validated_p) 313 { 314 /* Require the referenced argument to have a string type. For targets 315 like Darwin, also accept pointers to struct CFString. */ 316 if (tree val = positional_argument (fntype, atname, expr, STRING_CST, 317 argno, flags)) 318 { 319 *value = TREE_INT_CST_LOW (val); 320 return val; 321 } 322 323 gcc_assert (!validated_p); 324 return NULL_TREE; 325 } 326 327 /* Decode the arguments to a "format" attribute into a 328 function_format_info structure. It is already known that the list 329 is of the right length. If VALIDATED_P is true, then these 330 attributes have already been validated and must not be erroneous; 331 if false, it will give an error message. Returns true if the 332 attributes are successfully decoded, false otherwise. */ 333 334 static bool 335 decode_format_attr (const_tree fntype, tree atname, tree args, 336 function_format_info *info, bool validated_p) 337 { 338 tree format_type_id = TREE_VALUE (args); 339 /* Note that TREE_VALUE (args) is changed in place below. Ditto 340 for the value of the next element on the list. */ 341 tree *format_num_expr = &TREE_VALUE (TREE_CHAIN (args)); 342 tree *first_arg_num_expr = &TREE_VALUE (TREE_CHAIN (TREE_CHAIN (args))); 343 344 if (TREE_CODE (format_type_id) != IDENTIFIER_NODE) 345 { 346 gcc_assert (!validated_p); 347 error ("unrecognized format specifier"); 348 return false; 349 } 350 else 351 { 352 const char *p = IDENTIFIER_POINTER (format_type_id); 353 354 info->format_type = decode_format_type (p, &info->is_raw); 355 356 if (!c_dialect_objc () 357 && info->format_type == gcc_objc_string_format_type) 358 { 359 gcc_assert (!validated_p); 360 warning (OPT_Wformat_, "%qE is only allowed in Objective-C dialects", 361 format_type_id); 362 info->format_type = format_type_error; 363 return false; 364 } 365 366 if (info->format_type == format_type_error) 367 { 368 gcc_assert (!validated_p); 369 warning (OPT_Wformat_, "%qE is an unrecognized format function type", 370 format_type_id); 371 return false; 372 } 373 } 374 375 if (tree val = get_constant (fntype, atname, *format_num_expr, 376 2, &info->format_num, 0, validated_p)) 377 *format_num_expr = val; 378 else 379 return false; 380 381 if (tree val = get_constant (fntype, atname, *first_arg_num_expr, 382 3, &info->first_arg_num, 383 (POSARG_ZERO | POSARG_ELLIPSIS), validated_p)) 384 *first_arg_num_expr = val; 385 else 386 return false; 387 388 if (info->first_arg_num != 0 && info->first_arg_num <= info->format_num) 389 { 390 gcc_assert (!validated_p); 391 error ("format string argument follows the arguments to be formatted"); 392 return false; 393 } 394 395 return true; 396 } 397 398 /* Check a call to a format function against a parameter list. */ 400 401 /* The C standard version C++ is treated as equivalent to 402 or inheriting from, for the purpose of format features supported. */ 403 #define CPLUSPLUS_STD_VER (cxx_dialect < cxx11 ? STD_C94 : STD_C99) 404 /* The C standard version we are checking formats against when pedantic. */ 405 #define C_STD_VER ((int) (c_dialect_cxx () \ 406 ? CPLUSPLUS_STD_VER \ 407 : (flag_isoc2x \ 408 ? STD_C2X \ 409 : (flag_isoc99 \ 410 ? STD_C99 \ 411 : (flag_isoc94 ? STD_C94 : STD_C89))))) 412 /* The name to give to the standard version we are warning about when 413 pedantic. FEATURE_VER is the version in which the feature warned out 414 appeared, which is higher than C_STD_VER. */ 415 #define C_STD_NAME(FEATURE_VER) (c_dialect_cxx () \ 416 ? (cxx_dialect < cxx11 ? "ISO C++98" \ 417 : "ISO C++11") \ 418 : ((FEATURE_VER) == STD_EXT \ 419 ? "ISO C" \ 420 : ((FEATURE_VER) == STD_C2X \ 421 ? "ISO C17" \ 422 : "ISO C90"))) 423 /* Adjust a C standard version, which may be STD_C9L, to account for 424 -Wno-long-long. Returns other standard versions unchanged. */ 425 #define ADJ_STD(VER) ((int) ((VER) == STD_C9L \ 426 ? (warn_long_long ? STD_C99 : STD_C89) \ 427 : (VER))) 428 429 /* Enum describing the kind of specifiers present in the format and 430 requiring an argument. */ 431 enum format_specifier_kind { 432 CF_KIND_FORMAT, 433 CF_KIND_FIELD_WIDTH, 434 CF_KIND_FIELD_PRECISION 435 }; 436 437 static const char *kind_descriptions[] = { 438 N_("format"), 439 N_("field width specifier"), 440 N_("field precision specifier") 441 }; 442 443 /* Structure describing details of a type expected in format checking, 444 and the type to check against it. */ 445 struct format_wanted_type 446 { 447 /* The type wanted. */ 448 tree wanted_type; 449 /* The name of this type to use in diagnostics. */ 450 const char *wanted_type_name; 451 /* Should be type checked just for scalar width identity. */ 452 int scalar_identity_flag; 453 /* The level of indirection through pointers at which this type occurs. */ 454 int pointer_count; 455 /* Whether, when pointer_count is 1, to allow any character type when 456 pedantic, rather than just the character or void type specified. */ 457 int char_lenient_flag; 458 /* Whether the argument, dereferenced once, is written into and so the 459 argument must not be a pointer to a const-qualified type. */ 460 int writing_in_flag; 461 /* Whether the argument, dereferenced once, is read from and so 462 must not be a NULL pointer. */ 463 int reading_from_flag; 464 /* The kind of specifier that this type is used for. */ 465 enum format_specifier_kind kind; 466 /* The starting character of the specifier. This never includes the 467 initial percent sign. */ 468 const char *format_start; 469 /* The length of the specifier. */ 470 int format_length; 471 /* The actual parameter to check against the wanted type. */ 472 tree param; 473 /* The argument number of that parameter. */ 474 int arg_num; 475 /* The offset location of this argument with respect to the format 476 string location. */ 477 unsigned int offset_loc; 478 /* The next type to check for this format conversion, or NULL if none. */ 479 struct format_wanted_type *next; 480 }; 481 482 /* Convenience macro for format_length_info meaning unused. */ 483 #define NO_FMT NULL, FMT_LEN_none, STD_C89 484 485 static const format_length_info printf_length_specs[] = 486 { 487 { "h", FMT_LEN_h, STD_C89, "hh", FMT_LEN_hh, STD_C99, 0 }, 488 { "l", FMT_LEN_l, STD_C89, "ll", FMT_LEN_ll, STD_C9L, 0 }, 489 { "q", FMT_LEN_ll, STD_EXT, NO_FMT, 0 }, 490 { "L", FMT_LEN_L, STD_C89, NO_FMT, 0 }, 491 { "z", FMT_LEN_z, STD_C99, NO_FMT, 0 }, 492 { "Z", FMT_LEN_z, STD_EXT, NO_FMT, 0 }, 493 { "t", FMT_LEN_t, STD_C99, NO_FMT, 0 }, 494 { "j", FMT_LEN_j, STD_C99, NO_FMT, 0 }, 495 { "H", FMT_LEN_H, STD_C2X, NO_FMT, 0 }, 496 { "D", FMT_LEN_D, STD_C2X, "DD", FMT_LEN_DD, STD_C2X, 0 }, 497 { NO_FMT, NO_FMT, 0 } 498 }; 499 500 /* Length specifiers valid for asm_fprintf. */ 501 static const format_length_info asm_fprintf_length_specs[] = 502 { 503 { "l", FMT_LEN_l, STD_C89, "ll", FMT_LEN_ll, STD_C89, 0 }, 504 { "w", FMT_LEN_w, STD_C89, NO_FMT, 0 }, 505 { NO_FMT, NO_FMT, 0 } 506 }; 507 508 /* Length specifiers valid for GCC diagnostics. */ 509 static const format_length_info gcc_diag_length_specs[] = 510 { 511 { "l", FMT_LEN_l, STD_C89, "ll", FMT_LEN_ll, STD_C89, 0 }, 512 { "w", FMT_LEN_w, STD_C89, NO_FMT, 0 }, 513 { NO_FMT, NO_FMT, 0 } 514 }; 515 516 /* The custom diagnostics all accept the same length specifiers. */ 517 #define gcc_tdiag_length_specs gcc_diag_length_specs 518 #define gcc_cdiag_length_specs gcc_diag_length_specs 519 #define gcc_cxxdiag_length_specs gcc_diag_length_specs 520 #define gcc_dump_printf_length_specs gcc_diag_length_specs 521 522 /* This differs from printf_length_specs only in that "Z" is not accepted. */ 523 static const format_length_info scanf_length_specs[] = 524 { 525 { "h", FMT_LEN_h, STD_C89, "hh", FMT_LEN_hh, STD_C99, 0 }, 526 { "l", FMT_LEN_l, STD_C89, "ll", FMT_LEN_ll, STD_C9L, 0 }, 527 { "q", FMT_LEN_ll, STD_EXT, NO_FMT, 0 }, 528 { "L", FMT_LEN_L, STD_C89, NO_FMT, 0 }, 529 { "z", FMT_LEN_z, STD_C99, NO_FMT, 0 }, 530 { "t", FMT_LEN_t, STD_C99, NO_FMT, 0 }, 531 { "j", FMT_LEN_j, STD_C99, NO_FMT, 0 }, 532 { "H", FMT_LEN_H, STD_C2X, NO_FMT, 0 }, 533 { "D", FMT_LEN_D, STD_C2X, "DD", FMT_LEN_DD, STD_C2X, 0 }, 534 { NO_FMT, NO_FMT, 0 } 535 }; 536 537 538 /* All tables for strfmon use STD_C89 everywhere, since -pedantic warnings 539 make no sense for a format type not part of any C standard version. */ 540 static const format_length_info strfmon_length_specs[] = 541 { 542 /* A GNU extension. */ 543 { "L", FMT_LEN_L, STD_C89, NO_FMT, 0 }, 544 { NO_FMT, NO_FMT, 0 } 545 }; 546 547 548 /* Length modifiers used by the fortran/error.cc routines. */ 549 static const format_length_info gcc_gfc_length_specs[] = 550 { 551 { "l", FMT_LEN_l, STD_C89, "ll", FMT_LEN_ll, STD_C89, 0 }, 552 { "w", FMT_LEN_w, STD_C89, NO_FMT, 0 }, 553 { NO_FMT, NO_FMT, 0 } 554 }; 555 556 557 static const format_flag_spec printf_flag_specs[] = 558 { 559 { ' ', 0, 0, 0, N_("' ' flag"), N_("the ' ' printf flag"), STD_C89 }, 560 { '+', 0, 0, 0, N_("'+' flag"), N_("the '+' printf flag"), STD_C89 }, 561 { '#', 0, 0, 0, N_("'#' flag"), N_("the '#' printf flag"), STD_C89 }, 562 { '0', 0, 0, 0, N_("'0' flag"), N_("the '0' printf flag"), STD_C89 }, 563 { '-', 0, 0, 0, N_("'-' flag"), N_("the '-' printf flag"), STD_C89 }, 564 { '\'', 0, 0, 0, N_("''' flag"), N_("the ''' printf flag"), STD_EXT }, 565 { 'I', 0, 0, 0, N_("'I' flag"), N_("the 'I' printf flag"), STD_EXT }, 566 { 'w', 0, 0, 0, N_("field width"), N_("field width in printf format"), STD_C89 }, 567 { 'p', 0, 0, 0, N_("precision"), N_("precision in printf format"), STD_C89 }, 568 { 'L', 0, 0, 0, N_("length modifier"), N_("length modifier in printf format"), STD_C89 }, 569 { 0, 0, 0, 0, NULL, NULL, STD_C89 } 570 }; 571 572 573 static const format_flag_pair printf_flag_pairs[] = 574 { 575 { ' ', '+', 1, 0 }, 576 { '0', '-', 1, 0 }, 577 { '0', 'p', 1, 'i' }, 578 { 0, 0, 0, 0 } 579 }; 580 581 static const format_flag_spec asm_fprintf_flag_specs[] = 582 { 583 { ' ', 0, 0, 0, N_("' ' flag"), N_("the ' ' printf flag"), STD_C89 }, 584 { '+', 0, 0, 0, N_("'+' flag"), N_("the '+' printf flag"), STD_C89 }, 585 { '#', 0, 0, 0, N_("'#' flag"), N_("the '#' printf flag"), STD_C89 }, 586 { '0', 0, 0, 0, N_("'0' flag"), N_("the '0' printf flag"), STD_C89 }, 587 { '-', 0, 0, 0, N_("'-' flag"), N_("the '-' printf flag"), STD_C89 }, 588 { 'w', 0, 0, 0, N_("field width"), N_("field width in printf format"), STD_C89 }, 589 { 'p', 0, 0, 0, N_("precision"), N_("precision in printf format"), STD_C89 }, 590 { 'L', 0, 0, 0, N_("length modifier"), N_("length modifier in printf format"), STD_C89 }, 591 { 0, 0, 0, 0, NULL, NULL, STD_C89 } 592 }; 593 594 static const format_flag_pair asm_fprintf_flag_pairs[] = 595 { 596 { ' ', '+', 1, 0 }, 597 { '0', '-', 1, 0 }, 598 { '0', 'p', 1, 'i' }, 599 { 0, 0, 0, 0 } 600 }; 601 602 static const format_flag_pair gcc_diag_flag_pairs[] = 603 { 604 { 0, 0, 0, 0 } 605 }; 606 607 #define gcc_tdiag_flag_pairs gcc_diag_flag_pairs 608 #define gcc_cdiag_flag_pairs gcc_diag_flag_pairs 609 #define gcc_cxxdiag_flag_pairs gcc_diag_flag_pairs 610 #define gcc_gfc_flag_pairs gcc_diag_flag_pairs 611 #define gcc_dump_printf_flag_pairs gcc_diag_flag_pairs 612 613 static const format_flag_spec gcc_diag_flag_specs[] = 614 { 615 { '+', 0, 0, 0, N_("'+' flag"), N_("the '+' printf flag"), STD_C89 }, 616 { '#', 0, 0, 0, N_("'#' flag"), N_("the '#' printf flag"), STD_C89 }, 617 { 'q', 0, 0, 1, N_("'q' flag"), N_("the 'q' diagnostic flag"), STD_C89 }, 618 { 'p', 0, 0, 0, N_("precision"), N_("precision in printf format"), STD_C89 }, 619 { 'L', 0, 0, 0, N_("length modifier"), N_("length modifier in printf format"), STD_C89 }, 620 { 0, 0, 0, 0, NULL, NULL, STD_C89 } 621 }; 622 623 #define gcc_tdiag_flag_specs gcc_diag_flag_specs 624 #define gcc_cdiag_flag_specs gcc_diag_flag_specs 625 #define gcc_cxxdiag_flag_specs gcc_diag_flag_specs 626 #define gcc_gfc_flag_specs gcc_diag_flag_specs 627 #define gcc_dump_printf_flag_specs gcc_diag_flag_specs 628 629 static const format_flag_spec scanf_flag_specs[] = 630 { 631 { '*', 0, 0, 0, N_("assignment suppression"), N_("the assignment suppression scanf feature"), STD_C89 }, 632 { 'a', 0, 0, 0, N_("'a' flag"), N_("the 'a' scanf flag"), STD_EXT }, 633 { 'm', 0, 0, 0, N_("'m' flag"), N_("the 'm' scanf flag"), STD_EXT }, 634 { 'w', 0, 0, 0, N_("field width"), N_("field width in scanf format"), STD_C89 }, 635 { 'L', 0, 0, 0, N_("length modifier"), N_("length modifier in scanf format"), STD_C89 }, 636 { '\'', 0, 0, 0, N_("''' flag"), N_("the ''' scanf flag"), STD_EXT }, 637 { 'I', 0, 0, 0, N_("'I' flag"), N_("the 'I' scanf flag"), STD_EXT }, 638 { 0, 0, 0, 0, NULL, NULL, STD_C89 } 639 }; 640 641 642 static const format_flag_pair scanf_flag_pairs[] = 643 { 644 { '*', 'L', 0, 0 }, 645 { 'a', 'm', 0, 0 }, 646 { 0, 0, 0, 0 } 647 }; 648 649 650 static const format_flag_spec strftime_flag_specs[] = 651 { 652 { '_', 0, 0, 0, N_("'_' flag"), N_("the '_' strftime flag"), STD_EXT }, 653 { '-', 0, 0, 0, N_("'-' flag"), N_("the '-' strftime flag"), STD_EXT }, 654 { '0', 0, 0, 0, N_("'0' flag"), N_("the '0' strftime flag"), STD_EXT }, 655 { '^', 0, 0, 0, N_("'^' flag"), N_("the '^' strftime flag"), STD_EXT }, 656 { '#', 0, 0, 0, N_("'#' flag"), N_("the '#' strftime flag"), STD_EXT }, 657 { 'w', 0, 0, 0, N_("field width"), N_("field width in strftime format"), STD_EXT }, 658 { 'E', 0, 0, 0, N_("'E' modifier"), N_("the 'E' strftime modifier"), STD_C99 }, 659 { 'O', 0, 0, 0, N_("'O' modifier"), N_("the 'O' strftime modifier"), STD_C99 }, 660 { 'O', 'o', 0, 0, NULL, N_("the 'O' modifier"), STD_EXT }, 661 { 'O', 'p', 0, 0, NULL, N_("the 'O' modifier"), STD_C2X }, 662 { 0, 0, 0, 0, NULL, NULL, STD_C89 } 663 }; 664 665 666 static const format_flag_pair strftime_flag_pairs[] = 667 { 668 { 'E', 'O', 0, 0 }, 669 { '_', '-', 0, 0 }, 670 { '_', '0', 0, 0 }, 671 { '-', '0', 0, 0 }, 672 { '^', '#', 0, 0 }, 673 { 0, 0, 0, 0 } 674 }; 675 676 677 static const format_flag_spec strfmon_flag_specs[] = 678 { 679 { '=', 0, 1, 0, N_("fill character"), N_("fill character in strfmon format"), STD_C89 }, 680 { '^', 0, 0, 0, N_("'^' flag"), N_("the '^' strfmon flag"), STD_C89 }, 681 { '+', 0, 0, 0, N_("'+' flag"), N_("the '+' strfmon flag"), STD_C89 }, 682 { '(', 0, 0, 0, N_("'(' flag"), N_("the '(' strfmon flag"), STD_C89 }, 683 { '!', 0, 0, 0, N_("'!' flag"), N_("the '!' strfmon flag"), STD_C89 }, 684 { '-', 0, 0, 0, N_("'-' flag"), N_("the '-' strfmon flag"), STD_C89 }, 685 { 'w', 0, 0, 0, N_("field width"), N_("field width in strfmon format"), STD_C89 }, 686 { '#', 0, 0, 0, N_("left precision"), N_("left precision in strfmon format"), STD_C89 }, 687 { 'p', 0, 0, 0, N_("right precision"), N_("right precision in strfmon format"), STD_C89 }, 688 { 'L', 0, 0, 0, N_("length modifier"), N_("length modifier in strfmon format"), STD_C89 }, 689 { 0, 0, 0, 0, NULL, NULL, STD_C89 } 690 }; 691 692 static const format_flag_pair strfmon_flag_pairs[] = 693 { 694 { '+', '(', 0, 0 }, 695 { 0, 0, 0, 0 } 696 }; 697 698 699 static const format_char_info print_char_table[] = 700 { 701 /* C89 conversion specifiers. */ 702 { "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 }, 703 { "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 }, 704 { "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 }, 705 { "fgG", 0, STD_C89, { T89_D, BADLEN, BADLEN, T99_D, BADLEN, T89_LD, BADLEN, BADLEN, BADLEN, T2X_D32, T2X_D64, T2X_D128 }, "-wp0 +#'I", "", NULL }, 706 { "eE", 0, STD_C89, { T89_D, BADLEN, BADLEN, T99_D, BADLEN, T89_LD, BADLEN, BADLEN, BADLEN, T2X_D32, T2X_D64, T2X_D128 }, "-wp0 +#I", "", NULL }, 707 { "c", 0, STD_C89, { T89_I, BADLEN, BADLEN, T94_WI, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN }, "-w", "", NULL }, 708 { "s", 1, STD_C89, { T89_C, BADLEN, BADLEN, T94_W, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN }, "-wp", "cR", NULL }, 709 { "p", 1, STD_C89, { T89_V, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN }, "-w", "c", NULL }, 710 { "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 }, 711 /* C99 conversion specifiers. */ 712 { "F", 0, STD_C99, { T99_D, BADLEN, BADLEN, T99_D, BADLEN, T99_LD, BADLEN, BADLEN, BADLEN, T2X_D32, T2X_D64, T2X_D128 }, "-wp0 +#'I", "", NULL }, 713 { "aA", 0, STD_C99, { T99_D, BADLEN, BADLEN, T99_D, BADLEN, T99_LD, BADLEN, BADLEN, BADLEN, T2X_D32, T2X_D64, T2X_D128 }, "-wp0 +#", "", NULL }, 714 /* C2X conversion specifiers. */ 715 { "b", 0, STD_C2X, { T2X_UI, T2X_UC, T2X_US, T2X_UL, T2X_ULL, TEX_ULL, T2X_ST, T2X_UPD, T2X_UIM, BADLEN, BADLEN, BADLEN }, "-wp0#", "i", NULL }, 716 /* X/Open conversion specifiers. */ 717 { "C", 0, STD_EXT, { TEX_WI, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN }, "-w", "", NULL }, 718 { "S", 1, STD_EXT, { TEX_W, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN }, "-wp", "R", NULL }, 719 /* GNU conversion specifiers. */ 720 { "m", 0, STD_EXT, { T89_V, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN }, "-wp", "", NULL }, 721 { "B", 0, STD_EXT, { T2X_UI, T2X_UC, T2X_US, T2X_UL, T2X_ULL, TEX_ULL, T2X_ST, T2X_UPD, T2X_UIM, BADLEN, BADLEN, BADLEN }, "-wp0#", "i", NULL }, 722 { NULL, 0, STD_C89, NOLENGTHS, NULL, NULL, NULL } 723 }; 724 725 static const format_char_info asm_fprintf_char_table[] = 726 { 727 /* C89 conversion specifiers. */ 728 { "di", 0, STD_C89, { T89_I, BADLEN, BADLEN, T89_L, T9L_LL, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN }, "-wp0 +", "i", NULL }, 729 { "oxX", 0, STD_C89, { T89_UI, BADLEN, BADLEN, T89_UL, T9L_ULL, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN }, "-wp0#", "i", NULL }, 730 { "u", 0, STD_C89, { T89_UI, BADLEN, BADLEN, T89_UL, T9L_ULL, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN }, "-wp0", "i", NULL }, 731 { "c", 0, STD_C89, { T89_I, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN }, "-w", "", NULL }, 732 { "s", 1, STD_C89, { T89_C, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN }, "-wp", "cR", NULL }, 733 734 /* asm_fprintf conversion specifiers. */ 735 { "O", 0, STD_C89, NOARGUMENTS, "", "", NULL }, 736 { "R", 0, STD_C89, NOARGUMENTS, "", "", NULL }, 737 { "I", 0, STD_C89, NOARGUMENTS, "", "", NULL }, 738 { "L", 0, STD_C89, NOARGUMENTS, "", "", NULL }, 739 { "U", 0, STD_C89, NOARGUMENTS, "", "", NULL }, 740 { "r", 0, STD_C89, { T89_I, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN }, "", "", NULL }, 741 { "z", 0, STD_C89, NOARGUMENTS, "", "", NULL }, 742 { "@", 0, STD_C89, NOARGUMENTS, "", "", NULL }, 743 { NULL, 0, STD_C89, NOLENGTHS, NULL, NULL, NULL } 744 }; 745 746 /* GCC-specific format_char_info arrays. */ 747 748 /* The conversion specifiers implemented within pp_format, and thus supported 749 by all pretty_printer instances within GCC. */ 750 751 #define PP_FORMAT_CHAR_TABLE \ 752 { "di", 0, STD_C89, { T89_I, BADLEN, BADLEN, T89_L, T9L_LL, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN }, "q", "", NULL }, \ 753 { "ox", 0, STD_C89, { T89_UI, BADLEN, BADLEN, T89_UL, T9L_ULL, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN }, "q", "", NULL }, \ 754 { "u", 0, STD_C89, { T89_UI, BADLEN, BADLEN, T89_UL, T9L_ULL, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN }, "q", "", NULL }, \ 755 { "c", 0, STD_C89, { T89_I, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN }, "q", "", NULL }, \ 756 { "s", 1, STD_C89, { T89_C, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN }, "pq", "cR", NULL }, \ 757 { "p", 1, STD_C89, { T89_V, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN }, "q", "c", NULL }, \ 758 { "r", 1, STD_C89, { T89_C, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN }, "", "//cR", NULL }, \ 759 { "@", 1, STD_C89, { T_EVENT_PTR, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN }, "", "\"", NULL }, \ 760 { "<", 0, STD_C89, NOARGUMENTS, "", "<", NULL }, \ 761 { ">", 0, STD_C89, NOARGUMENTS, "", ">", NULL }, \ 762 { "'" , 0, STD_C89, NOARGUMENTS, "", "", NULL }, \ 763 { "{", 1, STD_C89, { T89_C, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN }, "", "cR", NULL }, \ 764 { "}", 0, STD_C89, NOARGUMENTS, "", "", NULL }, \ 765 { "R", 0, STD_C89, NOARGUMENTS, "", "\\", NULL }, \ 766 { "m", 0, STD_C89, NOARGUMENTS, "q", "", NULL }, \ 767 { "Z", 1, STD_C89, { T89_I, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN }, "", "", &gcc_diag_char_table[0] } 768 769 static const format_char_info gcc_diag_char_table[] = 770 { 771 /* The conversion specifiers implemented within pp_format. */ 772 PP_FORMAT_CHAR_TABLE, 773 774 { NULL, 0, STD_C89, NOLENGTHS, NULL, NULL, NULL } 775 }; 776 777 static const format_char_info gcc_tdiag_char_table[] = 778 { 779 /* The conversion specifiers implemented within pp_format. */ 780 PP_FORMAT_CHAR_TABLE, 781 782 /* Custom conversion specifiers implemented by default_tree_printer. */ 783 784 /* These will require a "tree" at runtime. */ 785 { "DFTV", 1, STD_C89, { T89_T, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN }, "q+", "'", NULL }, 786 { "E", 1, STD_C89, { T89_T, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN }, "q+", "", NULL }, 787 788 { NULL, 0, STD_C89, NOLENGTHS, NULL, NULL, NULL } 789 }; 790 791 static const format_char_info gcc_cdiag_char_table[] = 792 { 793 /* The conversion specifiers implemented within pp_format. */ 794 PP_FORMAT_CHAR_TABLE, 795 796 /* Custom conversion specifiers implemented by c_tree_printer. */ 797 798 /* These will require a "tree" at runtime. */ 799 { "DFTV", 1, STD_C89, { T89_T, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN }, "q+", "'", NULL }, 800 { "E", 1, STD_C89, { T89_T, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN }, "q+", "", NULL }, 801 802 { "v", 0, STD_C89, { T89_I, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN }, "q#", "", NULL }, 803 804 { NULL, 0, STD_C89, NOLENGTHS, NULL, NULL, NULL } 805 }; 806 807 static const format_char_info gcc_cxxdiag_char_table[] = 808 { 809 /* The conversion specifiers implemented within pp_format. */ 810 PP_FORMAT_CHAR_TABLE, 811 812 /* Custom conversion specifiers implemented by cp_printer. */ 813 814 /* These will require a "tree" at runtime. */ 815 { "ADFHISTVX",1,STD_C89,{ T89_T, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN }, "q+#", "'", NULL }, 816 { "E", 1,STD_C89,{ T89_T, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN }, "q+#", "", NULL }, 817 818 /* These accept either an 'int' or an 'enum tree_code' (which is handled as an 'int'.) */ 819 { "CLOPQ",0,STD_C89, { T89_I, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN }, "q", "", NULL }, 820 821 { NULL, 0, STD_C89, NOLENGTHS, NULL, NULL, NULL } 822 }; 823 824 static const format_char_info gcc_gfc_char_table[] = 825 { 826 /* C89 conversion specifiers. */ 827 { "di", 0, STD_C89, { T89_I, BADLEN, BADLEN, T89_L, T9L_LL, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN }, "q", "", NULL }, 828 { "u", 0, STD_C89, { T89_UI, BADLEN, BADLEN, T89_UL, T9L_ULL, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN }, "q", "", NULL }, 829 { "c", 0, STD_C89, { T89_I, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN }, "q", "", NULL }, 830 { "s", 1, STD_C89, { T89_C, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN }, "q", "cR", NULL }, 831 832 /* gfc conversion specifiers. */ 833 834 { "C", 0, STD_C89, NOARGUMENTS, "", "", NULL }, 835 836 /* This will require a "locus" at runtime. */ 837 { "L", 0, STD_C89, { T89_V, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN }, "", "R", NULL }, 838 839 /* These will require nothing. */ 840 { "<>",0, STD_C89, NOARGUMENTS, "", "", NULL }, 841 { NULL, 0, STD_C89, NOLENGTHS, NULL, NULL, NULL } 842 }; 843 844 static const format_char_info gcc_dump_printf_char_table[] = 845 { 846 /* The conversion specifiers implemented within pp_format. */ 847 PP_FORMAT_CHAR_TABLE, 848 849 /* Custom conversion specifiers implemented by dump_pretty_printer. */ 850 851 /* E and G require a "gimple *" argument at runtime. */ 852 { "EG", 1, STD_C89, { T89_G, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN }, "", "\"", NULL }, 853 854 /* C requires a "cgraph_node *" argument at runtime. */ 855 { "C", 1, STD_C89, { T_CGRAPH_NODE, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN }, "", "\"", NULL }, 856 857 /* T requires a "tree" at runtime. */ 858 { "T", 1, STD_C89, { T89_T, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN }, "", "\"", NULL }, 859 860 /* %f requires a "double"; it doesn't support modifiers. */ 861 { "f", 0, STD_C89, { T89_D, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN }, "", "\"", NULL }, 862 863 { NULL, 0, STD_C89, NOLENGTHS, NULL, NULL, NULL } 864 }; 865 866 static const format_char_info scan_char_table[] = 867 { 868 /* C89 conversion specifiers. */ 869 { "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 }, 870 { "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 }, 871 { "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 }, 872 { "efgEG", 1, STD_C89, { T89_F, BADLEN, BADLEN, T89_D, BADLEN, T89_LD, BADLEN, BADLEN, BADLEN, T2X_D32, T2X_D64, T2X_D128 }, "*w'", "W", NULL }, 873 { "c", 1, STD_C89, { T89_C, BADLEN, BADLEN, T94_W, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN }, "*mw", "cW", NULL }, 874 { "s", 1, STD_C89, { T89_C, BADLEN, BADLEN, T94_W, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN }, "*amw", "cW", NULL }, 875 { "[", 1, STD_C89, { T89_C, BADLEN, BADLEN, T94_W, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN }, "*amw", "cW[", NULL }, 876 { "p", 2, STD_C89, { T89_V, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN }, "*w", "W", NULL }, 877 { "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 }, 878 /* C99 conversion specifiers. */ 879 { "F", 1, STD_C99, { T99_F, BADLEN, BADLEN, T99_D, BADLEN, T99_LD, BADLEN, BADLEN, BADLEN, T2X_D32, T2X_D64, T2X_D128 }, "*w'", "W", NULL }, 880 { "aA", 1, STD_C99, { T99_F, BADLEN, BADLEN, T99_D, BADLEN, T99_LD, BADLEN, BADLEN, BADLEN, T2X_D32, T2X_D64, T2X_D128 }, "*w'", "W", NULL }, 881 /* C2X conversion specifiers. */ 882 { "b", 1, STD_C2X, { T2X_UI, T2X_UC, T2X_US, T2X_UL, T2X_ULL, TEX_ULL, T2X_ST, T2X_UPD, T2X_UIM, BADLEN, BADLEN, BADLEN }, "*w", "W", NULL }, 883 /* X/Open conversion specifiers. */ 884 { "C", 1, STD_EXT, { TEX_W, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN }, "*mw", "W", NULL }, 885 { "S", 1, STD_EXT, { TEX_W, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN }, "*amw", "W", NULL }, 886 { NULL, 0, STD_C89, NOLENGTHS, NULL, NULL, NULL } 887 }; 888 889 static const format_char_info time_char_table[] = 890 { 891 /* C89 conversion specifiers. */ 892 { "AZa", 0, STD_C89, NOLENGTHS, "^#", "", NULL }, 893 { "Bb", 0, STD_C89, NOLENGTHS, "O^#", "p", NULL }, 894 { "cx", 0, STD_C89, NOLENGTHS, "E", "3", NULL }, 895 { "HIMSUWdmw", 0, STD_C89, NOLENGTHS, "-_0Ow", "", NULL }, 896 { "j", 0, STD_C89, NOLENGTHS, "-_0Ow", "o", NULL }, 897 { "p", 0, STD_C89, NOLENGTHS, "#", "", NULL }, 898 { "X", 0, STD_C89, NOLENGTHS, "E", "", NULL }, 899 { "y", 0, STD_C89, NOLENGTHS, "EO-_0w", "4", NULL }, 900 { "Y", 0, STD_C89, NOLENGTHS, "-_0EOw", "o", NULL }, 901 { "%", 0, STD_C89, NOLENGTHS, "", "", NULL }, 902 /* C99 conversion specifiers. */ 903 { "C", 0, STD_C99, NOLENGTHS, "-_0EOw", "o", NULL }, 904 { "D", 0, STD_C99, NOLENGTHS, "", "2", NULL }, 905 { "eVu", 0, STD_C99, NOLENGTHS, "-_0Ow", "", NULL }, 906 { "FRTnrt", 0, STD_C99, NOLENGTHS, "", "", NULL }, 907 { "g", 0, STD_C99, NOLENGTHS, "O-_0w", "2o", NULL }, 908 { "G", 0, STD_C99, NOLENGTHS, "-_0Ow", "o", NULL }, 909 { "h", 0, STD_C99, NOLENGTHS, "^#", "", NULL }, 910 { "z", 0, STD_C99, NOLENGTHS, "O", "o", NULL }, 911 /* GNU conversion specifiers. */ 912 { "kls", 0, STD_EXT, NOLENGTHS, "-_0Ow", "", NULL }, 913 { "P", 0, STD_EXT, NOLENGTHS, "", "", NULL }, 914 { NULL, 0, STD_C89, NOLENGTHS, NULL, NULL, NULL } 915 }; 916 917 static const format_char_info monetary_char_table[] = 918 { 919 { "in", 0, STD_C89, { T89_D, BADLEN, BADLEN, BADLEN, BADLEN, T89_LD, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN }, "=^+(!-w#p", "", NULL }, 920 { NULL, 0, STD_C89, NOLENGTHS, NULL, NULL, NULL } 921 }; 922 923 /* This must be in the same order as enum format_type. */ 924 static const format_kind_info format_types_orig[] = 925 { 926 { "gnu_printf", printf_length_specs, print_char_table, " +#0-'I", NULL, 927 printf_flag_specs, printf_flag_pairs, 928 FMT_FLAG_ARG_CONVERT|FMT_FLAG_DOLLAR_MULTIPLE|FMT_FLAG_USE_DOLLAR|FMT_FLAG_EMPTY_PREC_OK, 929 'w', 0, 'p', 0, 'L', 0, 930 &integer_type_node, &integer_type_node, format_type_error 931 }, 932 { "asm_fprintf", asm_fprintf_length_specs, asm_fprintf_char_table, " +#0-", NULL, 933 asm_fprintf_flag_specs, asm_fprintf_flag_pairs, 934 FMT_FLAG_ARG_CONVERT|FMT_FLAG_EMPTY_PREC_OK, 935 'w', 0, 'p', 0, 'L', 0, 936 NULL, NULL, format_type_error 937 }, 938 { "gcc_diag", gcc_diag_length_specs, gcc_diag_char_table, "q+#", NULL, 939 gcc_diag_flag_specs, gcc_diag_flag_pairs, 940 FMT_FLAG_ARG_CONVERT|FMT_FLAG_M_OK, 941 0, 0, 'p', 0, 'L', 0, 942 NULL, &integer_type_node, format_type_error 943 }, 944 { "gcc_tdiag", gcc_tdiag_length_specs, gcc_tdiag_char_table, "q+#", NULL, 945 gcc_tdiag_flag_specs, gcc_tdiag_flag_pairs, 946 FMT_FLAG_ARG_CONVERT|FMT_FLAG_M_OK, 947 0, 0, 'p', 0, 'L', 0, 948 NULL, &integer_type_node, format_type_error 949 }, 950 { "gcc_cdiag", gcc_cdiag_length_specs, gcc_cdiag_char_table, "q+#", NULL, 951 gcc_cdiag_flag_specs, gcc_cdiag_flag_pairs, 952 FMT_FLAG_ARG_CONVERT|FMT_FLAG_M_OK, 953 0, 0, 'p', 0, 'L', 0, 954 NULL, &integer_type_node, format_type_error 955 }, 956 { "gcc_cxxdiag", gcc_cxxdiag_length_specs, gcc_cxxdiag_char_table, "q+#", NULL, 957 gcc_cxxdiag_flag_specs, gcc_cxxdiag_flag_pairs, 958 FMT_FLAG_ARG_CONVERT|FMT_FLAG_M_OK, 959 0, 0, 'p', 0, 'L', 0, 960 NULL, &integer_type_node, format_type_error 961 }, 962 { "gcc_gfc", gcc_gfc_length_specs, gcc_gfc_char_table, "q+#", NULL, 963 gcc_gfc_flag_specs, gcc_gfc_flag_pairs, 964 FMT_FLAG_ARG_CONVERT|FMT_FLAG_M_OK, 965 0, 0, 0, 0, 0, 0, 966 NULL, NULL, format_type_error 967 }, 968 { "gcc_dump_printf", gcc_dump_printf_length_specs, 969 gcc_dump_printf_char_table, "q+#", NULL, 970 gcc_dump_printf_flag_specs, gcc_dump_printf_flag_pairs, 971 FMT_FLAG_ARG_CONVERT, 972 0, 0, 'p', 0, 'L', 0, 973 NULL, &integer_type_node 974 }, 975 { "NSString", NULL, NULL, NULL, NULL, 976 NULL, NULL, 977 FMT_FLAG_ARG_CONVERT|FMT_FLAG_PARSE_ARG_CONVERT_EXTERNAL, 0, 0, 0, 0, 0, 0, 978 NULL, NULL, format_type_error 979 }, 980 { "gnu_scanf", scanf_length_specs, scan_char_table, "*'I", NULL, 981 scanf_flag_specs, scanf_flag_pairs, 982 FMT_FLAG_ARG_CONVERT|FMT_FLAG_SCANF_A_KLUDGE|FMT_FLAG_USE_DOLLAR|FMT_FLAG_ZERO_WIDTH_BAD|FMT_FLAG_DOLLAR_GAP_POINTER_OK, 983 'w', 0, 0, '*', 'L', 'm', 984 NULL, NULL, format_type_error 985 }, 986 { "gnu_strftime", NULL, time_char_table, "_-0^#", "EO", 987 strftime_flag_specs, strftime_flag_pairs, 988 FMT_FLAG_FANCY_PERCENT_OK|FMT_FLAG_M_OK, 'w', 0, 0, 0, 0, 0, 989 NULL, NULL, format_type_error 990 }, 991 { "gnu_strfmon", strfmon_length_specs, monetary_char_table, "=^+(!-", NULL, 992 strfmon_flag_specs, strfmon_flag_pairs, 993 FMT_FLAG_ARG_CONVERT, 'w', '#', 'p', 0, 'L', 0, 994 NULL, NULL, format_type_error 995 }, 996 { "gnu_syslog", printf_length_specs, print_char_table, " +#0-'I", NULL, 997 printf_flag_specs, printf_flag_pairs, 998 FMT_FLAG_ARG_CONVERT|FMT_FLAG_DOLLAR_MULTIPLE|FMT_FLAG_USE_DOLLAR|FMT_FLAG_EMPTY_PREC_OK|FMT_FLAG_M_OK, 999 'w', 0, 'p', 0, 'L', 0, 1000 &integer_type_node, &integer_type_node, printf_format_type 1001 }, 1002 }; 1003 1004 /* This layer of indirection allows GCC to reassign format_types with 1005 new data if necessary, while still allowing the original data to be 1006 const. */ 1007 static const format_kind_info *format_types = format_types_orig; 1008 /* We can modify this one. We also add target-specific format types 1009 to the end of the array. */ 1010 static format_kind_info *dynamic_format_types; 1011 1012 static int n_format_types = ARRAY_SIZE (format_types_orig); 1013 1014 /* Structure detailing the results of checking a format function call 1015 where the format expression may be a conditional expression with 1016 many leaves resulting from nested conditional expressions. */ 1017 struct format_check_results 1018 { 1019 /* Number of leaves of the format argument that could not be checked 1020 as they were not string literals. */ 1021 int number_non_literal; 1022 /* Number of leaves of the format argument that were null pointers or 1023 string literals, but had extra format arguments. */ 1024 int number_extra_args; 1025 location_t extra_arg_loc; 1026 /* Number of leaves of the format argument that were null pointers or 1027 string literals, but had extra format arguments and used $ operand 1028 numbers. */ 1029 int number_dollar_extra_args; 1030 /* Number of leaves of the format argument that were wide string 1031 literals. */ 1032 int number_wide; 1033 /* Number of leaves of the format argument that are not array of "char". */ 1034 int number_non_char; 1035 /* Number of leaves of the format argument that were empty strings. */ 1036 int number_empty; 1037 /* Number of leaves of the format argument that were unterminated 1038 strings. */ 1039 int number_unterminated; 1040 /* Number of leaves of the format argument that were not counted above. */ 1041 int number_other; 1042 /* Location of the format string. */ 1043 location_t format_string_loc; 1044 }; 1045 1046 struct format_check_context 1047 { 1048 format_check_results *res; 1049 function_format_info *info; 1050 tree params; 1051 vec<location_t> *arglocs; 1052 }; 1053 1054 /* Return the format name (as specified in the original table) for the format 1055 type indicated by format_num. */ 1056 static const char * 1057 format_name (int format_num) 1058 { 1059 if (format_num >= 0 && format_num < n_format_types) 1060 return format_types[format_num].name; 1061 gcc_unreachable (); 1062 } 1063 1064 /* Return the format flags (as specified in the original table) for the format 1065 type indicated by format_num. */ 1066 static int 1067 format_flags (int format_num) 1068 { 1069 if (format_num >= 0 && format_num < n_format_types) 1070 return format_types[format_num].flags; 1071 gcc_unreachable (); 1072 } 1073 1074 static void check_format_info (function_format_info *, tree, 1075 vec<location_t> *); 1076 static void check_format_arg (void *, tree, unsigned HOST_WIDE_INT); 1077 static void check_format_info_main (format_check_results *, 1078 function_format_info *, const char *, 1079 location_t, tree, 1080 int, tree, 1081 unsigned HOST_WIDE_INT, 1082 object_allocator<format_wanted_type> &, 1083 vec<location_t> *); 1084 1085 static void init_dollar_format_checking (int, tree); 1086 static int maybe_read_dollar_number (const char **, int, 1087 tree, tree *, const format_kind_info *); 1088 static bool avoid_dollar_number (const char *); 1089 static void finish_dollar_format_checking (format_check_results *, int); 1090 1091 static const format_flag_spec *get_flag_spec (const format_flag_spec *, 1092 int, const char *); 1093 1094 static void check_format_types (const substring_loc &fmt_loc, 1095 format_wanted_type *, 1096 const format_kind_info *fki, 1097 int offset_to_type_start, 1098 char conversion_char, 1099 vec<location_t> *arglocs); 1100 static void format_type_warning (const substring_loc &fmt_loc, 1101 location_t param_loc, 1102 format_wanted_type *, tree, 1103 tree, 1104 const format_kind_info *fki, 1105 int offset_to_type_start, 1106 char conversion_char); 1107 1108 /* Decode a format type from a string, returning the type, or 1109 format_type_error if not valid, in which case the caller should 1110 print an error message. On success, when IS_RAW is non-null, set 1111 *IS_RAW when the format type corresponds to a GCC "raw" diagnostic 1112 formatting function and clear it otherwise. */ 1113 static format_type 1114 decode_format_type (const char *s, bool *is_raw /* = NULL */) 1115 { 1116 bool is_raw_buf; 1117 1118 if (!is_raw) 1119 is_raw = &is_raw_buf; 1120 1121 *is_raw = false; 1122 1123 s = convert_format_name_to_system_name (s); 1124 1125 size_t slen = strlen (s); 1126 for (int i = 0; i < n_format_types; i++) 1127 { 1128 /* Check for a match with no underscores. */ 1129 if (!strcmp (s, format_types[i].name)) 1130 return static_cast<format_type> (i); 1131 1132 /* Check for leading and trailing underscores. */ 1133 size_t alen = strlen (format_types[i].name); 1134 if (slen == alen + 4 && s[0] == '_' && s[1] == '_' 1135 && s[slen - 1] == '_' && s[slen - 2] == '_' 1136 && !strncmp (s + 2, format_types[i].name, alen)) 1137 return static_cast<format_type>(i); 1138 1139 /* Check for the "_raw" suffix and no leading underscores. */ 1140 if (slen == alen + 4 1141 && !strncmp (s, format_types[i].name, alen) 1142 && !strcmp (s + alen, "_raw")) 1143 { 1144 *is_raw = true; 1145 return static_cast<format_type>(i); 1146 } 1147 1148 /* Check for the "_raw__" suffix and leading underscores. */ 1149 if (slen == alen + 8 && s[0] == '_' && s[1] == '_' 1150 && !strncmp (s + 2, format_types[i].name, alen) 1151 && !strcmp (s + 2 + alen, "_raw__")) 1152 { 1153 *is_raw = true; 1154 return static_cast<format_type>(i); 1155 } 1156 } 1157 1158 return format_type_error; 1159 } 1160 1161 1162 /* Check the argument list of a call to printf, scanf, etc. 1164 ATTRS are the attributes on the function type. There are NARGS argument 1165 values in the array ARGARRAY. 1166 Also, if -Wsuggest-attribute=format, 1167 warn for calls to vprintf or vscanf in functions with no such format 1168 attribute themselves. */ 1169 1170 void 1171 check_function_format (const_tree fntype, tree attrs, int nargs, 1172 tree *argarray, vec<location_t> *arglocs) 1173 { 1174 tree a; 1175 1176 tree atname = get_identifier ("format"); 1177 1178 /* See if this function has any format attributes. */ 1179 for (a = attrs; a; a = TREE_CHAIN (a)) 1180 { 1181 if (is_attribute_p ("format", get_attribute_name (a))) 1182 { 1183 /* Yup; check it. */ 1184 function_format_info info; 1185 decode_format_attr (fntype, atname, TREE_VALUE (a), &info, 1186 /*validated=*/true); 1187 if (warn_format) 1188 { 1189 /* FIXME: Rewrite all the internal functions in this file 1190 to use the ARGARRAY directly instead of constructing this 1191 temporary list. */ 1192 tree params = NULL_TREE; 1193 int i; 1194 for (i = nargs - 1; i >= 0; i--) 1195 params = tree_cons (NULL_TREE, argarray[i], params); 1196 check_format_info (&info, params, arglocs); 1197 } 1198 const format_kind_info *fi = &format_types[info.format_type]; 1199 1200 /* Attempt to detect whether the current function might benefit 1201 from the format attribute if the called function is decorated 1202 with it. Avoid using calls with string literal formats for 1203 guidance since those are unlikely to be viable candidates. */ 1204 if (warn_suggest_attribute_format 1205 && current_function_decl != NULL_TREE 1206 && info.first_arg_num == 0 1207 && (fi->flags & (int) FMT_FLAG_ARG_CONVERT) 1208 /* c_strlen will fail for a function parameter but succeed 1209 for a literal or constant array. */ 1210 && !c_strlen (argarray[info.format_num - 1], 1)) 1211 { 1212 tree c; 1213 for (c = TYPE_ATTRIBUTES (TREE_TYPE (current_function_decl)); 1214 c; 1215 c = TREE_CHAIN (c)) 1216 { 1217 if (!is_attribute_p ("format", TREE_PURPOSE (c))) 1218 continue; 1219 int format_type = decode_format_type ( 1220 IDENTIFIER_POINTER (TREE_VALUE (TREE_VALUE (c)))); 1221 if (format_type == format_type_error) 1222 continue; 1223 if (format_type == info.format_type || 1224 format_type == fi->parent_format_type) 1225 break; 1226 } 1227 if (c == NULL_TREE) 1228 { 1229 /* Check if the current function has a parameter to which 1230 the format attribute could be attached; if not, it 1231 can't be a candidate for a format attribute, despite 1232 the vprintf-like or vscanf-like call. */ 1233 tree args; 1234 for (args = DECL_ARGUMENTS (current_function_decl); 1235 args != 0; 1236 args = DECL_CHAIN (args)) 1237 { 1238 if (TREE_CODE (TREE_TYPE (args)) == POINTER_TYPE 1239 && (TYPE_MAIN_VARIANT (TREE_TYPE (TREE_TYPE (args))) 1240 == char_type_node)) 1241 break; 1242 } 1243 if (args != 0) 1244 warning (OPT_Wsuggest_attribute_format, "function %qD " 1245 "might be a candidate for %qs format attribute", 1246 current_function_decl, 1247 format_types[info.format_type].name); 1248 } 1249 } 1250 } 1251 } 1252 } 1253 1254 1255 /* Variables used by the checking of $ operand number formats. */ 1256 static char *dollar_arguments_used = NULL; 1257 static char *dollar_arguments_pointer_p = NULL; 1258 static int dollar_arguments_alloc = 0; 1259 static int dollar_arguments_count; 1260 static int dollar_first_arg_num; 1261 static int dollar_max_arg_used; 1262 static int dollar_format_warned; 1263 1264 /* Initialize the checking for a format string that may contain $ 1265 parameter number specifications; we will need to keep track of whether 1266 each parameter has been used. FIRST_ARG_NUM is the number of the first 1267 argument that is a parameter to the format, or 0 for a vprintf-style 1268 function; PARAMS is the list of arguments starting at this argument. */ 1269 1270 static void 1271 init_dollar_format_checking (int first_arg_num, tree params) 1272 { 1273 tree oparams = params; 1274 1275 dollar_first_arg_num = first_arg_num; 1276 dollar_arguments_count = 0; 1277 dollar_max_arg_used = 0; 1278 dollar_format_warned = 0; 1279 if (first_arg_num > 0) 1280 { 1281 while (params) 1282 { 1283 dollar_arguments_count++; 1284 params = TREE_CHAIN (params); 1285 } 1286 } 1287 if (dollar_arguments_alloc < dollar_arguments_count) 1288 { 1289 free (dollar_arguments_used); 1290 free (dollar_arguments_pointer_p); 1291 dollar_arguments_alloc = dollar_arguments_count; 1292 dollar_arguments_used = XNEWVEC (char, dollar_arguments_alloc); 1293 dollar_arguments_pointer_p = XNEWVEC (char, dollar_arguments_alloc); 1294 } 1295 if (dollar_arguments_alloc) 1296 { 1297 memset (dollar_arguments_used, 0, dollar_arguments_alloc); 1298 if (first_arg_num > 0) 1299 { 1300 int i = 0; 1301 params = oparams; 1302 while (params) 1303 { 1304 dollar_arguments_pointer_p[i] = (TREE_CODE (TREE_TYPE (TREE_VALUE (params))) 1305 == POINTER_TYPE); 1306 params = TREE_CHAIN (params); 1307 i++; 1308 } 1309 } 1310 } 1311 } 1312 1313 1314 /* Look for a decimal number followed by a $ in *FORMAT. If DOLLAR_NEEDED 1315 is set, it is an error if one is not found; otherwise, it is OK. If 1316 such a number is found, check whether it is within range and mark that 1317 numbered operand as being used for later checking. Returns the operand 1318 number if found and within range, zero if no such number was found and 1319 this is OK, or -1 on error. PARAMS points to the first operand of the 1320 format; PARAM_PTR is made to point to the parameter referred to. If 1321 a $ format is found, *FORMAT is updated to point just after it. */ 1322 1323 static int 1324 maybe_read_dollar_number (const char **format, 1325 int dollar_needed, tree params, tree *param_ptr, 1326 const format_kind_info *fki) 1327 { 1328 int argnum; 1329 int overflow_flag; 1330 const char *fcp = *format; 1331 if (!ISDIGIT (*fcp)) 1332 { 1333 if (dollar_needed) 1334 { 1335 warning (OPT_Wformat_, "missing $ operand number in format"); 1336 return -1; 1337 } 1338 else 1339 return 0; 1340 } 1341 argnum = 0; 1342 overflow_flag = 0; 1343 while (ISDIGIT (*fcp)) 1344 { 1345 HOST_WIDE_INT nargnum 1346 = HOST_WIDE_INT_UC (10) * argnum + (*fcp - '0'); 1347 if ((int) nargnum != nargnum) 1348 overflow_flag = 1; 1349 argnum = nargnum; 1350 fcp++; 1351 } 1352 if (*fcp != '$') 1353 { 1354 if (dollar_needed) 1355 { 1356 warning (OPT_Wformat_, "missing $ operand number in format"); 1357 return -1; 1358 } 1359 else 1360 return 0; 1361 } 1362 *format = fcp + 1; 1363 if (pedantic && !dollar_format_warned) 1364 { 1365 warning (OPT_Wformat_, "%s does not support %%n$ operand number formats", 1366 C_STD_NAME (STD_EXT)); 1367 dollar_format_warned = 1; 1368 } 1369 if (overflow_flag || argnum == 0 1370 || (dollar_first_arg_num && argnum > dollar_arguments_count)) 1371 { 1372 warning (OPT_Wformat_, "operand number out of range in format"); 1373 return -1; 1374 } 1375 if (argnum > dollar_max_arg_used) 1376 dollar_max_arg_used = argnum; 1377 /* For vprintf-style functions we may need to allocate more memory to 1378 track which arguments are used. */ 1379 while (dollar_arguments_alloc < dollar_max_arg_used) 1380 { 1381 int nalloc; 1382 nalloc = 2 * dollar_arguments_alloc + 16; 1383 dollar_arguments_used = XRESIZEVEC (char, dollar_arguments_used, 1384 nalloc); 1385 dollar_arguments_pointer_p = XRESIZEVEC (char, dollar_arguments_pointer_p, 1386 nalloc); 1387 memset (dollar_arguments_used + dollar_arguments_alloc, 0, 1388 nalloc - dollar_arguments_alloc); 1389 dollar_arguments_alloc = nalloc; 1390 } 1391 if (!(fki->flags & (int) FMT_FLAG_DOLLAR_MULTIPLE) 1392 && dollar_arguments_used[argnum - 1] == 1) 1393 { 1394 dollar_arguments_used[argnum - 1] = 2; 1395 warning (OPT_Wformat_, "format argument %d used more than once in %s format", 1396 argnum, fki->name); 1397 } 1398 else 1399 dollar_arguments_used[argnum - 1] = 1; 1400 if (dollar_first_arg_num) 1401 { 1402 int i; 1403 *param_ptr = params; 1404 for (i = 1; i < argnum && *param_ptr != 0; i++) 1405 *param_ptr = TREE_CHAIN (*param_ptr); 1406 1407 /* This case shouldn't be caught here. */ 1408 gcc_assert (*param_ptr); 1409 } 1410 else 1411 *param_ptr = 0; 1412 return argnum; 1413 } 1414 1415 /* Ensure that FORMAT does not start with a decimal number followed by 1416 a $; give a diagnostic and return true if it does, false otherwise. */ 1417 1418 static bool 1419 avoid_dollar_number (const char *format) 1420 { 1421 if (!ISDIGIT (*format)) 1422 return false; 1423 while (ISDIGIT (*format)) 1424 format++; 1425 if (*format == '$') 1426 { 1427 warning (OPT_Wformat_, 1428 "%<$%>operand number used after format without operand number"); 1429 return true; 1430 } 1431 return false; 1432 } 1433 1434 1435 /* Finish the checking for a format string that used $ operand number formats 1436 instead of non-$ formats. We check for unused operands before used ones 1437 (a serious error, since the implementation of the format function 1438 can't know what types to pass to va_arg to find the later arguments). 1439 and for unused operands at the end of the format (if we know how many 1440 arguments the format had, so not for vprintf). If there were operand 1441 numbers out of range on a non-vprintf-style format, we won't have reached 1442 here. If POINTER_GAP_OK, unused arguments are OK if all arguments are 1443 pointers. */ 1444 1445 static void 1446 finish_dollar_format_checking (format_check_results *res, int pointer_gap_ok) 1447 { 1448 int i; 1449 bool found_pointer_gap = false; 1450 for (i = 0; i < dollar_max_arg_used; i++) 1451 { 1452 if (!dollar_arguments_used[i]) 1453 { 1454 if (pointer_gap_ok && (dollar_first_arg_num == 0 1455 || dollar_arguments_pointer_p[i])) 1456 found_pointer_gap = true; 1457 else 1458 warning_at (res->format_string_loc, OPT_Wformat_, 1459 "format argument %d unused before used argument %d " 1460 "in %<$%>-style format", 1461 i + 1, dollar_max_arg_used); 1462 } 1463 } 1464 if (found_pointer_gap 1465 || (dollar_first_arg_num 1466 && dollar_max_arg_used < dollar_arguments_count)) 1467 { 1468 res->number_other--; 1469 res->number_dollar_extra_args++; 1470 } 1471 } 1472 1473 1474 /* Retrieve the specification for a format flag. SPEC contains the 1475 specifications for format flags for the applicable kind of format. 1476 FLAG is the flag in question. If PREDICATES is NULL, the basic 1477 spec for that flag must be retrieved and must exist. If 1478 PREDICATES is not NULL, it is a string listing possible predicates 1479 for the spec entry; if an entry predicated on any of these is 1480 found, it is returned, otherwise NULL is returned. */ 1481 1482 static const format_flag_spec * 1483 get_flag_spec (const format_flag_spec *spec, int flag, const char *predicates) 1484 { 1485 int i; 1486 for (i = 0; spec[i].flag_char != 0; i++) 1487 { 1488 if (spec[i].flag_char != flag) 1489 continue; 1490 if (predicates != NULL) 1491 { 1492 if (spec[i].predicate != 0 1493 && strchr (predicates, spec[i].predicate) != 0) 1494 return &spec[i]; 1495 } 1496 else if (spec[i].predicate == 0) 1497 return &spec[i]; 1498 } 1499 gcc_assert (predicates); 1500 return NULL; 1501 } 1502 1503 1504 /* Check the argument list of a call to printf, scanf, etc. 1505 INFO points to the function_format_info structure. 1506 PARAMS is the list of argument values. */ 1507 1508 static void 1509 check_format_info (function_format_info *info, tree params, 1510 vec<location_t> *arglocs) 1511 { 1512 format_check_context format_ctx; 1513 unsigned HOST_WIDE_INT arg_num; 1514 tree format_tree; 1515 format_check_results res; 1516 /* Skip to format argument. If the argument isn't available, there's 1517 no work for us to do; prototype checking will catch the problem. */ 1518 for (arg_num = 1; ; ++arg_num) 1519 { 1520 if (params == 0) 1521 return; 1522 if (arg_num == info->format_num) 1523 break; 1524 params = TREE_CHAIN (params); 1525 } 1526 format_tree = TREE_VALUE (params); 1527 params = TREE_CHAIN (params); 1528 if (format_tree == 0) 1529 return; 1530 1531 res.number_non_literal = 0; 1532 res.number_extra_args = 0; 1533 res.extra_arg_loc = UNKNOWN_LOCATION; 1534 res.number_dollar_extra_args = 0; 1535 res.number_wide = 0; 1536 res.number_non_char = 0; 1537 res.number_empty = 0; 1538 res.number_unterminated = 0; 1539 res.number_other = 0; 1540 res.format_string_loc = input_location; 1541 1542 format_ctx.res = &res; 1543 format_ctx.info = info; 1544 format_ctx.params = params; 1545 format_ctx.arglocs = arglocs; 1546 1547 check_function_arguments_recurse (check_format_arg, &format_ctx, 1548 format_tree, arg_num, OPT_Wformat_); 1549 1550 location_t loc = format_ctx.res->format_string_loc; 1551 1552 if (res.number_non_literal > 0) 1553 { 1554 /* Functions taking a va_list normally pass a non-literal format 1555 string. These functions typically are declared with 1556 first_arg_num == 0, so avoid warning in those cases. */ 1557 if (!(format_types[info->format_type].flags & (int) FMT_FLAG_ARG_CONVERT)) 1558 { 1559 /* For strftime-like formats, warn for not checking the format 1560 string; but there are no arguments to check. */ 1561 warning_at (loc, OPT_Wformat_nonliteral, 1562 "format not a string literal, format string not checked"); 1563 } 1564 else if (info->first_arg_num != 0) 1565 { 1566 /* If there are no arguments for the format at all, we may have 1567 printf (foo) which is likely to be a security hole. */ 1568 while (arg_num + 1 < info->first_arg_num) 1569 { 1570 if (params == 0) 1571 break; 1572 params = TREE_CHAIN (params); 1573 ++arg_num; 1574 } 1575 if (params == 0 && warn_format_security) 1576 warning_at (loc, OPT_Wformat_security, 1577 "format not a string literal and no format arguments"); 1578 else if (params == 0 && warn_format_nonliteral) 1579 warning_at (loc, OPT_Wformat_nonliteral, 1580 "format not a string literal and no format arguments"); 1581 else 1582 warning_at (loc, OPT_Wformat_nonliteral, 1583 "format not a string literal, argument types not checked"); 1584 } 1585 } 1586 1587 /* If there were extra arguments to the format, normally warn. However, 1588 the standard does say extra arguments are ignored, so in the specific 1589 case where we have multiple leaves (conditional expressions or 1590 ngettext) allow extra arguments if at least one leaf didn't have extra 1591 arguments, but was otherwise OK (either non-literal or checked OK). 1592 If the format is an empty string, this should be counted similarly to the 1593 case of extra format arguments. */ 1594 if (res.number_extra_args > 0 && res.number_non_literal == 0 1595 && res.number_other == 0) 1596 { 1597 if (res.extra_arg_loc == UNKNOWN_LOCATION) 1598 res.extra_arg_loc = loc; 1599 warning_at (res.extra_arg_loc, OPT_Wformat_extra_args, 1600 "too many arguments for format"); 1601 } 1602 if (res.number_dollar_extra_args > 0 && res.number_non_literal == 0 1603 && res.number_other == 0) 1604 warning_at (loc, OPT_Wformat_extra_args, 1605 "unused arguments in %<$%>-style format"); 1606 if (res.number_empty > 0 && res.number_non_literal == 0 1607 && res.number_other == 0) 1608 warning_at (loc, OPT_Wformat_zero_length, "zero-length %s format string", 1609 format_types[info->format_type].name); 1610 1611 if (res.number_wide > 0) 1612 warning_at (loc, OPT_Wformat_, "format is a wide character string"); 1613 1614 if (res.number_non_char > 0) 1615 warning_at (loc, OPT_Wformat_, 1616 "format string is not an array of type %qs", "char"); 1617 1618 if (res.number_unterminated > 0) 1619 warning_at (loc, OPT_Wformat_, "unterminated format string"); 1620 } 1621 1622 /* Callback from check_function_arguments_recurse to check a 1623 format string. FORMAT_TREE is the format parameter. ARG_NUM 1624 is the number of the format argument. CTX points to a 1625 format_check_context. */ 1626 1627 static void 1628 check_format_arg (void *ctx, tree format_tree, 1629 unsigned HOST_WIDE_INT arg_num) 1630 { 1631 format_check_context *format_ctx = (format_check_context *) ctx; 1632 format_check_results *res = format_ctx->res; 1633 function_format_info *info = format_ctx->info; 1634 tree params = format_ctx->params; 1635 vec<location_t> *arglocs = format_ctx->arglocs; 1636 1637 int format_length; 1638 HOST_WIDE_INT offset; 1639 const char *format_chars; 1640 tree array_size = 0; 1641 tree array_init; 1642 1643 location_t fmt_param_loc = EXPR_LOC_OR_LOC (format_tree, input_location); 1644 1645 /* Pull out a constant value if the front end didn't, and handle location 1646 wrappers. */ 1647 format_tree = fold_for_warn (format_tree); 1648 STRIP_NOPS (format_tree); 1649 1650 if (integer_zerop (format_tree)) 1651 { 1652 /* Skip to first argument to check, so we can see if this format 1653 has any arguments (it shouldn't). */ 1654 while (arg_num + 1 < info->first_arg_num) 1655 { 1656 if (params == 0) 1657 return; 1658 params = TREE_CHAIN (params); 1659 ++arg_num; 1660 } 1661 1662 if (params == 0) 1663 res->number_other++; 1664 else 1665 { 1666 if (res->number_extra_args == 0) 1667 res->extra_arg_loc = EXPR_LOC_OR_LOC (TREE_VALUE (params), 1668 input_location); 1669 res->number_extra_args++; 1670 } 1671 return; 1672 } 1673 1674 offset = 0; 1675 if (TREE_CODE (format_tree) == POINTER_PLUS_EXPR) 1676 { 1677 tree arg0, arg1; 1678 1679 arg0 = TREE_OPERAND (format_tree, 0); 1680 arg1 = TREE_OPERAND (format_tree, 1); 1681 STRIP_NOPS (arg0); 1682 STRIP_NOPS (arg1); 1683 if (TREE_CODE (arg1) == INTEGER_CST) 1684 format_tree = arg0; 1685 else 1686 { 1687 res->number_non_literal++; 1688 return; 1689 } 1690 /* POINTER_PLUS_EXPR offsets are to be interpreted signed. */ 1691 if (!cst_and_fits_in_hwi (arg1)) 1692 { 1693 res->number_non_literal++; 1694 return; 1695 } 1696 offset = int_cst_value (arg1); 1697 } 1698 if (TREE_CODE (format_tree) != ADDR_EXPR) 1699 { 1700 res->number_non_literal++; 1701 return; 1702 } 1703 res->format_string_loc = EXPR_LOC_OR_LOC (format_tree, input_location); 1704 format_tree = TREE_OPERAND (format_tree, 0); 1705 if (format_types[info->format_type].flags 1706 & (int) FMT_FLAG_PARSE_ARG_CONVERT_EXTERNAL) 1707 { 1708 bool objc_str = (info->format_type == gcc_objc_string_format_type); 1709 /* We cannot examine this string here - but we can check that it is 1710 a valid type. */ 1711 if (TREE_CODE (format_tree) != CONST_DECL 1712 || !((objc_str && objc_string_ref_type_p (TREE_TYPE (format_tree))) 1713 || (*targetcm.string_object_ref_type_p) 1714 ((const_tree) TREE_TYPE (format_tree)))) 1715 { 1716 res->number_non_literal++; 1717 return; 1718 } 1719 /* Skip to first argument to check. */ 1720 while (arg_num + 1 < info->first_arg_num) 1721 { 1722 if (params == 0) 1723 return; 1724 params = TREE_CHAIN (params); 1725 ++arg_num; 1726 } 1727 /* So, we have a valid literal string object and one or more params. 1728 We need to use an external helper to parse the string into format 1729 info. For Objective-C variants we provide the resource within the 1730 objc tree, for target variants, via a hook. */ 1731 if (objc_str) 1732 objc_check_format_arg (format_tree, params); 1733 else if (targetcm.check_string_object_format_arg) 1734 (*targetcm.check_string_object_format_arg) (format_tree, params); 1735 /* Else we can't handle it and retire quietly. */ 1736 return; 1737 } 1738 if (TREE_CODE (format_tree) == ARRAY_REF 1739 && tree_fits_shwi_p (TREE_OPERAND (format_tree, 1)) 1740 && (offset += tree_to_shwi (TREE_OPERAND (format_tree, 1))) >= 0) 1741 format_tree = TREE_OPERAND (format_tree, 0); 1742 if (offset < 0) 1743 { 1744 res->number_non_literal++; 1745 return; 1746 } 1747 if (VAR_P (format_tree) 1748 && TREE_CODE (TREE_TYPE (format_tree)) == ARRAY_TYPE 1749 && (array_init = decl_constant_value (format_tree)) != format_tree 1750 && TREE_CODE (array_init) == STRING_CST) 1751 { 1752 /* Extract the string constant initializer. Note that this may include 1753 a trailing NUL character that is not in the array (e.g. 1754 const char a[3] = "foo";). */ 1755 array_size = DECL_SIZE_UNIT (format_tree); 1756 format_tree = array_init; 1757 } 1758 if (TREE_CODE (format_tree) != STRING_CST) 1759 { 1760 res->number_non_literal++; 1761 return; 1762 } 1763 tree underlying_type 1764 = TYPE_MAIN_VARIANT (TREE_TYPE (TREE_TYPE (format_tree))); 1765 if (underlying_type != char_type_node 1766 && !(flag_char8_t && underlying_type == char8_type_node)) 1767 { 1768 if (underlying_type == char16_type_node 1769 || underlying_type == char32_type_node 1770 || underlying_type == wchar_type_node) 1771 res->number_wide++; 1772 else 1773 res->number_non_char++; 1774 return; 1775 } 1776 format_chars = TREE_STRING_POINTER (format_tree); 1777 format_length = TREE_STRING_LENGTH (format_tree); 1778 if (array_size != 0) 1779 { 1780 /* Variable length arrays can't be initialized. */ 1781 gcc_assert (TREE_CODE (array_size) == INTEGER_CST); 1782 1783 if (tree_fits_shwi_p (array_size)) 1784 { 1785 HOST_WIDE_INT array_size_value = tree_to_shwi (array_size); 1786 if (array_size_value > 0 1787 && array_size_value == (int) array_size_value 1788 && format_length > array_size_value) 1789 format_length = array_size_value; 1790 } 1791 } 1792 if (offset) 1793 { 1794 if (offset >= format_length) 1795 { 1796 res->number_non_literal++; 1797 return; 1798 } 1799 format_chars += offset; 1800 format_length -= offset; 1801 } 1802 if (format_length < 1 || format_chars[--format_length] != 0) 1803 { 1804 res->number_unterminated++; 1805 return; 1806 } 1807 if (format_length == 0) 1808 { 1809 res->number_empty++; 1810 return; 1811 } 1812 1813 /* Skip to first argument to check. */ 1814 while (arg_num + 1 < info->first_arg_num) 1815 { 1816 if (params == 0) 1817 return; 1818 params = TREE_CHAIN (params); 1819 ++arg_num; 1820 } 1821 /* Provisionally increment res->number_other; check_format_info_main 1822 will decrement it if it finds there are extra arguments, but this way 1823 need not adjust it for every return. */ 1824 res->number_other++; 1825 object_allocator <format_wanted_type> fwt_pool ("format_wanted_type pool"); 1826 check_format_info_main (res, info, format_chars, fmt_param_loc, format_tree, 1827 format_length, params, arg_num, fwt_pool, arglocs); 1828 } 1829 1830 /* Support class for argument_parser and check_format_info_main. 1831 Tracks any flag characters that have been applied to the 1832 current argument. */ 1833 1834 class flag_chars_t 1835 { 1836 public: 1837 flag_chars_t (); 1838 bool has_char_p (char ch) const; 1839 void add_char (char ch); 1840 void validate (const format_kind_info *fki, 1841 const format_char_info *fci, 1842 const format_flag_spec *flag_specs, 1843 const char * const format_chars, 1844 tree format_string_cst, 1845 location_t format_string_loc, 1846 const char * const orig_format_chars, 1847 char format_char, 1848 bool quoted); 1849 int get_alloc_flag (const format_kind_info *fki); 1850 int assignment_suppression_p (const format_kind_info *fki); 1851 1852 private: 1853 char m_flag_chars[256]; 1854 }; 1855 1856 /* Support struct for argument_parser and check_format_info_main. 1857 Encapsulates any length modifier applied to the current argument. */ 1858 1859 class length_modifier 1860 { 1861 public: 1862 length_modifier () 1863 : chars (NULL), val (FMT_LEN_none), std (STD_C89), 1864 scalar_identity_flag (0) 1865 { 1866 } 1867 1868 length_modifier (const char *chars_, 1869 enum format_lengths val_, 1870 enum format_std_version std_, 1871 int scalar_identity_flag_) 1872 : chars (chars_), val (val_), std (std_), 1873 scalar_identity_flag (scalar_identity_flag_) 1874 { 1875 } 1876 1877 const char *chars; 1878 enum format_lengths val; 1879 enum format_std_version std; 1880 int scalar_identity_flag; 1881 }; 1882 1883 /* Parsing one argument within a format string. */ 1884 1885 class argument_parser 1886 { 1887 public: 1888 argument_parser (function_format_info *info, const char *&format_chars, 1889 tree format_string_cst, 1890 const char * const orig_format_chars, 1891 location_t format_string_loc, flag_chars_t &flag_chars, 1892 int &has_operand_number, tree first_fillin_param, 1893 object_allocator <format_wanted_type> &fwt_pool_, 1894 vec<location_t> *arglocs); 1895 1896 bool read_any_dollar (); 1897 1898 bool read_format_flags (); 1899 1900 bool 1901 read_any_format_width (tree ¶ms, 1902 unsigned HOST_WIDE_INT &arg_num); 1903 1904 void 1905 read_any_format_left_precision (); 1906 1907 bool 1908 read_any_format_precision (tree ¶ms, 1909 unsigned HOST_WIDE_INT &arg_num); 1910 1911 void handle_alloc_chars (); 1912 1913 length_modifier read_any_length_modifier (); 1914 1915 void read_any_other_modifier (); 1916 1917 const format_char_info *find_format_char_info (char format_char); 1918 1919 void 1920 validate_flag_pairs (const format_char_info *fci, 1921 char format_char); 1922 1923 void 1924 give_y2k_warnings (const format_char_info *fci, 1925 char format_char); 1926 1927 void parse_any_scan_set (const format_char_info *fci); 1928 1929 bool handle_conversions (const format_char_info *fci, 1930 const length_modifier &len_modifier, 1931 tree &wanted_type, 1932 const char *&wanted_type_name, 1933 unsigned HOST_WIDE_INT &arg_num, 1934 tree ¶ms, 1935 char format_char); 1936 1937 bool 1938 check_argument_type (const format_char_info *fci, 1939 const length_modifier &len_modifier, 1940 tree &wanted_type, 1941 const char *&wanted_type_name, 1942 const bool suppressed, 1943 unsigned HOST_WIDE_INT &arg_num, 1944 tree ¶ms, 1945 const int alloc_flag, 1946 const char * const format_start, 1947 const char * const type_start, 1948 location_t fmt_param_loc, 1949 char conversion_char); 1950 1951 private: 1952 const function_format_info *const info; 1953 const format_kind_info * const fki; 1954 const format_flag_spec * const flag_specs; 1955 const char *start_of_this_format; 1956 const char *&format_chars; 1957 const tree format_string_cst; 1958 const char * const orig_format_chars; 1959 const location_t format_string_loc; 1960 object_allocator <format_wanted_type> &fwt_pool; 1961 flag_chars_t &flag_chars; 1962 int main_arg_num; 1963 tree main_arg_params; 1964 int &has_operand_number; 1965 const tree first_fillin_param; 1966 format_wanted_type width_wanted_type; 1967 format_wanted_type precision_wanted_type; 1968 public: 1969 format_wanted_type main_wanted_type; 1970 private: 1971 format_wanted_type *first_wanted_type; 1972 format_wanted_type *last_wanted_type; 1973 vec<location_t> *arglocs; 1974 }; 1975 1976 /* flag_chars_t's constructor. */ 1977 1978 flag_chars_t::flag_chars_t () 1979 { 1980 m_flag_chars[0] = 0; 1981 } 1982 1983 /* Has CH been seen as a flag within the current argument? */ 1984 1985 bool 1986 flag_chars_t::has_char_p (char ch) const 1987 { 1988 return strchr (m_flag_chars, ch) != 0; 1989 } 1990 1991 /* Add CH to the flags seen within the current argument. */ 1992 1993 void 1994 flag_chars_t::add_char (char ch) 1995 { 1996 int i = strlen (m_flag_chars); 1997 m_flag_chars[i++] = ch; 1998 m_flag_chars[i] = 0; 1999 } 2000 2001 /* Validate the individual flags used, removing any that are invalid. */ 2002 2003 void 2004 flag_chars_t::validate (const format_kind_info *fki, 2005 const format_char_info *fci, 2006 const format_flag_spec *flag_specs, 2007 const char * const format_chars, 2008 tree format_string_cst, 2009 location_t format_string_loc, 2010 const char * const orig_format_chars, 2011 char format_char, 2012 bool quoted) 2013 { 2014 int i; 2015 int d = 0; 2016 bool quotflag = false; 2017 2018 for (i = 0; m_flag_chars[i] != 0; i++) 2019 { 2020 const format_flag_spec *s = get_flag_spec (flag_specs, 2021 m_flag_chars[i], NULL); 2022 m_flag_chars[i - d] = m_flag_chars[i]; 2023 if (m_flag_chars[i] == fki->length_code_char) 2024 continue; 2025 2026 /* Remember if a quoting flag is seen. */ 2027 quotflag |= s->quoting; 2028 2029 if (strchr (fci->flag_chars, m_flag_chars[i]) == 0) 2030 { 2031 format_warning_at_char (format_string_loc, format_string_cst, 2032 format_chars - orig_format_chars, 2033 OPT_Wformat_, 2034 "%s used with %<%%%c%> %s format", 2035 _(s->name), format_char, fki->name); 2036 d++; 2037 continue; 2038 } 2039 if (pedantic) 2040 { 2041 const format_flag_spec *t; 2042 if (ADJ_STD (s->std) > C_STD_VER) 2043 warning_at (format_string_loc, OPT_Wformat_, 2044 "%s does not support %s", 2045 C_STD_NAME (s->std), _(s->long_name)); 2046 t = get_flag_spec (flag_specs, m_flag_chars[i], fci->flags2); 2047 if (t != NULL && ADJ_STD (t->std) > ADJ_STD (s->std)) 2048 { 2049 const char *long_name = (t->long_name != NULL 2050 ? t->long_name 2051 : s->long_name); 2052 if (ADJ_STD (t->std) > C_STD_VER) 2053 warning_at (format_string_loc, OPT_Wformat_, 2054 "%s does not support %s with" 2055 " the %<%%%c%> %s format", 2056 C_STD_NAME (t->std), _(long_name), 2057 format_char, fki->name); 2058 } 2059 } 2060 2061 /* Detect quoting directives used within a quoted sequence, such 2062 as GCC's "%<...%qE". */ 2063 if (quoted && s->quoting) 2064 { 2065 format_warning_at_char (format_string_loc, format_string_cst, 2066 format_chars - orig_format_chars - 1, 2067 OPT_Wformat_, 2068 "%s used within a quoted sequence", 2069 _(s->name)); 2070 } 2071 } 2072 m_flag_chars[i - d] = 0; 2073 2074 if (!quoted 2075 && !quotflag 2076 && strchr (fci->flags2, '\'')) 2077 { 2078 format_warning_at_char (format_string_loc, format_string_cst, 2079 format_chars - orig_format_chars, 2080 OPT_Wformat_, 2081 "%qc conversion used unquoted", 2082 format_char); 2083 } 2084 } 2085 2086 /* Determine if an assignment-allocation has been set, requiring 2087 an extra char ** for writing back a dynamically-allocated char *. 2088 This is for handling the optional 'm' character in scanf. */ 2089 2090 int 2091 flag_chars_t::get_alloc_flag (const format_kind_info *fki) 2092 { 2093 if ((fki->flags & (int) FMT_FLAG_SCANF_A_KLUDGE) 2094 && has_char_p ('a')) 2095 return 1; 2096 if (fki->alloc_char && has_char_p (fki->alloc_char)) 2097 return 1; 2098 return 0; 2099 } 2100 2101 /* Determine if an assignment-suppression character was seen. 2102 ('*' in scanf, for discarding the converted input). */ 2103 2104 int 2105 flag_chars_t::assignment_suppression_p (const format_kind_info *fki) 2106 { 2107 if (fki->suppression_char 2108 && has_char_p (fki->suppression_char)) 2109 return 1; 2110 return 0; 2111 } 2112 2113 /* Constructor for argument_parser. Initialize for parsing one 2114 argument within a format string. */ 2115 2116 argument_parser:: 2117 argument_parser (function_format_info *info_, const char *&format_chars_, 2118 tree format_string_cst_, 2119 const char * const orig_format_chars_, 2120 location_t format_string_loc_, 2121 flag_chars_t &flag_chars_, 2122 int &has_operand_number_, 2123 tree first_fillin_param_, 2124 object_allocator <format_wanted_type> &fwt_pool_, 2125 vec<location_t> *arglocs_) 2126 : info (info_), 2127 fki (&format_types[info->format_type]), 2128 flag_specs (fki->flag_specs), 2129 start_of_this_format (format_chars_), 2130 format_chars (format_chars_), 2131 format_string_cst (format_string_cst_), 2132 orig_format_chars (orig_format_chars_), 2133 format_string_loc (format_string_loc_), 2134 fwt_pool (fwt_pool_), 2135 flag_chars (flag_chars_), 2136 main_arg_num (0), 2137 main_arg_params (NULL), 2138 has_operand_number (has_operand_number_), 2139 first_fillin_param (first_fillin_param_), 2140 first_wanted_type (NULL), 2141 last_wanted_type (NULL), 2142 arglocs (arglocs_) 2143 { 2144 } 2145 2146 /* Handle dollars at the start of format arguments, setting up main_arg_params 2147 and main_arg_num. 2148 2149 Return true if format parsing is to continue, false otherwise. */ 2150 2151 bool 2152 argument_parser::read_any_dollar () 2153 { 2154 if ((fki->flags & (int) FMT_FLAG_USE_DOLLAR) && has_operand_number != 0) 2155 { 2156 /* Possibly read a $ operand number at the start of the format. 2157 If one was previously used, one is required here. If one 2158 is not used here, we can't immediately conclude this is a 2159 format without them, since it could be printf %m or scanf %*. */ 2160 int opnum; 2161 opnum = maybe_read_dollar_number (&format_chars, 0, 2162 first_fillin_param, 2163 &main_arg_params, fki); 2164 if (opnum == -1) 2165 return false; 2166 else if (opnum > 0) 2167 { 2168 has_operand_number = 1; 2169 main_arg_num = opnum + info->first_arg_num - 1; 2170 } 2171 } 2172 else if (fki->flags & FMT_FLAG_USE_DOLLAR) 2173 { 2174 if (avoid_dollar_number (format_chars)) 2175 return false; 2176 } 2177 return true; 2178 } 2179 2180 /* Read any format flags, but do not yet validate them beyond removing 2181 duplicates, since in general validation depends on the rest of 2182 the format. 2183 2184 Return true if format parsing is to continue, false otherwise. */ 2185 2186 bool 2187 argument_parser::read_format_flags () 2188 { 2189 while (*format_chars != 0 2190 && strchr (fki->flag_chars, *format_chars) != 0) 2191 { 2192 const format_flag_spec *s = get_flag_spec (flag_specs, 2193 *format_chars, NULL); 2194 if (flag_chars.has_char_p (*format_chars)) 2195 { 2196 format_warning_at_char (format_string_loc, format_string_cst, 2197 format_chars + 1 - orig_format_chars, 2198 OPT_Wformat_, 2199 "repeated %s in format", _(s->name)); 2200 } 2201 else 2202 flag_chars.add_char (*format_chars); 2203 2204 if (s->skip_next_char) 2205 { 2206 ++format_chars; 2207 if (*format_chars == 0) 2208 { 2209 warning_at (format_string_loc, OPT_Wformat_, 2210 "missing fill character at end of strfmon format"); 2211 return false; 2212 } 2213 } 2214 ++format_chars; 2215 } 2216 2217 return true; 2218 } 2219 2220 /* Read any format width, possibly * or *m$. 2221 2222 Return true if format parsing is to continue, false otherwise. */ 2223 2224 bool 2225 argument_parser:: 2226 read_any_format_width (tree ¶ms, 2227 unsigned HOST_WIDE_INT &arg_num) 2228 { 2229 if (!fki->width_char) 2230 return true; 2231 2232 if (fki->width_type != NULL && *format_chars == '*') 2233 { 2234 flag_chars.add_char (fki->width_char); 2235 /* "...a field width...may be indicated by an asterisk. 2236 In this case, an int argument supplies the field width..." */ 2237 ++format_chars; 2238 if (has_operand_number != 0) 2239 { 2240 int opnum; 2241 opnum = maybe_read_dollar_number (&format_chars, 2242 has_operand_number == 1, 2243 first_fillin_param, 2244 ¶ms, fki); 2245 if (opnum == -1) 2246 return false; 2247 else if (opnum > 0) 2248 { 2249 has_operand_number = 1; 2250 arg_num = opnum + info->first_arg_num - 1; 2251 } 2252 else 2253 has_operand_number = 0; 2254 } 2255 else 2256 { 2257 if (avoid_dollar_number (format_chars)) 2258 return false; 2259 } 2260 if (info->first_arg_num != 0) 2261 { 2262 tree cur_param; 2263 if (params == 0) 2264 cur_param = NULL; 2265 else 2266 { 2267 cur_param = TREE_VALUE (params); 2268 if (has_operand_number <= 0) 2269 { 2270 params = TREE_CHAIN (params); 2271 ++arg_num; 2272 } 2273 } 2274 width_wanted_type.wanted_type = *fki->width_type; 2275 width_wanted_type.wanted_type_name = NULL; 2276 width_wanted_type.pointer_count = 0; 2277 width_wanted_type.char_lenient_flag = 0; 2278 width_wanted_type.scalar_identity_flag = 0; 2279 width_wanted_type.writing_in_flag = 0; 2280 width_wanted_type.reading_from_flag = 0; 2281 width_wanted_type.kind = CF_KIND_FIELD_WIDTH; 2282 width_wanted_type.format_start = format_chars - 1; 2283 width_wanted_type.format_length = 1; 2284 width_wanted_type.param = cur_param; 2285 width_wanted_type.arg_num = arg_num; 2286 width_wanted_type.offset_loc = 2287 format_chars - orig_format_chars; 2288 width_wanted_type.next = NULL; 2289 if (last_wanted_type != 0) 2290 last_wanted_type->next = &width_wanted_type; 2291 if (first_wanted_type == 0) 2292 first_wanted_type = &width_wanted_type; 2293 last_wanted_type = &width_wanted_type; 2294 } 2295 } 2296 else 2297 { 2298 /* Possibly read a numeric width. If the width is zero, 2299 we complain if appropriate. */ 2300 int non_zero_width_char = FALSE; 2301 int found_width = FALSE; 2302 while (ISDIGIT (*format_chars)) 2303 { 2304 found_width = TRUE; 2305 if (*format_chars != '0') 2306 non_zero_width_char = TRUE; 2307 ++format_chars; 2308 } 2309 if (found_width && !non_zero_width_char && 2310 (fki->flags & (int) FMT_FLAG_ZERO_WIDTH_BAD)) 2311 warning_at (format_string_loc, OPT_Wformat_, 2312 "zero width in %s format", fki->name); 2313 if (found_width) 2314 flag_chars.add_char (fki->width_char); 2315 } 2316 2317 return true; 2318 } 2319 2320 /* Read any format left precision (must be a number, not *). */ 2321 void 2322 argument_parser::read_any_format_left_precision () 2323 { 2324 if (fki->left_precision_char == 0) 2325 return; 2326 if (*format_chars != '#') 2327 return; 2328 2329 ++format_chars; 2330 flag_chars.add_char (fki->left_precision_char); 2331 if (!ISDIGIT (*format_chars)) 2332 format_warning_at_char (format_string_loc, format_string_cst, 2333 format_chars - orig_format_chars, 2334 OPT_Wformat_, 2335 "empty left precision in %s format", fki->name); 2336 while (ISDIGIT (*format_chars)) 2337 ++format_chars; 2338 } 2339 2340 /* Read any format precision, possibly * or *m$. 2341 2342 Return true if format parsing is to continue, false otherwise. */ 2343 2344 bool 2345 argument_parser:: 2346 read_any_format_precision (tree ¶ms, 2347 unsigned HOST_WIDE_INT &arg_num) 2348 { 2349 if (fki->precision_char == 0) 2350 return true; 2351 if (*format_chars != '.') 2352 return true; 2353 2354 ++format_chars; 2355 flag_chars.add_char (fki->precision_char); 2356 if (fki->precision_type != NULL && *format_chars == '*') 2357 { 2358 /* "...a...precision...may be indicated by an asterisk. 2359 In this case, an int argument supplies the...precision." */ 2360 ++format_chars; 2361 if (has_operand_number != 0) 2362 { 2363 int opnum; 2364 opnum = maybe_read_dollar_number (&format_chars, 2365 has_operand_number == 1, 2366 first_fillin_param, 2367 ¶ms, fki); 2368 if (opnum == -1) 2369 return false; 2370 else if (opnum > 0) 2371 { 2372 has_operand_number = 1; 2373 arg_num = opnum + info->first_arg_num - 1; 2374 } 2375 else 2376 has_operand_number = 0; 2377 } 2378 else 2379 { 2380 if (avoid_dollar_number (format_chars)) 2381 return false; 2382 } 2383 if (info->first_arg_num != 0) 2384 { 2385 tree cur_param; 2386 if (params == 0) 2387 cur_param = NULL; 2388 else 2389 { 2390 cur_param = TREE_VALUE (params); 2391 if (has_operand_number <= 0) 2392 { 2393 params = TREE_CHAIN (params); 2394 ++arg_num; 2395 } 2396 } 2397 precision_wanted_type.wanted_type = *fki->precision_type; 2398 precision_wanted_type.wanted_type_name = NULL; 2399 precision_wanted_type.pointer_count = 0; 2400 precision_wanted_type.char_lenient_flag = 0; 2401 precision_wanted_type.scalar_identity_flag = 0; 2402 precision_wanted_type.writing_in_flag = 0; 2403 precision_wanted_type.reading_from_flag = 0; 2404 precision_wanted_type.kind = CF_KIND_FIELD_PRECISION; 2405 precision_wanted_type.param = cur_param; 2406 precision_wanted_type.format_start = format_chars - 2; 2407 precision_wanted_type.format_length = 2; 2408 precision_wanted_type.arg_num = arg_num; 2409 precision_wanted_type.offset_loc = 2410 format_chars - orig_format_chars; 2411 precision_wanted_type.next = NULL; 2412 if (last_wanted_type != 0) 2413 last_wanted_type->next = &precision_wanted_type; 2414 if (first_wanted_type == 0) 2415 first_wanted_type = &precision_wanted_type; 2416 last_wanted_type = &precision_wanted_type; 2417 } 2418 } 2419 else 2420 { 2421 if (!(fki->flags & (int) FMT_FLAG_EMPTY_PREC_OK) 2422 && !ISDIGIT (*format_chars)) 2423 format_warning_at_char (format_string_loc, format_string_cst, 2424 format_chars - orig_format_chars, 2425 OPT_Wformat_, 2426 "empty precision in %s format", fki->name); 2427 while (ISDIGIT (*format_chars)) 2428 ++format_chars; 2429 } 2430 2431 return true; 2432 } 2433 2434 /* Parse any assignment-allocation flags, which request an extra 2435 char ** for writing back a dynamically-allocated char *. 2436 This is for handling the optional 'm' character in scanf, 2437 and, before C99, 'a' (for compatibility with a non-standard 2438 GNU libc extension). */ 2439 2440 void 2441 argument_parser::handle_alloc_chars () 2442 { 2443 if (fki->alloc_char && fki->alloc_char == *format_chars) 2444 { 2445 flag_chars.add_char (fki->alloc_char); 2446 format_chars++; 2447 } 2448 2449 /* Handle the scanf allocation kludge. */ 2450 if (fki->flags & (int) FMT_FLAG_SCANF_A_KLUDGE) 2451 { 2452 if (*format_chars == 'a' && !flag_isoc99) 2453 { 2454 if (format_chars[1] == 's' || format_chars[1] == 'S' 2455 || format_chars[1] == '[') 2456 { 2457 /* 'a' is used as a flag. */ 2458 flag_chars.add_char ('a'); 2459 format_chars++; 2460 } 2461 } 2462 } 2463 } 2464 2465 /* Look for length modifiers within the current format argument, 2466 returning a length_modifier instance describing it (or the 2467 default if one is not found). 2468 2469 Issue warnings about non-standard modifiers. */ 2470 2471 length_modifier 2472 argument_parser::read_any_length_modifier () 2473 { 2474 length_modifier result; 2475 2476 const format_length_info *fli = fki->length_char_specs; 2477 if (!fli) 2478 return result; 2479 2480 while (fli->name != 0 2481 && strncmp (fli->name, format_chars, strlen (fli->name))) 2482 fli++; 2483 if (fli->name != 0) 2484 { 2485 format_chars += strlen (fli->name); 2486 if (fli->double_name != 0 && fli->name[0] == *format_chars) 2487 { 2488 format_chars++; 2489 result = length_modifier (fli->double_name, fli->double_index, 2490 fli->double_std, 0); 2491 } 2492 else 2493 { 2494 result = length_modifier (fli->name, fli->index, fli->std, 2495 fli->scalar_identity_flag); 2496 } 2497 flag_chars.add_char (fki->length_code_char); 2498 } 2499 if (pedantic) 2500 { 2501 /* Warn if the length modifier is non-standard. */ 2502 if (ADJ_STD (result.std) > C_STD_VER) 2503 warning_at (format_string_loc, OPT_Wformat_, 2504 "%s does not support the %qs %s length modifier", 2505 C_STD_NAME (result.std), result.chars, 2506 fki->name); 2507 } 2508 2509 return result; 2510 } 2511 2512 /* Read any other modifier (strftime E/O). */ 2513 2514 void 2515 argument_parser::read_any_other_modifier () 2516 { 2517 if (fki->modifier_chars == NULL) 2518 return; 2519 2520 while (*format_chars != 0 2521 && strchr (fki->modifier_chars, *format_chars) != 0) 2522 { 2523 if (flag_chars.has_char_p (*format_chars)) 2524 { 2525 const format_flag_spec *s = get_flag_spec (flag_specs, 2526 *format_chars, NULL); 2527 format_warning_at_char (format_string_loc, format_string_cst, 2528 format_chars - orig_format_chars, 2529 OPT_Wformat_, 2530 "repeated %s in format", _(s->name)); 2531 } 2532 else 2533 flag_chars.add_char (*format_chars); 2534 ++format_chars; 2535 } 2536 } 2537 2538 /* Return the format_char_info corresponding to FORMAT_CHAR, 2539 potentially issuing a warning if the format char is 2540 not supported in the C standard version we are checking 2541 against. 2542 2543 Issue a warning and return NULL if it is not found. 2544 2545 Issue warnings about non-standard modifiers. */ 2546 2547 const format_char_info * 2548 argument_parser::find_format_char_info (char format_char) 2549 { 2550 const format_char_info *fci = fki->conversion_specs; 2551 2552 while (fci->format_chars != 0 2553 && strchr (fci->format_chars, format_char) == 0) 2554 ++fci; 2555 if (fci->format_chars == 0) 2556 { 2557 format_warning_at_char (format_string_loc, format_string_cst, 2558 format_chars - orig_format_chars, 2559 OPT_Wformat_, 2560 "unknown conversion type character" 2561 " %qc in format", 2562 format_char); 2563 return NULL; 2564 } 2565 2566 if (pedantic) 2567 { 2568 if (ADJ_STD (fci->std) > C_STD_VER) 2569 format_warning_at_char (format_string_loc, format_string_cst, 2570 format_chars - orig_format_chars, 2571 OPT_Wformat_, 2572 "%s does not support the %<%%%c%> %s format", 2573 C_STD_NAME (fci->std), format_char, fki->name); 2574 } 2575 2576 return fci; 2577 } 2578 2579 /* Validate the pairs of flags used. 2580 Issue warnings about incompatible combinations of flags. */ 2581 2582 void 2583 argument_parser::validate_flag_pairs (const format_char_info *fci, 2584 char format_char) 2585 { 2586 const format_flag_pair * const bad_flag_pairs = fki->bad_flag_pairs; 2587 2588 for (int i = 0; bad_flag_pairs[i].flag_char1 != 0; i++) 2589 { 2590 const format_flag_spec *s, *t; 2591 if (!flag_chars.has_char_p (bad_flag_pairs[i].flag_char1)) 2592 continue; 2593 if (!flag_chars.has_char_p (bad_flag_pairs[i].flag_char2)) 2594 continue; 2595 if (bad_flag_pairs[i].predicate != 0 2596 && strchr (fci->flags2, bad_flag_pairs[i].predicate) == 0) 2597 continue; 2598 s = get_flag_spec (flag_specs, bad_flag_pairs[i].flag_char1, NULL); 2599 t = get_flag_spec (flag_specs, bad_flag_pairs[i].flag_char2, NULL); 2600 if (bad_flag_pairs[i].ignored) 2601 { 2602 if (bad_flag_pairs[i].predicate != 0) 2603 warning_at (format_string_loc, OPT_Wformat_, 2604 "%s ignored with %s and %<%%%c%> %s format", 2605 _(s->name), _(t->name), format_char, 2606 fki->name); 2607 else 2608 warning_at (format_string_loc, OPT_Wformat_, 2609 "%s ignored with %s in %s format", 2610 _(s->name), _(t->name), fki->name); 2611 } 2612 else 2613 { 2614 if (bad_flag_pairs[i].predicate != 0) 2615 warning_at (format_string_loc, OPT_Wformat_, 2616 "use of %s and %s together with %<%%%c%> %s format", 2617 _(s->name), _(t->name), format_char, 2618 fki->name); 2619 else 2620 warning_at (format_string_loc, OPT_Wformat_, 2621 "use of %s and %s together in %s format", 2622 _(s->name), _(t->name), fki->name); 2623 } 2624 } 2625 } 2626 2627 /* Give Y2K warnings. */ 2628 2629 void 2630 argument_parser::give_y2k_warnings (const format_char_info *fci, 2631 char format_char) 2632 { 2633 if (!warn_format_y2k) 2634 return; 2635 2636 int y2k_level = 0; 2637 if (strchr (fci->flags2, '4') != 0) 2638 if (flag_chars.has_char_p ('E')) 2639 y2k_level = 3; 2640 else 2641 y2k_level = 2; 2642 else if (strchr (fci->flags2, '3') != 0) 2643 y2k_level = 3; 2644 else if (strchr (fci->flags2, '2') != 0) 2645 y2k_level = 2; 2646 if (y2k_level == 3) 2647 warning_at (format_string_loc, OPT_Wformat_y2k, 2648 "%<%%%c%> yields only last 2 digits of " 2649 "year in some locales", format_char); 2650 else if (y2k_level == 2) 2651 warning_at (format_string_loc, OPT_Wformat_y2k, 2652 "%<%%%c%> yields only last 2 digits of year", 2653 format_char); 2654 } 2655 2656 /* Parse any "scan sets" enclosed in square brackets, e.g. 2657 for scanf-style calls. */ 2658 2659 void 2660 argument_parser::parse_any_scan_set (const format_char_info *fci) 2661 { 2662 if (strchr (fci->flags2, '[') == NULL) 2663 return; 2664 2665 /* Skip over scan set, in case it happens to have '%' in it. */ 2666 if (*format_chars == '^') 2667 ++format_chars; 2668 /* Find closing bracket; if one is hit immediately, then 2669 it's part of the scan set rather than a terminator. */ 2670 if (*format_chars == ']') 2671 ++format_chars; 2672 while (*format_chars && *format_chars != ']') 2673 ++format_chars; 2674 if (*format_chars != ']') 2675 /* The end of the format string was reached. */ 2676 format_warning_at_char (format_string_loc, format_string_cst, 2677 format_chars - orig_format_chars, 2678 OPT_Wformat_, 2679 "no closing %<]%> for %<%%[%> format"); 2680 } 2681 2682 /* Return true if this argument is to be continued to be parsed, 2683 false to skip to next argument. */ 2684 2685 bool 2686 argument_parser::handle_conversions (const format_char_info *fci, 2687 const length_modifier &len_modifier, 2688 tree &wanted_type, 2689 const char *&wanted_type_name, 2690 unsigned HOST_WIDE_INT &arg_num, 2691 tree ¶ms, 2692 char format_char) 2693 { 2694 enum format_std_version wanted_type_std; 2695 2696 if (!(fki->flags & (int) FMT_FLAG_ARG_CONVERT)) 2697 return true; 2698 2699 wanted_type = (fci->types[len_modifier.val].type 2700 ? *fci->types[len_modifier.val].type : 0); 2701 wanted_type_name = fci->types[len_modifier.val].name; 2702 wanted_type_std = fci->types[len_modifier.val].std; 2703 if (wanted_type == 0) 2704 { 2705 format_warning_at_char (format_string_loc, format_string_cst, 2706 format_chars - orig_format_chars, 2707 OPT_Wformat_, 2708 "use of %qs length modifier with %qc type" 2709 " character has either no effect" 2710 " or undefined behavior", 2711 len_modifier.chars, format_char); 2712 /* Heuristic: skip one argument when an invalid length/type 2713 combination is encountered. */ 2714 arg_num++; 2715 if (params != 0) 2716 params = TREE_CHAIN (params); 2717 return false; 2718 } 2719 else if (pedantic 2720 /* Warn if non-standard, provided it is more non-standard 2721 than the length and type characters that may already 2722 have been warned for. */ 2723 && ADJ_STD (wanted_type_std) > ADJ_STD (len_modifier.std) 2724 && ADJ_STD (wanted_type_std) > ADJ_STD (fci->std)) 2725 { 2726 if (ADJ_STD (wanted_type_std) > C_STD_VER) 2727 format_warning_at_char (format_string_loc, format_string_cst, 2728 format_chars - orig_format_chars, 2729 OPT_Wformat_, 2730 "%s does not support the %<%%%s%c%> %s format", 2731 C_STD_NAME (wanted_type_std), 2732 len_modifier.chars, 2733 format_char, fki->name); 2734 } 2735 2736 return true; 2737 } 2738 2739 /* Check type of argument against desired type. 2740 2741 Return true if format parsing is to continue, false otherwise. */ 2742 2743 bool 2744 argument_parser:: 2745 check_argument_type (const format_char_info *fci, 2746 const length_modifier &len_modifier, 2747 tree &wanted_type, 2748 const char *&wanted_type_name, 2749 const bool suppressed, 2750 unsigned HOST_WIDE_INT &arg_num, 2751 tree ¶ms, 2752 const int alloc_flag, 2753 const char * const format_start, 2754 const char * const type_start, 2755 location_t fmt_param_loc, 2756 char conversion_char) 2757 { 2758 if (info->first_arg_num == 0) 2759 return true; 2760 2761 if ((fci->pointer_count == 0 && wanted_type == void_type_node) 2762 || suppressed) 2763 { 2764 if (main_arg_num != 0) 2765 { 2766 if (suppressed) 2767 warning_at (format_string_loc, OPT_Wformat_, 2768 "operand number specified with " 2769 "suppressed assignment"); 2770 else 2771 warning_at (format_string_loc, OPT_Wformat_, 2772 "operand number specified for format " 2773 "taking no argument"); 2774 } 2775 } 2776 else 2777 { 2778 format_wanted_type *wanted_type_ptr; 2779 2780 if (main_arg_num != 0) 2781 { 2782 arg_num = main_arg_num; 2783 params = main_arg_params; 2784 } 2785 else 2786 { 2787 ++arg_num; 2788 if (has_operand_number > 0) 2789 { 2790 warning_at (format_string_loc, OPT_Wformat_, 2791 "missing $ operand number in format"); 2792 return false; 2793 } 2794 else 2795 has_operand_number = 0; 2796 } 2797 2798 wanted_type_ptr = &main_wanted_type; 2799 while (fci) 2800 { 2801 tree cur_param; 2802 if (params == 0) 2803 cur_param = NULL; 2804 else 2805 { 2806 cur_param = TREE_VALUE (params); 2807 params = TREE_CHAIN (params); 2808 } 2809 2810 wanted_type_ptr->wanted_type = wanted_type; 2811 wanted_type_ptr->wanted_type_name = wanted_type_name; 2812 wanted_type_ptr->pointer_count = fci->pointer_count + alloc_flag; 2813 wanted_type_ptr->char_lenient_flag = 0; 2814 if (strchr (fci->flags2, 'c') != 0) 2815 wanted_type_ptr->char_lenient_flag = 1; 2816 wanted_type_ptr->scalar_identity_flag = 0; 2817 if (len_modifier.scalar_identity_flag) 2818 wanted_type_ptr->scalar_identity_flag = 1; 2819 wanted_type_ptr->writing_in_flag = 0; 2820 wanted_type_ptr->reading_from_flag = 0; 2821 if (alloc_flag) 2822 wanted_type_ptr->writing_in_flag = 1; 2823 else 2824 { 2825 if (strchr (fci->flags2, 'W') != 0) 2826 wanted_type_ptr->writing_in_flag = 1; 2827 if (strchr (fci->flags2, 'R') != 0) 2828 wanted_type_ptr->reading_from_flag = 1; 2829 } 2830 wanted_type_ptr->kind = CF_KIND_FORMAT; 2831 wanted_type_ptr->param = cur_param; 2832 wanted_type_ptr->arg_num = arg_num; 2833 wanted_type_ptr->format_start = format_start; 2834 wanted_type_ptr->format_length = format_chars - format_start; 2835 wanted_type_ptr->offset_loc = format_chars - orig_format_chars; 2836 wanted_type_ptr->next = NULL; 2837 if (last_wanted_type != 0) 2838 last_wanted_type->next = wanted_type_ptr; 2839 if (first_wanted_type == 0) 2840 first_wanted_type = wanted_type_ptr; 2841 last_wanted_type = wanted_type_ptr; 2842 2843 fci = fci->chain; 2844 if (fci) 2845 { 2846 wanted_type_ptr = fwt_pool.allocate (); 2847 arg_num++; 2848 wanted_type = *fci->types[len_modifier.val].type; 2849 wanted_type_name = fci->types[len_modifier.val].name; 2850 } 2851 } 2852 } 2853 2854 if (first_wanted_type != 0) 2855 { 2856 ptrdiff_t offset_to_format_start = (start_of_this_format - 1) - orig_format_chars; 2857 ptrdiff_t offset_to_format_end = (format_chars - 1) - orig_format_chars; 2858 /* By default, use the end of the range for the caret location. */ 2859 substring_loc fmt_loc (fmt_param_loc, TREE_TYPE (format_string_cst), 2860 offset_to_format_end, 2861 offset_to_format_start, offset_to_format_end); 2862 ptrdiff_t offset_to_type_start = type_start - orig_format_chars; 2863 check_format_types (fmt_loc, first_wanted_type, fki, 2864 offset_to_type_start, 2865 conversion_char, arglocs); 2866 } 2867 2868 return true; 2869 } 2870 2871 /* Describes "paired tokens" within the format string that are 2872 expected to be balanced. */ 2873 2874 class baltoks_t 2875 { 2876 public: 2877 baltoks_t (): singlequote (), doublequote () { } 2878 2879 typedef auto_vec<const char *> balanced_tokens_t; 2880 /* Vectors of pointers to opening brackets ('['), curly brackets ('{'), 2881 quoting directives (like GCC "%<"), parentheses, and angle brackets 2882 ('<'). Used to detect unbalanced tokens. */ 2883 balanced_tokens_t brackets; 2884 balanced_tokens_t curly; 2885 balanced_tokens_t quotdirs; 2886 balanced_tokens_t parens; 2887 balanced_tokens_t pointy; 2888 /* Pointer to the last opening quote. */ 2889 const char *singlequote; 2890 const char *doublequote; 2891 }; 2892 2893 /* Describes a keyword, operator, or other name. */ 2894 2895 struct token_t 2896 { 2897 const char *name; /* Keyword/operator name. */ 2898 unsigned char len; /* Its length. */ 2899 const char *alt; /* Alternate spelling. */ 2900 }; 2901 2902 /* Helper for initializing global token_t arrays below. */ 2903 #define NAME(name) { name, sizeof name - 1, NULL } 2904 2905 /* C/C++ operators that are expected to be quoted within the format 2906 string. */ 2907 2908 static const token_t c_opers[] = 2909 { 2910 NAME ("!="), NAME ("%="), NAME ("&&"), NAME ("&="), NAME ("*="), 2911 NAME ("++"), NAME ("+="), NAME ("--"), NAME ("-="), NAME ("->"), 2912 NAME ("/="), NAME ("<<"), NAME ("<<="), NAME ("<="), NAME ("=="), 2913 NAME (">="), NAME (">>="), NAME (">>"), NAME ("?:"), NAME ("^="), 2914 NAME ("|="), NAME ("||") 2915 }; 2916 2917 static const token_t cxx_opers[] = 2918 { 2919 NAME ("->*"), NAME (".*"), NAME ("::"), NAME ("<=>") 2920 }; 2921 2922 /* Common C/C++ keywords that are expected to be quoted within the format 2923 string. Keywords like auto, inline, or volatile are exccluded because 2924 they are sometimes used in common terms like /auto variables/, /inline 2925 function/, or /volatile access/ where they should not be quoted. */ 2926 2927 static const token_t c_keywords[] = 2928 { 2929 #undef NAME 2930 #define NAME(name, alt) { name, sizeof name - 1, alt } 2931 2932 NAME ("alignas", NULL), 2933 NAME ("alignof", NULL), 2934 NAME ("asm", NULL), 2935 NAME ("bool", NULL), 2936 NAME ("char", NULL), 2937 NAME ("const %", NULL), 2938 NAME ("const-qualified", "%<const%>-qualified"), 2939 NAME ("float", NULL), 2940 NAME ("ifunc", NULL), 2941 NAME ("int", NULL), 2942 NAME ("long double", NULL), 2943 NAME ("long int", NULL), 2944 NAME ("long long", NULL), 2945 NAME ("malloc", NULL), 2946 NAME ("noclone", NULL), 2947 NAME ("noinline", NULL), 2948 NAME ("nonnull", NULL), 2949 NAME ("noreturn", NULL), 2950 NAME ("offsetof", NULL), 2951 NAME ("readonly", "read-only"), 2952 NAME ("readwrite", "read-write"), 2953 NAME ("restrict %", NULL), 2954 NAME ("restrict-qualified", "%<restrict%>-qualified"), 2955 NAME ("short int", NULL), 2956 NAME ("signed char", NULL), 2957 NAME ("signed int", NULL), 2958 NAME ("signed long", NULL), 2959 NAME ("signed short", NULL), 2960 NAME ("sizeof", NULL), 2961 NAME ("typeof", NULL), 2962 NAME ("unsigned char", NULL), 2963 NAME ("unsigned int", NULL), 2964 NAME ("unsigned long", NULL), 2965 NAME ("unsigned short", NULL), 2966 NAME ("volatile %", NULL), 2967 NAME ("volatile-qualified", "%<volatile%>-qualified"), 2968 NAME ("weakref", NULL), 2969 }; 2970 2971 static const token_t cxx_keywords[] = 2972 { 2973 /* C++ only keywords and operators. */ 2974 NAME ("catch", NULL), 2975 NAME ("constexpr if", NULL), 2976 NAME ("constexpr", NULL), 2977 NAME ("constinit", NULL), 2978 NAME ("consteval", NULL), 2979 NAME ("decltype", NULL), 2980 NAME ("nullptr", NULL), 2981 NAME ("operator delete", NULL), 2982 NAME ("operator new", NULL), 2983 NAME ("typeid", NULL), 2984 NAME ("typeinfo", NULL) 2985 }; 2986 2987 /* Blacklisted words such as misspellings that should be avoided in favor 2988 of the specified alternatives. */ 2989 static const struct 2990 { 2991 const char *name; /* Bad word. */ 2992 unsigned char len; /* Its length. */ 2993 const char *alt; /* Preferred alternative. */ 2994 } badwords[] = 2995 { 2996 NAME ("arg", "argument"), 2997 NAME ("bitfield", "bit-field"), 2998 NAME ("builtin function", "built-in function"), 2999 NAME ("can not", "cannot"), 3000 NAME ("commandline option", "command-line option"), 3001 NAME ("commandline", "command line"), 3002 NAME ("command line option", "command-line option"), 3003 NAME ("decl", "declaration"), 3004 NAME ("enumeral", "enumerated"), 3005 NAME ("floating point", "floating-point"), 3006 NAME ("nonstatic", "non-static"), 3007 NAME ("non-zero", "nonzero"), 3008 NAME ("reg", "register"), 3009 NAME ("stmt", "statement"), 3010 }; 3011 3012 /* Common contractions that should be avoided in favor of the specified 3013 alternatives. */ 3014 3015 static const struct 3016 { 3017 const char *name; /* Contraction. */ 3018 unsigned char len; /* Its length. */ 3019 const char *alt; /* Preferred alternative. */ 3020 } contrs[] = 3021 { 3022 NAME ("can't", "cannot"), 3023 NAME ("didn't", "did not"), 3024 /* These are commonly abused. Avoid diagnosing them for now. 3025 NAME ("isn't", "is not"), 3026 NAME ("don't", "is not"), 3027 */ 3028 NAME ("mustn't", "must not"), 3029 NAME ("needn't", "need not"), 3030 NAME ("should't", "should not"), 3031 NAME ("that's", "that is"), 3032 NAME ("there's", "there is"), 3033 NAME ("they're", "they are"), 3034 NAME ("what's", "what is"), 3035 NAME ("won't", "will not") 3036 }; 3037 3038 /* Check for unquoted TOKENS. FORMAT_STRING_LOC is the location of 3039 the format string, FORMAT_STRING_CST the format string itself (as 3040 a tree), ORIG_FORMAT_CHARS and FORMAT_CHARS are pointers to 3041 the beginning of the format string and the character currently 3042 being processed, and BALTOKS describes paired "tokens" within 3043 the format string that are expected to be balanced. 3044 Returns a pointer to the last processed character or null when 3045 nothing was done. */ 3046 3047 static const char* 3048 check_tokens (const token_t *tokens, unsigned ntoks, 3049 location_t format_string_loc, tree format_string_cst, 3050 const char *orig_format_chars, const char *format_chars, 3051 baltoks_t &baltoks) 3052 { 3053 /* For brevity. */ 3054 const int opt = OPT_Wformat_diag; 3055 /* Zero-based starting position of a problem sequence. */ 3056 int fmtchrpos = format_chars - orig_format_chars; 3057 3058 /* For identifier-like "words," set to the word length. */ 3059 unsigned wlen = 0; 3060 /* Set for an operator, clear for an identifier/word. */ 3061 bool is_oper = false; 3062 bool underscore = false; 3063 3064 if (format_chars[0] == '_' || ISALPHA (format_chars[0])) 3065 { 3066 while (format_chars[wlen] == '_' || ISALNUM (format_chars[wlen])) 3067 { 3068 underscore |= format_chars[wlen] == '_'; 3069 ++wlen; 3070 } 3071 } 3072 else 3073 is_oper = true; 3074 3075 for (unsigned i = 0; i != ntoks; ++i) 3076 { 3077 unsigned toklen = tokens[i].len; 3078 3079 if (toklen < wlen 3080 || strncmp (format_chars, tokens[i].name, toklen)) 3081 continue; 3082 3083 if (toklen == 2 3084 && format_chars - orig_format_chars > 0 3085 && (TOUPPER (format_chars[-1]) == 'C' 3086 || TOUPPER (format_chars[-1]) == 'G')) 3087 return format_chars + toklen - 1; /* Reference to C++ or G++. */ 3088 3089 if (ISPUNCT (format_chars[toklen - 1])) 3090 { 3091 if (format_chars[toklen - 1] == format_chars[toklen]) 3092 return NULL; /* Operator followed by another punctuator. */ 3093 } 3094 else if (ISALNUM (format_chars[toklen])) 3095 return NULL; /* Keyword prefix for a longer word. */ 3096 3097 if (toklen == 2 3098 && format_chars[0] == '-' 3099 && format_chars[1] == '-' 3100 && ISALNUM (format_chars[2])) 3101 return NULL; /* Probably option like --help. */ 3102 3103 /* Allow this ugly warning for the time being. */ 3104 if (toklen == 2 3105 && format_chars - orig_format_chars > 6 3106 && startswith (format_chars - 7, " count >= width of ")) 3107 return format_chars + 10; 3108 3109 /* The token is a type if it ends in an alphabetic character. */ 3110 bool is_type = (ISALPHA (tokens[i].name[toklen - 1]) 3111 && strchr (tokens[i].name, ' ')); 3112 3113 /* Backtrack to the last alphabetic character (for tokens whose 3114 names end in '%'). */ 3115 if (!is_oper) 3116 while (!ISALPHA (tokens[i].name[toklen - 1])) 3117 --toklen; 3118 3119 if (format_warning_substr (format_string_loc, format_string_cst, 3120 fmtchrpos, fmtchrpos + toklen, opt, 3121 (is_type 3122 ? G_("unquoted type name %<%.*s%> in format") 3123 : (is_oper 3124 ? G_("unquoted operator %<%.*s%> in format") 3125 : G_("unquoted keyword %<%.*s%> in format"))), 3126 toklen, format_chars) 3127 && tokens[i].alt) 3128 inform (format_string_loc, "use %qs instead", tokens[i].alt); 3129 3130 return format_chars + toklen - 1; 3131 } 3132 3133 /* Diagnose unquoted __attribute__. Consider any parenthesized 3134 argument to the attribute to avoid redundant warnings for 3135 the double parentheses that might follow. */ 3136 if (startswith (format_chars, "__attribute")) 3137 { 3138 unsigned nchars = sizeof "__attribute" - 1; 3139 while ('_' == format_chars[nchars]) 3140 ++nchars; 3141 3142 for (int i = nchars; format_chars[i]; ++i) 3143 if (' ' != format_chars[i]) 3144 { 3145 nchars = i; 3146 break; 3147 } 3148 3149 if (format_chars[nchars] == '(') 3150 { 3151 baltoks.parens.safe_push (format_chars + nchars); 3152 3153 ++nchars; 3154 bool close = false; 3155 if (format_chars[nchars] == '(') 3156 { 3157 baltoks.parens.safe_push (format_chars + nchars); 3158 close = true; 3159 ++nchars; 3160 } 3161 for (int i = nchars; format_chars[i]; ++i) 3162 if (')' == format_chars[i]) 3163 { 3164 if (baltoks.parens.length () > 0) 3165 baltoks.parens.pop (); 3166 nchars = i + 1; 3167 break; 3168 } 3169 3170 if (close && format_chars[nchars] == ')') 3171 { 3172 if (baltoks.parens.length () > 0) 3173 baltoks.parens.pop (); 3174 ++nchars; 3175 } 3176 } 3177 3178 format_warning_substr (format_string_loc, format_string_cst, 3179 fmtchrpos, fmtchrpos + nchars, opt, 3180 "unquoted attribute in format"); 3181 return format_chars + nchars - 1; 3182 } 3183 3184 /* Diagnose unquoted built-ins. */ 3185 if (format_chars[0] == '_' 3186 && format_chars[1] == '_' 3187 && (startswith (format_chars + 2, "atomic") 3188 || startswith (format_chars + 2, "builtin") 3189 || startswith (format_chars + 2, "sync"))) 3190 { 3191 format_warning_substr (format_string_loc, format_string_cst, 3192 fmtchrpos, fmtchrpos + wlen, opt, 3193 "unquoted name of built-in function %<%.*s%> " 3194 "in format", 3195 wlen, format_chars); 3196 return format_chars + wlen - 1; 3197 } 3198 3199 /* Diagnose unquoted substrings of alphanumeric characters containing 3200 underscores. They most likely refer to identifiers and should be 3201 quoted. */ 3202 if (underscore) 3203 format_warning_substr (format_string_loc, format_string_cst, 3204 format_chars - orig_format_chars, 3205 format_chars + wlen - orig_format_chars, 3206 opt, 3207 "unquoted identifier or keyword %<%.*s%> in format", 3208 wlen, format_chars); 3209 else 3210 { 3211 /* Diagnose some common misspellings. */ 3212 for (unsigned i = 0; i != sizeof badwords / sizeof *badwords; ++i) 3213 { 3214 unsigned badwlen = strspn (badwords[i].name, " -"); 3215 if (wlen >= badwlen 3216 && (wlen <= badwords[i].len 3217 || (wlen == badwords[i].len + 1U 3218 && TOUPPER (format_chars[wlen - 1]) == 'S')) 3219 && !strncasecmp (format_chars, badwords[i].name, badwords[i].len)) 3220 { 3221 /* Handle singular as well as plural forms of all bad words 3222 even though the latter don't necessarily make sense for 3223 all of the former (like "can nots"). */ 3224 badwlen = badwords[i].len; 3225 const char *plural = ""; 3226 if (TOUPPER (format_chars[badwlen]) == 'S') 3227 { 3228 ++badwlen; 3229 plural = "s"; 3230 } 3231 3232 /* As an exception, don't warn about "decl-specifier*" since 3233 it's a C++ grammar production. */ 3234 if (badwords[i].name[0] == 'd' 3235 && startswith (format_chars, "decl-specifier")) 3236 continue; 3237 3238 format_warning_substr (format_string_loc, format_string_cst, 3239 fmtchrpos, fmtchrpos + badwords[i].len, 3240 opt, 3241 "misspelled term %<%.*s%> in format; " 3242 "use %<%s%s%> instead", 3243 badwlen, format_chars, 3244 badwords[i].alt, plural); 3245 3246 return format_chars + badwords[i].len - 1; 3247 } 3248 } 3249 3250 /* Skip C++/G++. */ 3251 if (!strncasecmp (format_chars, "c++", 3) 3252 || !strncasecmp (format_chars, "g++", 3)) 3253 return format_chars + 2; 3254 } 3255 3256 return wlen ? format_chars + wlen - 1 : NULL; 3257 } 3258 3259 /* Check plain text in a format string of a GCC diagnostic function 3260 for common quoting, punctuation, and spelling mistakes, and issue 3261 -Wformat-diag warnings if they are found. FORMAT_STRING_LOC is 3262 the location of the format string, FORMAT_STRING_CST the format 3263 string itself (as a tree), ORIG_FORMAT_CHARS and FORMAT_CHARS are 3264 pointers to the beginning of the format string and the character 3265 currently being processed, and BALTOKS describes paired "tokens" 3266 within the format string that are expected to be balanced. 3267 Returns a pointer to the last processed character. */ 3268 3269 static const char* 3270 check_plain (location_t format_string_loc, tree format_string_cst, 3271 const char *orig_format_chars, const char *format_chars, 3272 baltoks_t &baltoks) 3273 { 3274 /* For brevity. */ 3275 const int opt = OPT_Wformat_diag; 3276 /* Zero-based starting position of a problem sequence. */ 3277 int fmtchrpos = format_chars - orig_format_chars; 3278 3279 if (*format_chars == '%') 3280 { 3281 /* Diagnose %<%s%> and suggest using %qs instead. */ 3282 if (startswith (format_chars, "%<%s%>")) 3283 format_warning_substr (format_string_loc, format_string_cst, 3284 fmtchrpos, fmtchrpos + 6, opt, 3285 "quoted %qs directive in format; " 3286 "use %qs instead", "%s", "%qs"); 3287 else if (format_chars - orig_format_chars > 2 3288 && !strncasecmp (format_chars - 3, "can%'t", 6)) 3289 format_warning_substr (format_string_loc, 3290 format_string_cst, 3291 fmtchrpos - 3, fmtchrpos + 3, opt, 3292 "contraction %<%.*s%> in format; " 3293 "use %qs instead", 3294 6, format_chars - 3, "cannot"); 3295 3296 return format_chars; 3297 } 3298 3299 if (baltoks.quotdirs.length ()) 3300 { 3301 /* Skip over all plain text within a quoting directive until 3302 the next directive. */ 3303 while (*format_chars && '%' != *format_chars) 3304 ++format_chars; 3305 3306 return format_chars; 3307 } 3308 3309 /* The length of the problem sequence. */ 3310 int nchars = 0; 3311 3312 /* Diagnose any whitespace characters other than <space> but only 3313 leading, trailing, and two or more consecutive <space>s. Do 3314 this before diagnosing control characters because whitespace 3315 is a subset of controls. */ 3316 const char *other_than_space = NULL; 3317 while (ISSPACE (format_chars[nchars])) 3318 { 3319 if (format_chars[nchars] != ' ' && !other_than_space) 3320 other_than_space = format_chars + nchars; 3321 ++nchars; 3322 } 3323 3324 if (nchars) 3325 { 3326 /* This is the most common problem: go the extra mile to describe 3327 the problem in as much helpful detail as possible. */ 3328 if (other_than_space) 3329 { 3330 format_warning_substr (format_string_loc, format_string_cst, 3331 fmtchrpos, fmtchrpos + nchars, opt, 3332 "unquoted whitespace character %qc in format", 3333 *other_than_space); 3334 return format_chars + nchars - 1; 3335 } 3336 3337 if (fmtchrpos == 0) 3338 /* Accept strings of leading spaces with no warning. */ 3339 return format_chars + nchars - 1; 3340 3341 if (!format_chars[nchars]) 3342 { 3343 format_warning_substr (format_string_loc, format_string_cst, 3344 fmtchrpos, fmtchrpos + nchars, opt, 3345 "spurious trailing space in format"); 3346 return format_chars + nchars - 1; 3347 } 3348 3349 if (nchars > 1) 3350 { 3351 if (nchars == 2 3352 && orig_format_chars < format_chars 3353 && format_chars[-1] == '.' 3354 && format_chars[0] == ' ' 3355 && format_chars[1] == ' ') 3356 { 3357 /* A period followed by two spaces. */ 3358 if (ISUPPER (*orig_format_chars)) 3359 { 3360 /* If the part before the period is a capitalized 3361 sentence check to make sure that what follows 3362 is also capitalized. */ 3363 if (ISLOWER (format_chars[2])) 3364 format_warning_substr (format_string_loc, format_string_cst, 3365 fmtchrpos, fmtchrpos + nchars, opt, 3366 "inconsistent capitalization in " 3367 "format"); 3368 } 3369 } 3370 else 3371 format_warning_substr (format_string_loc, format_string_cst, 3372 fmtchrpos, fmtchrpos + nchars, opt, 3373 "unquoted sequence of %i consecutive " 3374 "space characters in format", nchars); 3375 return format_chars + nchars - 1; 3376 } 3377 3378 format_chars += nchars; 3379 nchars = 0; 3380 } 3381 3382 fmtchrpos = format_chars - orig_format_chars; 3383 3384 /* Diagnose any unquoted control characters other than the terminating 3385 NUL. */ 3386 while (format_chars[nchars] && ISCNTRL (format_chars[nchars])) 3387 ++nchars; 3388 3389 if (nchars > 1) 3390 { 3391 format_warning_substr (format_string_loc, format_string_cst, 3392 fmtchrpos, fmtchrpos + nchars, opt, 3393 "unquoted control characters in format"); 3394 return format_chars + nchars - 1; 3395 } 3396 if (nchars) 3397 { 3398 format_warning_substr (format_string_loc, format_string_cst, 3399 fmtchrpos, fmtchrpos + nchars, opt, 3400 "unquoted control character %qc in format", 3401 *format_chars); 3402 return format_chars + nchars - 1; 3403 } 3404 3405 if (ISPUNCT (format_chars[0])) 3406 { 3407 size_t nelts = sizeof c_opers / sizeof *c_opers; 3408 if (const char *ret = check_tokens (c_opers, nelts, 3409 format_string_loc, format_string_cst, 3410 orig_format_chars, format_chars, 3411 baltoks)) 3412 return ret; 3413 3414 nelts = c_dialect_cxx () ? sizeof cxx_opers / sizeof *cxx_opers : 0; 3415 if (const char *ret = check_tokens (cxx_opers, nelts, 3416 format_string_loc, format_string_cst, 3417 orig_format_chars, format_chars, 3418 baltoks)) 3419 return ret; 3420 } 3421 3422 if (ISALPHA (format_chars[0])) 3423 { 3424 size_t nelts = sizeof c_keywords / sizeof *c_keywords; 3425 if (const char *ret = check_tokens (c_keywords, nelts, 3426 format_string_loc, format_string_cst, 3427 orig_format_chars, format_chars, 3428 baltoks)) 3429 return ret; 3430 3431 nelts = c_dialect_cxx () ? sizeof cxx_keywords / sizeof *cxx_keywords : 0; 3432 if (const char *ret = check_tokens (cxx_keywords, nelts, 3433 format_string_loc, format_string_cst, 3434 orig_format_chars, format_chars, 3435 baltoks)) 3436 return ret; 3437 } 3438 3439 nchars = 0; 3440 3441 /* Diagnose unquoted options. */ 3442 if ((format_chars == orig_format_chars 3443 || format_chars[-1] == ' ') 3444 && format_chars[0] == '-' 3445 && ((format_chars[1] == '-' 3446 && ISALPHA (format_chars[2])) 3447 || ISALPHA (format_chars[1]))) 3448 { 3449 nchars = 1; 3450 while (ISALNUM (format_chars[nchars]) 3451 || '_' == format_chars[nchars] 3452 || '-' == format_chars[nchars] 3453 || '+' == format_chars[nchars]) 3454 ++nchars; 3455 3456 format_warning_substr (format_string_loc, format_string_cst, 3457 fmtchrpos, fmtchrpos + nchars, opt, 3458 "unquoted option name %<%.*s%> in format", 3459 nchars, format_chars); 3460 return format_chars + nchars - 1; 3461 } 3462 3463 /* Diagnose leading, trailing, and two or more consecutive punctuation 3464 characters. */ 3465 const char *unbalanced = NULL; 3466 while ('%' != format_chars[nchars] 3467 && ISPUNCT (format_chars[nchars]) 3468 && !unbalanced) 3469 { 3470 switch (format_chars[nchars]) 3471 { 3472 case '[': 3473 baltoks.brackets.safe_push (format_chars + nchars); 3474 break; 3475 case '{': 3476 baltoks.curly.safe_push (format_chars + nchars); 3477 break; 3478 case '(': 3479 baltoks.parens.safe_push (format_chars + nchars); 3480 break; 3481 case '<': 3482 baltoks.pointy.safe_push (format_chars + nchars); 3483 break; 3484 3485 case ']': 3486 if (baltoks.brackets.length () > 0) 3487 baltoks.brackets.pop (); 3488 else 3489 unbalanced = format_chars + nchars; 3490 break; 3491 case '}': 3492 if (baltoks.curly.length () > 0) 3493 baltoks.curly.pop (); 3494 else 3495 unbalanced = format_chars + nchars; 3496 break; 3497 case ')': 3498 if (baltoks.parens.length () > 0) 3499 baltoks.parens.pop (); 3500 else 3501 unbalanced = format_chars + nchars; 3502 break; 3503 case '>': 3504 if (baltoks.pointy.length () > 0) 3505 baltoks.pointy.pop (); 3506 else 3507 unbalanced = format_chars + nchars; 3508 break; 3509 } 3510 3511 ++nchars; 3512 } 3513 3514 if (unbalanced) 3515 { 3516 format_warning_substr (format_string_loc, format_string_cst, 3517 fmtchrpos, fmtchrpos + nchars, opt, 3518 "unbalanced punctuation character %qc in format", 3519 *unbalanced); 3520 return format_chars + nchars - 1; 3521 } 3522 3523 if (nchars) 3524 { 3525 /* Consider any identifier that follows the pound ('#') sign 3526 a preprocessing directive. */ 3527 if (nchars == 1 3528 && format_chars[0] == '#' 3529 && ISALPHA (format_chars[1])) 3530 { 3531 while (ISALNUM (format_chars[nchars]) 3532 || format_chars[nchars] == '_') 3533 ++nchars; 3534 3535 format_warning_substr (format_string_loc, format_string_cst, 3536 fmtchrpos, fmtchrpos + nchars, opt, 3537 "unquoted preprocessing directive %<%.*s%> " 3538 "in format", nchars, format_chars); 3539 return format_chars + nchars - 1; 3540 } 3541 3542 /* Diagnose a bare single quote. */ 3543 if (nchars == 1 3544 && format_chars[0] == '\'' 3545 && format_chars - orig_format_chars 3546 && ISALPHA (format_chars[-1]) 3547 && ISALPHA (format_chars[1])) 3548 { 3549 /* Diagnose a subset of contractions that are best avoided. */ 3550 for (unsigned i = 0; i != sizeof contrs / sizeof *contrs; ++i) 3551 { 3552 const char *apos = strchr (contrs[i].name, '\''); 3553 gcc_assert (apos != NULL); 3554 int off = apos - contrs[i].name; 3555 3556 if (format_chars - orig_format_chars >= off 3557 && !strncmp (format_chars - off, 3558 contrs[i].name, contrs[i].len)) 3559 { 3560 format_warning_substr (format_string_loc, 3561 format_string_cst, 3562 fmtchrpos, fmtchrpos + nchars, opt, 3563 "contraction %<%.*s%> in format; " 3564 "use %qs instead", 3565 contrs[i].len, contrs[i].name, 3566 contrs[i].alt); 3567 return format_chars + nchars - 1; 3568 } 3569 } 3570 3571 if (format_warning_substr (format_string_loc, format_string_cst, 3572 fmtchrpos, fmtchrpos + nchars, opt, 3573 "bare apostrophe %<'%> in format")) 3574 inform (format_string_loc, 3575 "if avoiding the apostrophe is not feasible, enclose " 3576 "it in a pair of %qs and %qs directives instead", 3577 "%<", "%>"); 3578 return format_chars + nchars - 1; 3579 } 3580 3581 /* Diagnose a backtick (grave accent). */ 3582 if (nchars == 1 3583 && format_chars[0] == '`') 3584 { 3585 if (format_warning_substr (format_string_loc, format_string_cst, 3586 fmtchrpos, fmtchrpos + nchars, opt, 3587 "grave accent %<`%> in format")) 3588 inform (format_string_loc, 3589 "use the apostrophe directive %qs instead", "%'"); 3590 return format_chars + nchars - 1; 3591 } 3592 3593 /* Diagnose a punctuation character after a space. */ 3594 if (nchars == 1 3595 && format_chars - orig_format_chars 3596 && format_chars[-1] == ' ' 3597 && strspn (format_chars, "!?:;.,") == 1) 3598 { 3599 format_warning_substr (format_string_loc, format_string_cst, 3600 fmtchrpos - 1, fmtchrpos, opt, 3601 "space followed by punctuation character " 3602 "%<%c%>", format_chars[0]); 3603 return format_chars; 3604 } 3605 3606 if (nchars == 1) 3607 { 3608 if (startswith (format_chars, "\"%s\"")) 3609 { 3610 if (format_warning_substr (format_string_loc, format_string_cst, 3611 fmtchrpos, fmtchrpos + 4, opt, 3612 "quoted %qs directive in format", 3613 "%s")) 3614 inform (format_string_loc, "if using %qs is not feasible, " 3615 "use %qs instead", "%qs", "\"%-s\""); 3616 } 3617 3618 if (format_chars[0] == '"') 3619 { 3620 baltoks.doublequote = baltoks.doublequote ? NULL : format_chars; 3621 return format_chars + nchars - 1; 3622 } 3623 if (format_chars[0] == '\'') 3624 { 3625 baltoks.singlequote = baltoks.singlequote ? NULL : format_chars; 3626 return format_chars + nchars - 1; 3627 } 3628 } 3629 3630 if (fmtchrpos == 0) 3631 { 3632 if (nchars == 1 3633 && format_chars[0] == '(') 3634 ; /* Text beginning in an open parenthesis. */ 3635 else if (nchars == 3 3636 && startswith (format_chars, "...") 3637 && format_chars[3]) 3638 ; /* Text beginning in an ellipsis. */ 3639 else 3640 { 3641 format_warning_substr (format_string_loc, format_string_cst, 3642 fmtchrpos, fmtchrpos + nchars, opt, 3643 "spurious leading punctuation sequence " 3644 "%<%.*s%> in format", 3645 nchars, format_chars); 3646 return format_chars + nchars - 1; 3647 } 3648 } 3649 else if (!format_chars[nchars]) 3650 { 3651 if (nchars == 1 3652 && (format_chars[nchars - 1] == ':' 3653 || format_chars[nchars - 1] == ')')) 3654 ; /* Text ending in a colon or a closing parenthesis. */ 3655 else if (nchars == 1 3656 && ((ISUPPER (*orig_format_chars) 3657 && format_chars[nchars - 1] == '.') 3658 || strspn (format_chars + nchars - 1, "?])") == 1)) 3659 ; /* Capitalized sentence terminated by a single period, 3660 or text ending in a question mark, closing bracket, 3661 or parenthesis. */ 3662 else if (nchars == 2 3663 && format_chars[0] == '?' 3664 && format_chars[1] == ')') 3665 ; /* A question mark after a closing parenthetical note. */ 3666 else if (nchars == 2 3667 && format_chars[0] == ')' 3668 && (format_chars[1] == '?' 3669 || format_chars[1] == ';' 3670 || format_chars[1] == ':' 3671 || (ISUPPER (*orig_format_chars) 3672 && format_chars[1] == '.'))) 3673 ; /* Closing parenthetical note followed by a question mark, 3674 semicolon, or colon at the end of the string, or by 3675 a period at the end of a capitalized sentence. */ 3676 else if (nchars == 3 3677 && format_chars - orig_format_chars > 0 3678 && startswith (format_chars, "...")) 3679 ; /* Text ending in the ellipsis. */ 3680 else 3681 format_warning_substr (format_string_loc, format_string_cst, 3682 fmtchrpos, fmtchrpos + nchars, opt, 3683 "spurious trailing punctuation sequence " 3684 "%<%.*s%> in format", 3685 nchars, format_chars); 3686 3687 return format_chars + nchars - 1; 3688 } 3689 else if (nchars == 2 3690 && format_chars[0] == ')' 3691 && (format_chars[1] == ':' 3692 || format_chars[1] == ';' 3693 || format_chars[1] == ',') 3694 && format_chars[2] == ' ') 3695 ; /* Closing parenthetical note followed by a colon, semicolon 3696 or a comma followed by a space in the middle of the string. */ 3697 else if (nchars > 1) 3698 format_warning_substr (format_string_loc, format_string_cst, 3699 fmtchrpos, fmtchrpos + nchars, opt, 3700 "unquoted sequence of %i consecutive " 3701 "punctuation characters %q.*s in format", 3702 nchars, nchars, format_chars); 3703 return format_chars + nchars - 1; 3704 } 3705 3706 nchars = 0; 3707 3708 /* Finally, diagnose any unquoted non-graph, non-punctuation characters 3709 other than the terminating NUL. */ 3710 while (format_chars[nchars] 3711 && '%' != format_chars[nchars] 3712 && !ISPUNCT (format_chars[nchars]) 3713 && !ISGRAPH (format_chars[nchars])) 3714 ++nchars; 3715 3716 if (nchars > 1) 3717 { 3718 format_warning_substr (format_string_loc, format_string_cst, 3719 fmtchrpos, fmtchrpos + nchars, opt, 3720 "unquoted non-graph characters in format"); 3721 return format_chars + nchars - 1; 3722 } 3723 if (nchars) 3724 { 3725 format_warning_substr (format_string_loc, format_string_cst, 3726 fmtchrpos, fmtchrpos + nchars, opt, 3727 "unquoted non-graph character %qc in format", 3728 *format_chars); 3729 return format_chars + nchars - 1; 3730 } 3731 3732 return format_chars; 3733 } 3734 3735 /* Diagnose unbalanced tokens described by BALTOKS in format string 3736 ORIG_FORMAT_CHARS and the corresponding FORMAT_STRING_CST. */ 3737 3738 static void 3739 maybe_diag_unbalanced_tokens (location_t format_string_loc, 3740 const char *orig_format_chars, 3741 tree format_string_cst, 3742 baltoks_t &baltoks) 3743 { 3744 const char *unbalanced = NULL; 3745 3746 if (baltoks.brackets.length ()) 3747 unbalanced = baltoks.brackets.pop (); 3748 else if (baltoks.curly.length ()) 3749 unbalanced = baltoks.curly.pop (); 3750 else if (baltoks.parens.length ()) 3751 unbalanced = baltoks.parens.pop (); 3752 else if (baltoks.pointy.length ()) 3753 unbalanced = baltoks.pointy.pop (); 3754 3755 if (unbalanced) 3756 format_warning_at_char (format_string_loc, format_string_cst, 3757 unbalanced - orig_format_chars + 1, 3758 OPT_Wformat_diag, 3759 "unbalanced punctuation character %<%c%> in format", 3760 *unbalanced); 3761 3762 if (baltoks.quotdirs.length ()) 3763 format_warning_at_char (format_string_loc, format_string_cst, 3764 baltoks.quotdirs.pop () - orig_format_chars, 3765 OPT_Wformat_, 3766 "unterminated quoting directive"); 3767 3768 const char *quote 3769 = baltoks.singlequote ? baltoks.singlequote : baltoks.doublequote; 3770 3771 if (quote) 3772 format_warning_at_char (format_string_loc, format_string_cst, 3773 quote - orig_format_chars + 1, 3774 OPT_Wformat_diag, 3775 "unterminated quote character %<%c%> in format", 3776 *quote); 3777 } 3778 3779 /* Do the main part of checking a call to a format function. FORMAT_CHARS 3780 is the NUL-terminated format string (which at this point may contain 3781 internal NUL characters); FORMAT_LENGTH is its length (excluding the 3782 terminating NUL character). ARG_NUM is one less than the number of 3783 the first format argument to check; PARAMS points to that format 3784 argument in the list of arguments. */ 3785 3786 static void 3787 check_format_info_main (format_check_results *res, 3788 function_format_info *info, const char *format_chars, 3789 location_t fmt_param_loc, tree format_string_cst, 3790 int format_length, tree params, 3791 unsigned HOST_WIDE_INT arg_num, 3792 object_allocator <format_wanted_type> &fwt_pool, 3793 vec<location_t> *arglocs) 3794 { 3795 const char * const orig_format_chars = format_chars; 3796 const tree first_fillin_param = params; 3797 3798 const format_kind_info * const fki = &format_types[info->format_type]; 3799 const format_flag_spec * const flag_specs = fki->flag_specs; 3800 const location_t format_string_loc = res->format_string_loc; 3801 3802 /* -1 if no conversions taking an operand have been found; 0 if one has 3803 and it didn't use $; 1 if $ formats are in use. */ 3804 int has_operand_number = -1; 3805 3806 /* Vectors of pointers to opening quoting directives (like GCC "%<"), 3807 opening braces, brackets, and parentheses. Used to detect unbalanced 3808 tokens. */ 3809 baltoks_t baltoks; 3810 3811 /* Pointers to the most recent color directives (like GCC's "%r or %R"). 3812 A starting color directive much be terminated before the end of 3813 the format string. A terminating directive makes no sense without 3814 a prior starting directive. */ 3815 const char *color_begin = NULL; 3816 const char *color_end = NULL; 3817 3818 init_dollar_format_checking (info->first_arg_num, first_fillin_param); 3819 3820 /* In GCC diagnostic functions check plain directives (substrings within 3821 the format string that don't start with %) for quoting and punctuations 3822 problems. */ 3823 bool ck_plain = (!info->is_raw 3824 && (info->format_type == gcc_diag_format_type 3825 || info->format_type == gcc_tdiag_format_type 3826 || info->format_type == gcc_cdiag_format_type 3827 || info->format_type == gcc_cxxdiag_format_type)); 3828 3829 while (*format_chars != 0) 3830 { 3831 if (ck_plain) 3832 format_chars = check_plain (format_string_loc, 3833 format_string_cst, 3834 orig_format_chars, format_chars, 3835 baltoks); 3836 3837 if (*format_chars == 0 || *format_chars++ != '%') 3838 continue; 3839 3840 if (*format_chars == 0) 3841 { 3842 format_warning_at_char (format_string_loc, format_string_cst, 3843 format_chars - orig_format_chars, 3844 OPT_Wformat_, 3845 "spurious trailing %<%%%> in format"); 3846 continue; 3847 } 3848 if (*format_chars == '%') 3849 { 3850 ++format_chars; 3851 continue; 3852 } 3853 3854 /* ARGUMENT_PARSER ctor takes FORMAT_CHARS by reference and calls 3855 to ARG_PARSER members may modify the variable. */ 3856 flag_chars_t flag_chars; 3857 argument_parser arg_parser (info, format_chars, format_string_cst, 3858 orig_format_chars, format_string_loc, 3859 flag_chars, has_operand_number, 3860 first_fillin_param, fwt_pool, arglocs); 3861 3862 if (!arg_parser.read_any_dollar ()) 3863 return; 3864 3865 if (!arg_parser.read_format_flags ()) 3866 return; 3867 3868 /* Read any format width, possibly * or *m$. */ 3869 if (!arg_parser.read_any_format_width (params, arg_num)) 3870 return; 3871 3872 /* Read any format left precision (must be a number, not *). */ 3873 arg_parser.read_any_format_left_precision (); 3874 3875 /* Read any format precision, possibly * or *m$. */ 3876 if (!arg_parser.read_any_format_precision (params, arg_num)) 3877 return; 3878 3879 const char *format_start = format_chars; 3880 3881 arg_parser.handle_alloc_chars (); 3882 3883 /* The rest of the conversion specification is the length modifier 3884 (if any), and the conversion specifier, so this is where the 3885 type information starts. If we need to issue a suggestion 3886 about a type mismatch, then we should preserve everything up 3887 to here. */ 3888 const char *type_start = format_chars; 3889 3890 /* Read any length modifier, if this kind of format has them. */ 3891 const length_modifier len_modifier 3892 = arg_parser.read_any_length_modifier (); 3893 3894 /* Read any modifier (strftime E/O). */ 3895 arg_parser.read_any_other_modifier (); 3896 3897 char format_char = *format_chars; 3898 if (format_char == 0 3899 || (!(fki->flags & (int) FMT_FLAG_FANCY_PERCENT_OK) 3900 && format_char == '%')) 3901 { 3902 format_warning_at_char (format_string_loc, format_string_cst, 3903 format_chars - orig_format_chars, 3904 OPT_Wformat_, 3905 "conversion lacks type at end of format"); 3906 continue; 3907 } 3908 3909 if (format_char == 'm' && !(fki->flags & FMT_FLAG_M_OK)) 3910 { 3911 warning (OPT_Wformat_, 3912 "%%m is only allowed in syslog(3) like functions"); 3913 continue; 3914 } 3915 3916 format_chars++; 3917 3918 const format_char_info * const fci 3919 = arg_parser.find_format_char_info (format_char); 3920 if (!fci) 3921 continue; 3922 3923 flag_chars.validate (fki, fci, flag_specs, format_chars, 3924 format_string_cst, 3925 format_string_loc, orig_format_chars, format_char, 3926 baltoks.quotdirs.length () > 0); 3927 3928 const int alloc_flag = flag_chars.get_alloc_flag (fki); 3929 const bool suppressed = flag_chars.assignment_suppression_p (fki); 3930 3931 /* Diagnose nested or unmatched quoting directives such as GCC's 3932 "%<...%<" and "%>...%>". */ 3933 bool quot_begin_p = strchr (fci->flags2, '<'); 3934 bool quot_end_p = strchr (fci->flags2, '>'); 3935 3936 if (quot_begin_p && !quot_end_p) 3937 { 3938 if (baltoks.quotdirs.length ()) 3939 format_warning_at_char (format_string_loc, format_string_cst, 3940 format_chars - orig_format_chars, 3941 OPT_Wformat_, 3942 "nested quoting directive"); 3943 baltoks.quotdirs.safe_push (format_chars); 3944 } 3945 else if (!quot_begin_p && quot_end_p) 3946 { 3947 if (baltoks.quotdirs.length ()) 3948 baltoks.quotdirs.pop (); 3949 else 3950 format_warning_at_char (format_string_loc, format_string_cst, 3951 format_chars - orig_format_chars, 3952 OPT_Wformat_, 3953 "unmatched quoting directive"); 3954 } 3955 3956 bool color_begin_p = strchr (fci->flags2, '/'); 3957 if (color_begin_p) 3958 { 3959 color_begin = format_chars; 3960 color_end = NULL; 3961 } 3962 else if (strchr (fci->flags2, '\\')) 3963 { 3964 if (color_end) 3965 format_warning_at_char (format_string_loc, format_string_cst, 3966 format_chars - orig_format_chars, 3967 OPT_Wformat_, 3968 "%qc directive redundant after prior " 3969 "occurence of the same", format_char); 3970 else if (!color_begin) 3971 format_warning_at_char (format_string_loc, format_string_cst, 3972 format_chars - orig_format_chars, 3973 OPT_Wformat_, 3974 "unmatched color reset directive"); 3975 color_end = format_chars; 3976 } 3977 3978 /* Diagnose directives that shouldn't appear in a quoted sequence. 3979 (They are denoted by a double quote in FLAGS2.) */ 3980 if (baltoks.quotdirs.length ()) 3981 { 3982 if (strchr (fci->flags2, '"')) 3983 format_warning_at_char (format_string_loc, format_string_cst, 3984 format_chars - orig_format_chars, 3985 OPT_Wformat_, 3986 "%qc conversion used within a quoted " 3987 "sequence", 3988 format_char); 3989 } 3990 3991 /* Validate the pairs of flags used. */ 3992 arg_parser.validate_flag_pairs (fci, format_char); 3993 3994 arg_parser.give_y2k_warnings (fci, format_char); 3995 3996 arg_parser.parse_any_scan_set (fci); 3997 3998 tree wanted_type = NULL; 3999 const char *wanted_type_name = NULL; 4000 4001 if (!arg_parser.handle_conversions (fci, len_modifier, 4002 wanted_type, wanted_type_name, 4003 arg_num, 4004 params, 4005 format_char)) 4006 continue; 4007 4008 arg_parser.main_wanted_type.next = NULL; 4009 4010 /* Finally. . .check type of argument against desired type! */ 4011 if (!arg_parser.check_argument_type (fci, len_modifier, 4012 wanted_type, wanted_type_name, 4013 suppressed, 4014 arg_num, params, 4015 alloc_flag, 4016 format_start, type_start, 4017 fmt_param_loc, 4018 format_char)) 4019 return; 4020 } 4021 4022 if (format_chars - orig_format_chars != format_length) 4023 format_warning_at_char (format_string_loc, format_string_cst, 4024 format_chars + 1 - orig_format_chars, 4025 OPT_Wformat_contains_nul, 4026 "embedded %<\\0%> in format"); 4027 if (info->first_arg_num != 0 && params != 0 4028 && has_operand_number <= 0) 4029 { 4030 res->number_other--; 4031 res->number_extra_args++; 4032 } 4033 if (has_operand_number > 0) 4034 finish_dollar_format_checking (res, fki->flags & (int) FMT_FLAG_DOLLAR_GAP_POINTER_OK); 4035 4036 maybe_diag_unbalanced_tokens (format_string_loc, orig_format_chars, 4037 format_string_cst, baltoks); 4038 4039 if (color_begin && !color_end) 4040 format_warning_at_char (format_string_loc, format_string_cst, 4041 color_begin - orig_format_chars, 4042 OPT_Wformat_, "unterminated color directive"); 4043 } 4044 4045 /* Check the argument types from a single format conversion (possibly 4046 including width and precision arguments). 4047 4048 FMT_LOC is the location of the format conversion. 4049 4050 TYPES is a singly-linked list expressing the parts of the format 4051 conversion that expect argument types, and the arguments they 4052 correspond to. 4053 4054 OFFSET_TO_TYPE_START is the offset within the execution-charset encoded 4055 format string to where type information begins for the conversion 4056 (the length modifier and conversion specifier). 4057 4058 CONVERSION_CHAR is the user-provided conversion specifier. 4059 4060 For example, given: 4061 4062 sprintf (d, "before %-+*.*lld after", arg3, arg4, arg5); 4063 4064 then FMT_LOC covers this range: 4065 4066 sprintf (d, "before %-+*.*lld after", arg3, arg4, arg5); 4067 ^^^^^^^^^ 4068 4069 and TYPES in this case is a three-entry singly-linked list consisting of: 4070 (1) the check for the field width here: 4071 sprintf (d, "before %-+*.*lld after", arg3, arg4, arg5); 4072 ^ ^^^^ 4073 against arg3, and 4074 (2) the check for the field precision here: 4075 sprintf (d, "before %-+*.*lld after", arg3, arg4, arg5); 4076 ^^ ^^^^ 4077 against arg4, and 4078 (3) the check for the length modifier and conversion char here: 4079 sprintf (d, "before %-+*.*lld after", arg3, arg4, arg5); 4080 ^^^ ^^^^ 4081 against arg5. 4082 4083 OFFSET_TO_TYPE_START is 13, the offset to the "lld" within the 4084 STRING_CST: 4085 4086 0000000000111111111122 4087 0123456789012345678901 4088 sprintf (d, "before %-+*.*lld after", arg3, arg4, arg5); 4089 ^ ^ 4090 | ` CONVERSION_CHAR: 'd' 4091 type starts here. */ 4092 4093 static void 4094 check_format_types (const substring_loc &fmt_loc, 4095 format_wanted_type *types, const format_kind_info *fki, 4096 int offset_to_type_start, 4097 char conversion_char, 4098 vec<location_t> *arglocs) 4099 { 4100 for (; types != 0; types = types->next) 4101 { 4102 tree cur_param; 4103 tree cur_type; 4104 tree orig_cur_type; 4105 tree wanted_type; 4106 int arg_num; 4107 int i; 4108 int char_type_flag; 4109 4110 wanted_type = types->wanted_type; 4111 arg_num = types->arg_num; 4112 4113 /* The following should not occur here. */ 4114 gcc_assert (wanted_type); 4115 gcc_assert (wanted_type != void_type_node || types->pointer_count); 4116 4117 if (types->pointer_count == 0) 4118 wanted_type = lang_hooks.types.type_promotes_to (wanted_type); 4119 4120 wanted_type = TYPE_MAIN_VARIANT (wanted_type); 4121 4122 cur_param = types->param; 4123 if (!cur_param) 4124 { 4125 format_type_warning (fmt_loc, UNKNOWN_LOCATION, types, wanted_type, 4126 NULL, fki, offset_to_type_start, 4127 conversion_char); 4128 continue; 4129 } 4130 4131 cur_type = TREE_TYPE (cur_param); 4132 if (cur_type == error_mark_node) 4133 continue; 4134 orig_cur_type = cur_type; 4135 char_type_flag = 0; 4136 4137 location_t param_loc = UNKNOWN_LOCATION; 4138 if (EXPR_HAS_LOCATION (cur_param)) 4139 param_loc = EXPR_LOCATION (cur_param); 4140 else if (arglocs) 4141 { 4142 /* arg_num is 1-based. */ 4143 gcc_assert (types->arg_num > 0); 4144 param_loc = (*arglocs)[types->arg_num - 1]; 4145 } 4146 4147 STRIP_NOPS (cur_param); 4148 4149 /* Check the types of any additional pointer arguments 4150 that precede the "real" argument. */ 4151 for (i = 0; i < types->pointer_count; ++i) 4152 { 4153 if (TREE_CODE (cur_type) == POINTER_TYPE) 4154 { 4155 cur_type = TREE_TYPE (cur_type); 4156 if (cur_type == error_mark_node) 4157 break; 4158 4159 /* Check for writing through a NULL pointer. */ 4160 if (types->writing_in_flag 4161 && i == 0 4162 && cur_param != 0 4163 && integer_zerop (cur_param)) 4164 warning (OPT_Wformat_, "writing through null pointer " 4165 "(argument %d)", arg_num); 4166 4167 /* Check for reading through a NULL pointer. Ignore 4168 printf-family of functions as they are checked for 4169 null arguments by the middle-end. */ 4170 if (fki->conversion_specs != print_char_table 4171 && types->reading_from_flag 4172 && i == 0 4173 && cur_param != 0 4174 && integer_zerop (cur_param)) 4175 warning (OPT_Wformat_, "reading through null pointer " 4176 "(argument %d)", arg_num); 4177 4178 if (cur_param != 0 && TREE_CODE (cur_param) == ADDR_EXPR) 4179 cur_param = TREE_OPERAND (cur_param, 0); 4180 else 4181 cur_param = 0; 4182 4183 /* See if this is an attempt to write into a const type with 4184 scanf or with printf "%n". Note: the writing in happens 4185 at the first indirection only, if for example 4186 void * const * is passed to scanf %p; passing 4187 const void ** is simply passing an incompatible type. */ 4188 if (types->writing_in_flag 4189 && i == 0 4190 && (TYPE_READONLY (cur_type) 4191 || (cur_param != 0 4192 && (CONSTANT_CLASS_P (cur_param) 4193 || (DECL_P (cur_param) 4194 && TREE_READONLY (cur_param)))))) 4195 warning (OPT_Wformat_, "writing into constant object " 4196 "(argument %d)", arg_num); 4197 4198 /* If there are extra type qualifiers beyond the first 4199 indirection, then this makes the types technically 4200 incompatible. */ 4201 if (i > 0 4202 && pedantic 4203 && (TYPE_READONLY (cur_type) 4204 || TYPE_VOLATILE (cur_type) 4205 || TYPE_ATOMIC (cur_type) 4206 || TYPE_RESTRICT (cur_type))) 4207 warning (OPT_Wformat_, "extra type qualifiers in format " 4208 "argument (argument %d)", 4209 arg_num); 4210 4211 } 4212 else 4213 { 4214 format_type_warning (fmt_loc, param_loc, 4215 types, wanted_type, orig_cur_type, fki, 4216 offset_to_type_start, conversion_char); 4217 break; 4218 } 4219 } 4220 4221 if (i < types->pointer_count) 4222 continue; 4223 4224 cur_type = TYPE_MAIN_VARIANT (cur_type); 4225 4226 /* Check whether the argument type is a character type. This leniency 4227 only applies to certain formats, flagged with 'c'. */ 4228 if (types->char_lenient_flag) 4229 char_type_flag = (cur_type == char_type_node 4230 || cur_type == signed_char_type_node 4231 || cur_type == unsigned_char_type_node); 4232 4233 /* Check the type of the "real" argument, if there's a type we want. */ 4234 if (lang_hooks.types_compatible_p (wanted_type, cur_type)) 4235 continue; 4236 /* If we want 'void *', allow any pointer type. 4237 (Anything else would already have got a warning.) 4238 With -Wpedantic, only allow pointers to void and to character 4239 types. */ 4240 if (wanted_type == void_type_node 4241 && (!pedantic || (i == 1 && char_type_flag))) 4242 continue; 4243 /* Don't warn about differences merely in signedness, unless 4244 -Wpedantic. With -Wpedantic, warn if the type is a pointer 4245 target and not a character type, and for character types at 4246 a second level of indirection. */ 4247 if (TREE_CODE (wanted_type) == INTEGER_TYPE 4248 && TREE_CODE (cur_type) == INTEGER_TYPE 4249 && ((!pedantic && !warn_format_signedness) 4250 || (i == 0 && !warn_format_signedness) 4251 || (i == 1 && char_type_flag)) 4252 && (TYPE_UNSIGNED (wanted_type) 4253 ? wanted_type == c_common_unsigned_type (cur_type) 4254 : wanted_type == c_common_signed_type (cur_type))) 4255 continue; 4256 /* Don't warn about differences merely in signedness if we know 4257 that the current type is integer-promoted and its original type 4258 was unsigned such as that it is in the range of WANTED_TYPE. */ 4259 if (TREE_CODE (wanted_type) == INTEGER_TYPE 4260 && TREE_CODE (cur_type) == INTEGER_TYPE 4261 && warn_format_signedness 4262 && TYPE_UNSIGNED (wanted_type) 4263 && cur_param != NULL_TREE 4264 && TREE_CODE (cur_param) == NOP_EXPR) 4265 { 4266 tree t = TREE_TYPE (TREE_OPERAND (cur_param, 0)); 4267 if (TYPE_UNSIGNED (t) 4268 && cur_type == lang_hooks.types.type_promotes_to (t)) 4269 continue; 4270 } 4271 /* Likewise, "signed char", "unsigned char" and "char" are 4272 equivalent but the above test won't consider them equivalent. */ 4273 if (wanted_type == char_type_node 4274 && (!pedantic || i < 2) 4275 && char_type_flag) 4276 continue; 4277 if (types->scalar_identity_flag 4278 && (TREE_CODE (cur_type) == TREE_CODE (wanted_type) 4279 || (INTEGRAL_TYPE_P (cur_type) 4280 && INTEGRAL_TYPE_P (wanted_type))) 4281 && TYPE_PRECISION (cur_type) == TYPE_PRECISION (wanted_type)) 4282 continue; 4283 /* Now we have a type mismatch. */ 4284 format_type_warning (fmt_loc, param_loc, types, 4285 wanted_type, orig_cur_type, fki, 4286 offset_to_type_start, conversion_char); 4287 } 4288 } 4289 4290 /* Given type TYPE, attempt to dereference the type N times 4291 (e.g. from ("int ***", 2) to "int *") 4292 4293 Return the derefenced type, with any qualifiers 4294 such as "const" stripped from the result, or 4295 NULL if unsuccessful (e.g. TYPE is not a pointer type). */ 4296 4297 static tree 4298 deref_n_times (tree type, int n) 4299 { 4300 gcc_assert (type); 4301 4302 for (int i = n; i > 0; i--) 4303 { 4304 if (TREE_CODE (type) != POINTER_TYPE) 4305 return NULL_TREE; 4306 type = TREE_TYPE (type); 4307 } 4308 /* Strip off any "const" etc. */ 4309 return build_qualified_type (type, 0); 4310 } 4311 4312 /* Lookup the format code for FORMAT_LEN within FLI, 4313 returning the string code for expressing it, or NULL 4314 if it is not found. */ 4315 4316 static const char * 4317 get_modifier_for_format_len (const format_length_info *fli, 4318 enum format_lengths format_len) 4319 { 4320 for (; fli->name; fli++) 4321 { 4322 if (fli->index == format_len) 4323 return fli->name; 4324 if (fli->double_index == format_len) 4325 return fli->double_name; 4326 } 4327 return NULL; 4328 } 4329 4330 #if CHECKING_P 4331 4332 namespace selftest { 4333 4334 static void 4335 test_get_modifier_for_format_len () 4336 { 4337 ASSERT_STREQ ("h", 4338 get_modifier_for_format_len (printf_length_specs, FMT_LEN_h)); 4339 ASSERT_STREQ ("hh", 4340 get_modifier_for_format_len (printf_length_specs, FMT_LEN_hh)); 4341 ASSERT_STREQ ("L", 4342 get_modifier_for_format_len (printf_length_specs, FMT_LEN_L)); 4343 ASSERT_EQ (NULL, 4344 get_modifier_for_format_len (printf_length_specs, FMT_LEN_none)); 4345 } 4346 4347 } // namespace selftest 4348 4349 #endif /* CHECKING_P */ 4350 4351 /* Determine if SPEC_TYPE and ARG_TYPE are sufficiently similar for a 4352 format_type_detail using SPEC_TYPE to be offered as a suggestion for 4353 Wformat type errors where the argument has type ARG_TYPE. */ 4354 4355 static bool 4356 matching_type_p (tree spec_type, tree arg_type) 4357 { 4358 gcc_assert (spec_type); 4359 gcc_assert (arg_type); 4360 4361 /* If any of the types requires structural equality, we can't compare 4362 their canonical types. */ 4363 if (TYPE_STRUCTURAL_EQUALITY_P (spec_type) 4364 || TYPE_STRUCTURAL_EQUALITY_P (arg_type)) 4365 return false; 4366 4367 spec_type = TYPE_CANONICAL (spec_type); 4368 arg_type = TYPE_CANONICAL (arg_type); 4369 4370 if (TREE_CODE (spec_type) == INTEGER_TYPE 4371 && TREE_CODE (arg_type) == INTEGER_TYPE 4372 && (TYPE_UNSIGNED (spec_type) 4373 ? spec_type == c_common_unsigned_type (arg_type) 4374 : spec_type == c_common_signed_type (arg_type))) 4375 return true; 4376 4377 return spec_type == arg_type; 4378 } 4379 4380 /* Subroutine of get_format_for_type. 4381 4382 Generate a string containing the length modifier and conversion specifier 4383 that should be used to format arguments of type ARG_TYPE within FKI 4384 (effectively the inverse of the checking code). 4385 4386 If CONVERSION_CHAR is not zero (the first pass), the resulting suggestion 4387 is required to use it, for correcting bogus length modifiers. 4388 If CONVERSION_CHAR is zero (the second pass), then allow any suggestion 4389 that matches ARG_TYPE. 4390 4391 If successful, returns a non-NULL string which should be freed 4392 by the caller. 4393 Otherwise, returns NULL. */ 4394 4395 static char * 4396 get_format_for_type_1 (const format_kind_info *fki, tree arg_type, 4397 char conversion_char) 4398 { 4399 gcc_assert (arg_type); 4400 4401 const format_char_info *spec; 4402 for (spec = &fki->conversion_specs[0]; 4403 spec->format_chars; 4404 spec++) 4405 { 4406 if (conversion_char) 4407 if (!strchr (spec->format_chars, conversion_char)) 4408 continue; 4409 4410 tree effective_arg_type = deref_n_times (arg_type, 4411 spec->pointer_count); 4412 if (!effective_arg_type) 4413 continue; 4414 for (int i = 0; i < FMT_LEN_MAX; i++) 4415 { 4416 const format_type_detail *ftd = &spec->types[i]; 4417 if (!ftd->type || *ftd->type == NULL_TREE) 4418 continue; 4419 if (matching_type_p (*ftd->type, effective_arg_type)) 4420 { 4421 const char *len_modifier 4422 = get_modifier_for_format_len (fki->length_char_specs, 4423 (enum format_lengths)i); 4424 if (!len_modifier) 4425 len_modifier = ""; 4426 4427 if (conversion_char) 4428 /* We found a match, using the given conversion char - the 4429 length modifier was incorrect (or absent). 4430 Provide a suggestion using the conversion char with the 4431 correct length modifier for the type. */ 4432 return xasprintf ("%s%c", len_modifier, conversion_char); 4433 else 4434 /* 2nd pass: no match was possible using the user-provided 4435 conversion char, but we do have a match without using it. 4436 Provide a suggestion using the first conversion char 4437 listed for the given type. */ 4438 return xasprintf ("%s%c", len_modifier, spec->format_chars[0]); 4439 } 4440 } 4441 } 4442 4443 return NULL; 4444 } 4445 4446 /* Generate a string containing the length modifier and conversion specifier 4447 that should be used to format arguments of type ARG_TYPE within FKI 4448 (effectively the inverse of the checking code). 4449 4450 If successful, returns a non-NULL string which should be freed 4451 by the caller. 4452 Otherwise, returns NULL. */ 4453 4454 static char * 4455 get_format_for_type (const format_kind_info *fki, tree arg_type, 4456 char conversion_char) 4457 { 4458 gcc_assert (arg_type); 4459 gcc_assert (conversion_char); 4460 4461 /* First pass: look for a format_char_info containing CONVERSION_CHAR 4462 If we find one, then presumably the length modifier was incorrect 4463 (or absent). */ 4464 char *result = get_format_for_type_1 (fki, arg_type, conversion_char); 4465 if (result) 4466 return result; 4467 4468 /* Second pass: we didn't find a match for CONVERSION_CHAR, so try 4469 matching just on the type. */ 4470 return get_format_for_type_1 (fki, arg_type, '\0'); 4471 } 4472 4473 /* Attempt to get a string for use as a replacement fix-it hint for the 4474 source range in FMT_LOC. 4475 4476 Preserve all of the text within the range of FMT_LOC up to 4477 OFFSET_TO_TYPE_START, replacing the rest with an appropriate 4478 length modifier and conversion specifier for ARG_TYPE, attempting 4479 to keep the user-provided CONVERSION_CHAR if possible. 4480 4481 For example, given a long vs long long mismatch for arg5 here: 4482 4483 000000000111111111122222222223333333333| 4484 123456789012345678901234567890123456789` column numbers 4485 0000000000111111111122| 4486 0123456789012345678901` string offsets 4487 V~~~~~~~~ : range of FMT_LOC, from cols 23-31 4488 sprintf (d, "before %-+*.*lld after", arg3, arg4, arg5); 4489 ^ ^ 4490 | ` CONVERSION_CHAR: 'd' 4491 type starts here 4492 4493 where OFFSET_TO_TYPE_START is 13 (the offset to the "lld" within the 4494 STRING_CST), where the user provided: 4495 %-+*.*lld 4496 the result (assuming "long" argument 5) should be: 4497 %-+*.*ld 4498 4499 If successful, returns a non-NULL string which should be freed 4500 by the caller. 4501 Otherwise, returns NULL. */ 4502 4503 static char * 4504 get_corrected_substring (const substring_loc &fmt_loc, 4505 format_wanted_type *type, tree arg_type, 4506 const format_kind_info *fki, 4507 int offset_to_type_start, char conversion_char) 4508 { 4509 /* Attempt to provide hints for argument types, but not for field widths 4510 and precisions. */ 4511 if (!arg_type) 4512 return NULL; 4513 if (type->kind != CF_KIND_FORMAT) 4514 return NULL; 4515 4516 /* Locate the current code within the source range, rejecting 4517 any awkward cases where the format string occupies more than 4518 one line. 4519 Lookup the place where the type starts (including any length 4520 modifiers), getting it as the caret location. */ 4521 substring_loc type_loc (fmt_loc); 4522 type_loc.set_caret_index (offset_to_type_start); 4523 4524 location_t fmt_substring_loc; 4525 const char *err = type_loc.get_location (&fmt_substring_loc); 4526 if (err) 4527 return NULL; 4528 4529 source_range fmt_substring_range 4530 = get_range_from_loc (line_table, fmt_substring_loc); 4531 4532 expanded_location caret 4533 = expand_location_to_spelling_point (fmt_substring_loc); 4534 expanded_location start 4535 = expand_location_to_spelling_point (fmt_substring_range.m_start); 4536 expanded_location finish 4537 = expand_location_to_spelling_point (fmt_substring_range.m_finish); 4538 if (caret.file != start.file) 4539 return NULL; 4540 if (start.file != finish.file) 4541 return NULL; 4542 if (caret.line != start.line) 4543 return NULL; 4544 if (start.line != finish.line) 4545 return NULL; 4546 if (start.column > caret.column) 4547 return NULL; 4548 if (start.column > finish.column) 4549 return NULL; 4550 if (caret.column > finish.column) 4551 return NULL; 4552 4553 char_span line = location_get_source_line (start.file, start.line); 4554 if (!line) 4555 return NULL; 4556 4557 /* If we got this far, then we have the line containing the 4558 existing conversion specification. 4559 4560 Generate a trimmed copy, containing the prefix part of the conversion 4561 specification, up to the (but not including) the length modifier. 4562 In the above example, this would be "%-+*.*". */ 4563 int length_up_to_type = caret.column - start.column; 4564 char_span prefix_span = line.subspan (start.column - 1, length_up_to_type); 4565 char *prefix = prefix_span.xstrdup (); 4566 4567 /* Now attempt to generate a suggestion for the rest of the specification 4568 (length modifier and conversion char), based on ARG_TYPE and 4569 CONVERSION_CHAR. 4570 In the above example, this would be "ld". */ 4571 char *format_for_type = get_format_for_type (fki, arg_type, conversion_char); 4572 if (!format_for_type) 4573 { 4574 free (prefix); 4575 return NULL; 4576 } 4577 4578 /* Success. Generate the resulting suggestion for the whole range of 4579 FMT_LOC by concatenating the two strings. 4580 In the above example, this would be "%-+*.*ld". */ 4581 char *result = concat (prefix, format_for_type, NULL); 4582 free (format_for_type); 4583 free (prefix); 4584 return result; 4585 } 4586 4587 /* Helper class for adding zero or more trailing '*' to types. 4588 4589 The format type and name exclude any '*' for pointers, so those 4590 must be formatted manually. For all the types we currently have, 4591 this is adequate, but formats taking pointers to functions or 4592 arrays would require the full type to be built up in order to 4593 print it with %T. */ 4594 4595 class indirection_suffix 4596 { 4597 public: 4598 indirection_suffix (int pointer_count) : m_pointer_count (pointer_count) {} 4599 4600 /* Determine the size of the buffer (including NUL-terminator). */ 4601 4602 size_t get_buffer_size () const 4603 { 4604 return m_pointer_count + 2; 4605 } 4606 4607 /* Write the '*' to DST and add a NUL-terminator. */ 4608 4609 void fill_buffer (char *dst) const 4610 { 4611 if (m_pointer_count == 0) 4612 dst[0] = 0; 4613 else if (c_dialect_cxx ()) 4614 { 4615 memset (dst, '*', m_pointer_count); 4616 dst[m_pointer_count] = 0; 4617 } 4618 else 4619 { 4620 dst[0] = ' '; 4621 memset (dst + 1, '*', m_pointer_count); 4622 dst[m_pointer_count + 1] = 0; 4623 } 4624 } 4625 4626 private: 4627 int m_pointer_count; 4628 }; 4629 4630 /* Subclass of range_label for labelling the range in the format string 4631 with the type in question, adding trailing '*' for pointer_count. */ 4632 4633 class range_label_for_format_type_mismatch 4634 : public range_label_for_type_mismatch 4635 { 4636 public: 4637 range_label_for_format_type_mismatch (tree labelled_type, tree other_type, 4638 int pointer_count) 4639 : range_label_for_type_mismatch (labelled_type, other_type), 4640 m_pointer_count (pointer_count) 4641 { 4642 } 4643 4644 label_text get_text (unsigned range_idx) const FINAL OVERRIDE 4645 { 4646 label_text text = range_label_for_type_mismatch::get_text (range_idx); 4647 if (text.m_buffer == NULL) 4648 return text; 4649 4650 indirection_suffix suffix (m_pointer_count); 4651 char *p = (char *) alloca (suffix.get_buffer_size ()); 4652 suffix.fill_buffer (p); 4653 4654 char *result = concat (text.m_buffer, p, NULL); 4655 text.maybe_free (); 4656 return label_text::take (result); 4657 } 4658 4659 private: 4660 int m_pointer_count; 4661 }; 4662 4663 /* Give a warning about a format argument of different type from that expected. 4664 The range of the diagnostic is taken from WHOLE_FMT_LOC; the caret location 4665 is based on the location of the char at TYPE->offset_loc. 4666 PARAM_LOC is the location of the relevant argument, or UNKNOWN_LOCATION 4667 if this is unavailable. 4668 WANTED_TYPE is the type the argument should have, 4669 possibly stripped of pointer dereferences. The description (such as "field 4670 precision"), the placement in the format string, a possibly more 4671 friendly name of WANTED_TYPE, and the number of pointer dereferences 4672 are taken from TYPE. ARG_TYPE is the type of the actual argument, 4673 or NULL if it is missing. 4674 4675 OFFSET_TO_TYPE_START is the offset within the execution-charset encoded 4676 format string to where type information begins for the conversion 4677 (the length modifier and conversion specifier). 4678 CONVERSION_CHAR is the user-provided conversion specifier. 4679 4680 For example, given a type mismatch for argument 5 here: 4681 4682 00000000011111111112222222222333333333344444444445555555555| 4683 12345678901234567890123456789012345678901234567890123456789` column numbers 4684 0000000000111111111122| 4685 0123456789012345678901` offsets within STRING_CST 4686 V~~~~~~~~ : range of WHOLE_FMT_LOC, from cols 23-31 4687 sprintf (d, "before %-+*.*lld after", int_expr, int_expr, long_expr); 4688 ^ ^ ^~~~~~~~~ 4689 | ` CONVERSION_CHAR: 'd' PARAM_LOC 4690 type starts here 4691 4692 OFFSET_TO_TYPE_START is 13, the offset to the "lld" within the 4693 STRING_CST. */ 4694 4695 static void 4696 format_type_warning (const substring_loc &whole_fmt_loc, 4697 location_t param_loc, 4698 format_wanted_type *type, 4699 tree wanted_type, tree arg_type, 4700 const format_kind_info *fki, 4701 int offset_to_type_start, 4702 char conversion_char) 4703 { 4704 enum format_specifier_kind kind = type->kind; 4705 const char *wanted_type_name = type->wanted_type_name; 4706 const char *format_start = type->format_start; 4707 int format_length = type->format_length; 4708 int pointer_count = type->pointer_count; 4709 int arg_num = type->arg_num; 4710 4711 /* If ARG_TYPE is a typedef with a misleading name (for example, 4712 size_t but not the standard size_t expected by printf %zu), avoid 4713 printing the typedef name. */ 4714 if (wanted_type_name 4715 && arg_type 4716 && TYPE_NAME (arg_type) 4717 && TREE_CODE (TYPE_NAME (arg_type)) == TYPE_DECL 4718 && DECL_NAME (TYPE_NAME (arg_type)) 4719 && !strcmp (wanted_type_name, 4720 lang_hooks.decl_printable_name (TYPE_NAME (arg_type), 2))) 4721 arg_type = TYPE_MAIN_VARIANT (arg_type); 4722 4723 indirection_suffix suffix (pointer_count); 4724 char *p = (char *) alloca (suffix.get_buffer_size ()); 4725 suffix.fill_buffer (p); 4726 4727 /* WHOLE_FMT_LOC has the caret at the end of the range. 4728 Set the caret to be at the offset from TYPE. Subtract one 4729 from the offset for the same reason as in format_warning_at_char. */ 4730 substring_loc fmt_loc (whole_fmt_loc); 4731 fmt_loc.set_caret_index (type->offset_loc - 1); 4732 4733 range_label_for_format_type_mismatch fmt_label (wanted_type, arg_type, 4734 pointer_count); 4735 range_label_for_type_mismatch param_label (arg_type, wanted_type); 4736 4737 /* Get a string for use as a replacement fix-it hint for the range in 4738 fmt_loc, or NULL. */ 4739 char *corrected_substring 4740 = get_corrected_substring (fmt_loc, type, arg_type, fki, 4741 offset_to_type_start, conversion_char); 4742 format_string_diagnostic_t diag (fmt_loc, &fmt_label, param_loc, ¶m_label, 4743 corrected_substring); 4744 if (wanted_type_name) 4745 { 4746 if (arg_type) 4747 diag.emit_warning 4748 (OPT_Wformat_, 4749 "%s %<%s%.*s%> expects argument of type %<%s%s%>, " 4750 "but argument %d has type %qT", 4751 gettext (kind_descriptions[kind]), 4752 (kind == CF_KIND_FORMAT ? "%" : ""), 4753 format_length, format_start, 4754 wanted_type_name, p, arg_num, arg_type); 4755 else 4756 diag.emit_warning 4757 (OPT_Wformat_, 4758 "%s %<%s%.*s%> expects a matching %<%s%s%> argument", 4759 gettext (kind_descriptions[kind]), 4760 (kind == CF_KIND_FORMAT ? "%" : ""), 4761 format_length, format_start, wanted_type_name, p); 4762 } 4763 else 4764 { 4765 if (arg_type) 4766 diag.emit_warning 4767 (OPT_Wformat_, 4768 "%s %<%s%.*s%> expects argument of type %<%T%s%>, " 4769 "but argument %d has type %qT", 4770 gettext (kind_descriptions[kind]), 4771 (kind == CF_KIND_FORMAT ? "%" : ""), 4772 format_length, format_start, 4773 wanted_type, p, arg_num, arg_type); 4774 else 4775 diag.emit_warning 4776 (OPT_Wformat_, 4777 "%s %<%s%.*s%> expects a matching %<%T%s%> argument", 4778 gettext (kind_descriptions[kind]), 4779 (kind == CF_KIND_FORMAT ? "%" : ""), 4780 format_length, format_start, wanted_type, p); 4781 } 4782 4783 free (corrected_substring); 4784 } 4785 4786 4787 /* Given a format_char_info array FCI, and a character C, this function 4788 returns the index into the conversion_specs where that specifier's 4789 data is located. The character must exist. */ 4790 static unsigned int 4791 find_char_info_specifier_index (const format_char_info *fci, int c) 4792 { 4793 unsigned i; 4794 4795 for (i = 0; fci->format_chars; i++, fci++) 4796 if (strchr (fci->format_chars, c)) 4797 return i; 4798 4799 /* We shouldn't be looking for a non-existent specifier. */ 4800 gcc_unreachable (); 4801 } 4802 4803 /* Given a format_length_info array FLI, and a character C, this 4804 function returns the index into the conversion_specs where that 4805 modifier's data is located. The character must exist. */ 4806 static unsigned int 4807 find_length_info_modifier_index (const format_length_info *fli, int c) 4808 { 4809 unsigned i; 4810 4811 for (i = 0; fli->name; i++, fli++) 4812 if (strchr (fli->name, c)) 4813 return i; 4814 4815 /* We shouldn't be looking for a non-existent modifier. */ 4816 gcc_unreachable (); 4817 } 4818 4819 /* Determine the type of HOST_WIDE_INT in the code being compiled for 4820 use in GCC's __asm_fprintf__ custom format attribute. You must 4821 have set dynamic_format_types before calling this function. */ 4822 static void 4823 init_dynamic_asm_fprintf_info (void) 4824 { 4825 static tree hwi; 4826 4827 if (!hwi) 4828 { 4829 format_length_info *new_asm_fprintf_length_specs; 4830 unsigned int i; 4831 4832 /* Find the underlying type for HOST_WIDE_INT. For the %w 4833 length modifier to work, one must have issued: "typedef 4834 HOST_WIDE_INT __gcc_host_wide_int__;" in one's source code 4835 prior to using that modifier. */ 4836 hwi = maybe_get_identifier ("__gcc_host_wide_int__"); 4837 if (!hwi) 4838 { 4839 error ("%<__gcc_host_wide_int__%> is not defined as a type"); 4840 return; 4841 } 4842 hwi = identifier_global_value (hwi); 4843 if (!hwi || TREE_CODE (hwi) != TYPE_DECL) 4844 { 4845 error ("%<__gcc_host_wide_int__%> is not defined as a type"); 4846 return; 4847 } 4848 hwi = DECL_ORIGINAL_TYPE (hwi); 4849 gcc_assert (hwi); 4850 if (hwi != long_integer_type_node && hwi != long_long_integer_type_node) 4851 { 4852 error ("%<__gcc_host_wide_int__%> is not defined as %<long%>" 4853 " or %<long long%>"); 4854 return; 4855 } 4856 4857 /* Create a new (writable) copy of asm_fprintf_length_specs. */ 4858 new_asm_fprintf_length_specs = (format_length_info *) 4859 xmemdup (asm_fprintf_length_specs, 4860 sizeof (asm_fprintf_length_specs), 4861 sizeof (asm_fprintf_length_specs)); 4862 4863 /* HOST_WIDE_INT must be one of 'long' or 'long long'. */ 4864 i = find_length_info_modifier_index (new_asm_fprintf_length_specs, 'w'); 4865 if (hwi == long_integer_type_node) 4866 new_asm_fprintf_length_specs[i].index = FMT_LEN_l; 4867 else if (hwi == long_long_integer_type_node) 4868 new_asm_fprintf_length_specs[i].index = FMT_LEN_ll; 4869 else 4870 gcc_unreachable (); 4871 4872 /* Assign the new data for use. */ 4873 dynamic_format_types[asm_fprintf_format_type].length_char_specs = 4874 new_asm_fprintf_length_specs; 4875 } 4876 } 4877 4878 static const format_length_info* 4879 get_init_dynamic_hwi (void) 4880 { 4881 static tree hwi; 4882 static format_length_info *diag_ls; 4883 4884 if (!hwi) 4885 { 4886 unsigned int i; 4887 4888 /* Find the underlying type for HOST_WIDE_INT. For the 'w' 4889 length modifier to work, one must have issued: "typedef 4890 HOST_WIDE_INT __gcc_host_wide_int__;" in one's source code 4891 prior to using that modifier. */ 4892 if ((hwi = maybe_get_identifier ("__gcc_host_wide_int__"))) 4893 { 4894 hwi = identifier_global_value (hwi); 4895 if (hwi) 4896 { 4897 if (TREE_CODE (hwi) != TYPE_DECL) 4898 { 4899 error ("%<__gcc_host_wide_int__%> is not defined as a type"); 4900 hwi = 0; 4901 } 4902 else 4903 { 4904 hwi = DECL_ORIGINAL_TYPE (hwi); 4905 gcc_assert (hwi); 4906 if (hwi != long_integer_type_node 4907 && hwi != long_long_integer_type_node) 4908 { 4909 error ("%<__gcc_host_wide_int__%> is not defined" 4910 " as %<long%> or %<long long%>"); 4911 hwi = 0; 4912 } 4913 } 4914 } 4915 } 4916 if (!diag_ls) 4917 diag_ls = (format_length_info *) 4918 xmemdup (gcc_diag_length_specs, 4919 sizeof (gcc_diag_length_specs), 4920 sizeof (gcc_diag_length_specs)); 4921 if (hwi) 4922 { 4923 /* HOST_WIDE_INT must be one of 'long' or 'long long'. */ 4924 i = find_length_info_modifier_index (diag_ls, 'w'); 4925 if (hwi == long_integer_type_node) 4926 diag_ls[i].index = FMT_LEN_l; 4927 else if (hwi == long_long_integer_type_node) 4928 diag_ls[i].index = FMT_LEN_ll; 4929 else 4930 gcc_unreachable (); 4931 } 4932 } 4933 return diag_ls; 4934 } 4935 4936 /* Determine the type of a "locus" in the code being compiled for use 4937 in GCC's __gcc_gfc__ custom format attribute. You must have set 4938 dynamic_format_types before calling this function. */ 4939 static void 4940 init_dynamic_gfc_info (void) 4941 { 4942 dynamic_format_types[gcc_gfc_format_type].length_char_specs 4943 = get_init_dynamic_hwi (); 4944 4945 if (!locus) 4946 { 4947 static format_char_info *gfc_fci; 4948 4949 /* For the GCC __gcc_gfc__ custom format specifier to work, one 4950 must have declared 'locus' prior to using this attribute. If 4951 we haven't seen this declarations then you shouldn't use the 4952 specifier requiring that type. */ 4953 if ((locus = maybe_get_identifier ("locus"))) 4954 { 4955 locus = identifier_global_value (locus); 4956 if (locus) 4957 { 4958 if (TREE_CODE (locus) != TYPE_DECL 4959 || TREE_TYPE (locus) == error_mark_node) 4960 { 4961 error ("%<locus%> is not defined as a type"); 4962 locus = 0; 4963 } 4964 else 4965 locus = TREE_TYPE (locus); 4966 } 4967 } 4968 4969 /* Assign the new data for use. */ 4970 4971 /* Handle the __gcc_gfc__ format specifics. */ 4972 if (!gfc_fci) 4973 dynamic_format_types[gcc_gfc_format_type].conversion_specs = 4974 gfc_fci = (format_char_info *) 4975 xmemdup (gcc_gfc_char_table, 4976 sizeof (gcc_gfc_char_table), 4977 sizeof (gcc_gfc_char_table)); 4978 if (locus) 4979 { 4980 const unsigned i = find_char_info_specifier_index (gfc_fci, 'L'); 4981 gfc_fci[i].types[0].type = &locus; 4982 gfc_fci[i].pointer_count = 1; 4983 } 4984 } 4985 } 4986 4987 /* Lookup the type named NAME and return a NAME type if found. 4988 Otherwise, return void_type_node if NAME has not been used yet, 4989 or NULL_TREE if NAME is not a type (issuing an error). */ 4990 4991 static tree 4992 get_named_type (const char *name) 4993 { 4994 if (tree result = maybe_get_identifier (name)) 4995 { 4996 result = identifier_global_tag (result); 4997 if (result) 4998 { 4999 if (TYPE_P (result)) 5000 ; 5001 else if (TREE_CODE (result) == TYPE_DECL) 5002 result = TREE_TYPE (result); 5003 else 5004 { 5005 error ("%qs is not defined as a type", name); 5006 result = NULL_TREE; 5007 } 5008 } 5009 return result; 5010 } 5011 else 5012 return void_type_node; 5013 } 5014 5015 /* Determine the types of "tree" and "location_t" in the code being 5016 compiled for use in GCC's diagnostic custom format attributes. You 5017 must have set dynamic_format_types before calling this function. */ 5018 static void 5019 init_dynamic_diag_info (void) 5020 { 5021 /* For the GCC-diagnostics custom format specifiers to work, one 5022 must have declared 'tree' and 'location_t' prior to using those 5023 attributes. If we haven't seen these declarations then 5024 the specifiers requiring these types shouldn't be used. 5025 However we don't force a hard ICE because we may see only one 5026 or the other type. */ 5027 if (tree loc = maybe_get_identifier ("location_t")) 5028 { 5029 loc = identifier_global_value (loc); 5030 if (loc && TREE_CODE (loc) != TYPE_DECL) 5031 error ("%<location_t%> is not defined as a type"); 5032 } 5033 5034 /* Initialize the global tree node type local to this file. */ 5035 if (!local_tree_type_node 5036 || local_tree_type_node == void_type_node) 5037 { 5038 /* We need to grab the underlying 'union tree_node' so peek into 5039 an extra type level. */ 5040 if ((local_tree_type_node = maybe_get_identifier ("tree"))) 5041 { 5042 local_tree_type_node 5043 = identifier_global_value (local_tree_type_node); 5044 if (local_tree_type_node) 5045 { 5046 if (TREE_CODE (local_tree_type_node) != TYPE_DECL) 5047 { 5048 error ("%<tree%> is not defined as a type"); 5049 local_tree_type_node = NULL_TREE; 5050 } 5051 else if (TREE_CODE (TREE_TYPE (local_tree_type_node)) 5052 != POINTER_TYPE) 5053 { 5054 error ("%<tree%> is not defined as a pointer type"); 5055 local_tree_type_node = NULL_TREE; 5056 } 5057 else 5058 local_tree_type_node 5059 = TREE_TYPE (TREE_TYPE (local_tree_type_node)); 5060 } 5061 } 5062 else 5063 local_tree_type_node = void_type_node; 5064 } 5065 5066 /* Similar to the above but for gimple*. */ 5067 if (!local_gimple_ptr_node 5068 || local_gimple_ptr_node == void_type_node) 5069 local_gimple_ptr_node = get_named_type ("gimple"); 5070 5071 /* Similar to the above but for cgraph_node*. */ 5072 if (!local_cgraph_node_ptr_node 5073 || local_cgraph_node_ptr_node == void_type_node) 5074 local_cgraph_node_ptr_node = get_named_type ("cgraph_node"); 5075 5076 /* Similar to the above but for diagnostic_event_id_t*. */ 5077 if (!local_event_ptr_node 5078 || local_event_ptr_node == void_type_node) 5079 local_event_ptr_node = get_named_type ("diagnostic_event_id_t"); 5080 5081 /* All the GCC diag formats use the same length specs. */ 5082 dynamic_format_types[gcc_diag_format_type].length_char_specs = 5083 dynamic_format_types[gcc_tdiag_format_type].length_char_specs = 5084 dynamic_format_types[gcc_cdiag_format_type].length_char_specs = 5085 dynamic_format_types[gcc_cxxdiag_format_type].length_char_specs = 5086 dynamic_format_types[gcc_dump_printf_format_type].length_char_specs 5087 = get_init_dynamic_hwi (); 5088 5089 /* It's safe to "re-initialize these to the same values. */ 5090 dynamic_format_types[gcc_diag_format_type].conversion_specs = 5091 gcc_diag_char_table; 5092 dynamic_format_types[gcc_tdiag_format_type].conversion_specs = 5093 gcc_tdiag_char_table; 5094 dynamic_format_types[gcc_cdiag_format_type].conversion_specs = 5095 gcc_cdiag_char_table; 5096 dynamic_format_types[gcc_cxxdiag_format_type].conversion_specs = 5097 gcc_cxxdiag_char_table; 5098 dynamic_format_types[gcc_dump_printf_format_type].conversion_specs = 5099 gcc_dump_printf_char_table; 5100 } 5101 5102 #ifdef TARGET_FORMAT_TYPES 5103 extern const format_kind_info TARGET_FORMAT_TYPES[]; 5104 #endif 5105 5106 #ifdef TARGET_OVERRIDES_FORMAT_ATTRIBUTES 5107 extern const target_ovr_attr TARGET_OVERRIDES_FORMAT_ATTRIBUTES[]; 5108 #endif 5109 #ifdef TARGET_OVERRIDES_FORMAT_INIT 5110 extern void TARGET_OVERRIDES_FORMAT_INIT (void); 5111 #endif 5112 5113 /* Attributes such as "printf" are equivalent to those such as 5114 "gnu_printf" unless this is overridden by a target. */ 5115 static const target_ovr_attr gnu_target_overrides_format_attributes[] = 5116 { 5117 { "gnu_printf", "printf" }, 5118 { "gnu_syslog", "syslog" }, 5119 { "gnu_scanf", "scanf" }, 5120 { "gnu_strftime", "strftime" }, 5121 { "gnu_strfmon", "strfmon" }, 5122 { NULL, NULL } 5123 }; 5124 5125 /* Translate to unified attribute name. This is used in decode_format_type and 5126 decode_format_attr. In attr_name the user specified argument is passed. It 5127 returns the unified format name from TARGET_OVERRIDES_FORMAT_ATTRIBUTES 5128 or the attr_name passed to this function, if there is no matching entry. */ 5129 static const char * 5130 convert_format_name_to_system_name (const char *attr_name) 5131 { 5132 int i; 5133 5134 if (attr_name == NULL || *attr_name == 0 5135 || startswith (attr_name, "gcc_")) 5136 return attr_name; 5137 #ifdef TARGET_OVERRIDES_FORMAT_INIT 5138 TARGET_OVERRIDES_FORMAT_INIT (); 5139 #endif 5140 5141 #ifdef TARGET_OVERRIDES_FORMAT_ATTRIBUTES 5142 /* Check if format attribute is overridden by target. */ 5143 if (TARGET_OVERRIDES_FORMAT_ATTRIBUTES != NULL 5144 && TARGET_OVERRIDES_FORMAT_ATTRIBUTES_COUNT > 0) 5145 { 5146 for (i = 0; i < TARGET_OVERRIDES_FORMAT_ATTRIBUTES_COUNT; ++i) 5147 { 5148 if (cmp_attribs (TARGET_OVERRIDES_FORMAT_ATTRIBUTES[i].named_attr_src, 5149 attr_name)) 5150 return attr_name; 5151 if (cmp_attribs (TARGET_OVERRIDES_FORMAT_ATTRIBUTES[i].named_attr_dst, 5152 attr_name)) 5153 return TARGET_OVERRIDES_FORMAT_ATTRIBUTES[i].named_attr_src; 5154 } 5155 } 5156 #endif 5157 /* Otherwise default to gnu format. */ 5158 for (i = 0; 5159 gnu_target_overrides_format_attributes[i].named_attr_src != NULL; 5160 ++i) 5161 { 5162 if (cmp_attribs (gnu_target_overrides_format_attributes[i].named_attr_src, 5163 attr_name)) 5164 return attr_name; 5165 if (cmp_attribs (gnu_target_overrides_format_attributes[i].named_attr_dst, 5166 attr_name)) 5167 return gnu_target_overrides_format_attributes[i].named_attr_src; 5168 } 5169 5170 return attr_name; 5171 } 5172 5173 /* Handle a "format" attribute; arguments as in 5174 struct attribute_spec.handler. */ 5175 tree 5176 handle_format_attribute (tree *node, tree atname, tree args, 5177 int flags, bool *no_add_attrs) 5178 { 5179 const_tree type = *node; 5180 function_format_info info; 5181 5182 #ifdef TARGET_FORMAT_TYPES 5183 /* If the target provides additional format types, we need to 5184 add them to FORMAT_TYPES at first use. */ 5185 if (!dynamic_format_types) 5186 { 5187 dynamic_format_types = XNEWVEC (format_kind_info, 5188 n_format_types + TARGET_N_FORMAT_TYPES); 5189 memcpy (dynamic_format_types, format_types_orig, 5190 sizeof (format_types_orig)); 5191 memcpy (&dynamic_format_types[n_format_types], TARGET_FORMAT_TYPES, 5192 TARGET_N_FORMAT_TYPES * sizeof (dynamic_format_types[0])); 5193 5194 format_types = dynamic_format_types; 5195 /* Provide a reference for the first potential external type. */ 5196 first_target_format_type = n_format_types; 5197 n_format_types += TARGET_N_FORMAT_TYPES; 5198 } 5199 #endif 5200 5201 /* Canonicalize name of format function. */ 5202 if (TREE_CODE (TREE_VALUE (args)) == IDENTIFIER_NODE) 5203 TREE_VALUE (args) = canonicalize_attr_name (TREE_VALUE (args)); 5204 5205 if (!decode_format_attr (type, atname, args, &info, /* validated_p = */false)) 5206 { 5207 *no_add_attrs = true; 5208 return NULL_TREE; 5209 } 5210 5211 if (prototype_p (type)) 5212 { 5213 if (!check_format_string (type, info.format_num, flags, 5214 no_add_attrs, info.format_type)) 5215 return NULL_TREE; 5216 5217 if (info.first_arg_num != 0) 5218 { 5219 unsigned HOST_WIDE_INT arg_num = 1; 5220 function_args_iterator iter; 5221 tree arg_type; 5222 5223 /* Verify that first_arg_num points to the last arg, 5224 the ... */ 5225 FOREACH_FUNCTION_ARGS (type, arg_type, iter) 5226 arg_num++; 5227 5228 if (arg_num != info.first_arg_num) 5229 { 5230 if (!(flags & (int) ATTR_FLAG_BUILT_IN)) 5231 error ("argument to be formatted is not %<...%>"); 5232 *no_add_attrs = true; 5233 return NULL_TREE; 5234 } 5235 } 5236 } 5237 5238 /* Check if this is a strftime variant. Just for this variant 5239 FMT_FLAG_ARG_CONVERT is not set. */ 5240 if ((format_types[info.format_type].flags & (int) FMT_FLAG_ARG_CONVERT) == 0 5241 && info.first_arg_num != 0) 5242 { 5243 error ("strftime formats cannot format arguments"); 5244 *no_add_attrs = true; 5245 return NULL_TREE; 5246 } 5247 5248 /* If this is a custom GCC-internal format type, we have to 5249 initialize certain bits at runtime. */ 5250 if (info.format_type == asm_fprintf_format_type 5251 || info.format_type == gcc_gfc_format_type 5252 || info.format_type == gcc_diag_format_type 5253 || info.format_type == gcc_tdiag_format_type 5254 || info.format_type == gcc_cdiag_format_type 5255 || info.format_type == gcc_cxxdiag_format_type 5256 || info.format_type == gcc_dump_printf_format_type) 5257 { 5258 /* Our first time through, we have to make sure that our 5259 format_type data is allocated dynamically and is modifiable. */ 5260 if (!dynamic_format_types) 5261 format_types = dynamic_format_types = (format_kind_info *) 5262 xmemdup (format_types_orig, sizeof (format_types_orig), 5263 sizeof (format_types_orig)); 5264 5265 /* If this is format __asm_fprintf__, we have to initialize 5266 GCC's notion of HOST_WIDE_INT for checking %wd. */ 5267 if (info.format_type == asm_fprintf_format_type) 5268 init_dynamic_asm_fprintf_info (); 5269 /* If this is format __gcc_gfc__, we have to initialize GCC's 5270 notion of 'locus' at runtime for %L. */ 5271 else if (info.format_type == gcc_gfc_format_type) 5272 init_dynamic_gfc_info (); 5273 /* If this is one of the diagnostic attributes, then we have to 5274 initialize 'location_t' and 'tree' at runtime. */ 5275 else if (info.format_type == gcc_diag_format_type 5276 || info.format_type == gcc_tdiag_format_type 5277 || info.format_type == gcc_cdiag_format_type 5278 || info.format_type == gcc_cxxdiag_format_type 5279 || info.format_type == gcc_dump_printf_format_type) 5280 init_dynamic_diag_info (); 5281 else 5282 gcc_unreachable (); 5283 } 5284 5285 return NULL_TREE; 5286 } 5287 5288 #if CHECKING_P 5289 5290 namespace selftest { 5291 5292 /* Selftests of location handling. */ 5293 5294 /* Get the format_kind_info with the given name. */ 5295 5296 static const format_kind_info * 5297 get_info (const char *name) 5298 { 5299 int idx = decode_format_type (name); 5300 const format_kind_info *fki = &format_types[idx]; 5301 ASSERT_STREQ (fki->name, name); 5302 return fki; 5303 } 5304 5305 /* Verify that get_format_for_type (FKI, TYPE, CONVERSION_CHAR) 5306 is EXPECTED_FORMAT. */ 5307 5308 static void 5309 assert_format_for_type_streq (const location &loc, const format_kind_info *fki, 5310 const char *expected_format, tree type, 5311 char conversion_char) 5312 { 5313 gcc_assert (fki); 5314 gcc_assert (expected_format); 5315 gcc_assert (type); 5316 5317 char *actual_format = get_format_for_type (fki, type, conversion_char); 5318 ASSERT_STREQ_AT (loc, expected_format, actual_format); 5319 free (actual_format); 5320 } 5321 5322 /* Selftests for get_format_for_type. */ 5323 5324 #define ASSERT_FORMAT_FOR_TYPE_STREQ(EXPECTED_FORMAT, TYPE, CONVERSION_CHAR) \ 5325 assert_format_for_type_streq (SELFTEST_LOCATION, (fki), (EXPECTED_FORMAT), \ 5326 (TYPE), (CONVERSION_CHAR)) 5327 5328 /* Selftest for get_format_for_type for "printf"-style functions. */ 5329 5330 static void 5331 test_get_format_for_type_printf () 5332 { 5333 const format_kind_info *fki = get_info ("gnu_printf"); 5334 ASSERT_NE (fki, NULL); 5335 5336 ASSERT_FORMAT_FOR_TYPE_STREQ ("f", double_type_node, 'i'); 5337 ASSERT_FORMAT_FOR_TYPE_STREQ ("Lf", long_double_type_node, 'i'); 5338 ASSERT_FORMAT_FOR_TYPE_STREQ ("f", double_type_node, 'o'); 5339 ASSERT_FORMAT_FOR_TYPE_STREQ ("Lf", long_double_type_node, 'o'); 5340 ASSERT_FORMAT_FOR_TYPE_STREQ ("f", double_type_node, 'x'); 5341 ASSERT_FORMAT_FOR_TYPE_STREQ ("Lf", long_double_type_node, 'x'); 5342 ASSERT_FORMAT_FOR_TYPE_STREQ ("f", double_type_node, 'X'); 5343 ASSERT_FORMAT_FOR_TYPE_STREQ ("Lf", long_double_type_node, 'X'); 5344 ASSERT_FORMAT_FOR_TYPE_STREQ ("d", integer_type_node, 'd'); 5345 ASSERT_FORMAT_FOR_TYPE_STREQ ("i", integer_type_node, 'i'); 5346 ASSERT_FORMAT_FOR_TYPE_STREQ ("o", integer_type_node, 'o'); 5347 ASSERT_FORMAT_FOR_TYPE_STREQ ("x", integer_type_node, 'x'); 5348 ASSERT_FORMAT_FOR_TYPE_STREQ ("X", integer_type_node, 'X'); 5349 ASSERT_FORMAT_FOR_TYPE_STREQ ("d", unsigned_type_node, 'd'); 5350 ASSERT_FORMAT_FOR_TYPE_STREQ ("i", unsigned_type_node, 'i'); 5351 ASSERT_FORMAT_FOR_TYPE_STREQ ("o", unsigned_type_node, 'o'); 5352 ASSERT_FORMAT_FOR_TYPE_STREQ ("x", unsigned_type_node, 'x'); 5353 ASSERT_FORMAT_FOR_TYPE_STREQ ("X", unsigned_type_node, 'X'); 5354 ASSERT_FORMAT_FOR_TYPE_STREQ ("ld", long_integer_type_node, 'd'); 5355 ASSERT_FORMAT_FOR_TYPE_STREQ ("li", long_integer_type_node, 'i'); 5356 ASSERT_FORMAT_FOR_TYPE_STREQ ("lx", long_integer_type_node, 'x'); 5357 ASSERT_FORMAT_FOR_TYPE_STREQ ("lo", long_unsigned_type_node, 'o'); 5358 ASSERT_FORMAT_FOR_TYPE_STREQ ("lx", long_unsigned_type_node, 'x'); 5359 ASSERT_FORMAT_FOR_TYPE_STREQ ("lld", long_long_integer_type_node, 'd'); 5360 ASSERT_FORMAT_FOR_TYPE_STREQ ("lli", long_long_integer_type_node, 'i'); 5361 ASSERT_FORMAT_FOR_TYPE_STREQ ("llo", long_long_unsigned_type_node, 'o'); 5362 ASSERT_FORMAT_FOR_TYPE_STREQ ("llx", long_long_unsigned_type_node, 'x'); 5363 ASSERT_FORMAT_FOR_TYPE_STREQ ("s", build_pointer_type (char_type_node), 'i'); 5364 } 5365 5366 /* Selftest for get_format_for_type for "scanf"-style functions. */ 5367 5368 static void 5369 test_get_format_for_type_scanf () 5370 { 5371 const format_kind_info *fki = get_info ("gnu_scanf"); 5372 ASSERT_NE (fki, NULL); 5373 ASSERT_FORMAT_FOR_TYPE_STREQ ("d", build_pointer_type (integer_type_node), 'd'); 5374 ASSERT_FORMAT_FOR_TYPE_STREQ ("u", build_pointer_type (unsigned_type_node), 'u'); 5375 ASSERT_FORMAT_FOR_TYPE_STREQ ("ld", 5376 build_pointer_type (long_integer_type_node), 'd'); 5377 ASSERT_FORMAT_FOR_TYPE_STREQ ("lu", 5378 build_pointer_type (long_unsigned_type_node), 'u'); 5379 ASSERT_FORMAT_FOR_TYPE_STREQ 5380 ("lld", build_pointer_type (long_long_integer_type_node), 'd'); 5381 ASSERT_FORMAT_FOR_TYPE_STREQ 5382 ("llu", build_pointer_type (long_long_unsigned_type_node), 'u'); 5383 ASSERT_FORMAT_FOR_TYPE_STREQ ("e", build_pointer_type (float_type_node), 'e'); 5384 ASSERT_FORMAT_FOR_TYPE_STREQ ("le", build_pointer_type (double_type_node), 'e'); 5385 } 5386 5387 #undef ASSERT_FORMAT_FOR_TYPE_STREQ 5388 5389 /* Exercise the type-printing label code, to give some coverage 5390 under "make selftest-valgrind" (in particular, to ensure that 5391 the label-printing machinery doesn't leak). */ 5392 5393 static void 5394 test_type_mismatch_range_labels () 5395 { 5396 /* Create a tempfile and write some text to it. 5397 ....................0000000001 11111111 12 22222222 5398 ....................1234567890 12345678 90 12345678. */ 5399 const char *content = " printf (\"msg: %i\\n\", msg);\n"; 5400 temp_source_file tmp (SELFTEST_LOCATION, ".c", content); 5401 line_table_test ltt; 5402 5403 linemap_add (line_table, LC_ENTER, false, tmp.get_filename (), 1); 5404 5405 location_t c17 = linemap_position_for_column (line_table, 17); 5406 ASSERT_EQ (LOCATION_COLUMN (c17), 17); 5407 location_t c18 = linemap_position_for_column (line_table, 18); 5408 location_t c24 = linemap_position_for_column (line_table, 24); 5409 location_t c26 = linemap_position_for_column (line_table, 26); 5410 5411 /* Don't attempt to run the tests if column data might be unavailable. */ 5412 if (c26 > LINE_MAP_MAX_LOCATION_WITH_COLS) 5413 return; 5414 5415 location_t fmt = make_location (c18, c17, c18); 5416 ASSERT_EQ (LOCATION_COLUMN (fmt), 18); 5417 5418 location_t param = make_location (c24, c24, c26); 5419 ASSERT_EQ (LOCATION_COLUMN (param), 24); 5420 5421 range_label_for_format_type_mismatch fmt_label (char_type_node, 5422 integer_type_node, 1); 5423 range_label_for_type_mismatch param_label (integer_type_node, 5424 char_type_node); 5425 gcc_rich_location richloc (fmt, &fmt_label); 5426 richloc.add_range (param, SHOW_RANGE_WITHOUT_CARET, ¶m_label); 5427 5428 test_diagnostic_context dc; 5429 diagnostic_show_locus (&dc, &richloc, DK_ERROR); 5430 if (c_dialect_cxx ()) 5431 /* "char*", without a space. */ 5432 ASSERT_STREQ (" printf (\"msg: %i\\n\", msg);\n" 5433 " ~^ ~~~\n" 5434 " | |\n" 5435 " char* int\n", 5436 pp_formatted_text (dc.printer)); 5437 else 5438 /* "char *", with a space. */ 5439 ASSERT_STREQ (" printf (\"msg: %i\\n\", msg);\n" 5440 " ~^ ~~~\n" 5441 " | |\n" 5442 " | int\n" 5443 " char *\n", 5444 pp_formatted_text (dc.printer)); 5445 } 5446 5447 /* Run all of the selftests within this file. */ 5448 5449 void 5450 c_format_cc_tests () 5451 { 5452 test_get_modifier_for_format_len (); 5453 test_get_format_for_type_printf (); 5454 test_get_format_for_type_scanf (); 5455 test_type_mismatch_range_labels (); 5456 } 5457 5458 } // namespace selftest 5459 5460 #endif /* CHECKING_P */ 5461 5462 #include "gt-c-family-c-format.h" 5463