comparison gcc/c-family/c-format.c @ 131:84e7813d76e9

gcc-8.2
author mir3636
date Thu, 25 Oct 2018 07:37:49 +0900
parents 04ced10e8804
children 1830386684a0
comparison
equal deleted inserted replaced
111:04ced10e8804 131:84e7813d76e9
1 /* Check calls to formatted I/O functions (-Wformat). 1 /* Check calls to formatted I/O functions (-Wformat).
2 Copyright (C) 1992-2017 Free Software Foundation, Inc. 2 Copyright (C) 1992-2018 Free Software Foundation, Inc.
3 3
4 This file is part of GCC. 4 This file is part of GCC.
5 5
6 GCC is free software; you can redistribute it and/or modify it under 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 7 the terms of the GNU General Public License as published by the Free
30 #include "langhooks.h" 30 #include "langhooks.h"
31 #include "c-format.h" 31 #include "c-format.h"
32 #include "diagnostic.h" 32 #include "diagnostic.h"
33 #include "substring-locations.h" 33 #include "substring-locations.h"
34 #include "selftest.h" 34 #include "selftest.h"
35 #include "selftest-diagnostic.h"
35 #include "builtins.h" 36 #include "builtins.h"
36 #include "attribs.h" 37 #include "attribs.h"
38 #include "gcc-rich-location.h"
37 39
38 /* Handle attributes associated with format checking. */ 40 /* Handle attributes associated with format checking. */
39 41
40 /* This must be in the same order as format_types, except for 42 /* This must be in the same order as format_types, except for
41 format_type_error. Target-specific format types do not have 43 format_type_error. Target-specific format types do not have
42 matching enum values. */ 44 matching enum values. */
43 enum format_type { printf_format_type, asm_fprintf_format_type, 45 enum format_type { printf_format_type, asm_fprintf_format_type,
44 gcc_diag_format_type, gcc_tdiag_format_type, 46 gcc_diag_format_type, gcc_tdiag_format_type,
45 gcc_cdiag_format_type, 47 gcc_cdiag_format_type,
46 gcc_cxxdiag_format_type, gcc_gfc_format_type, 48 gcc_cxxdiag_format_type, gcc_gfc_format_type,
49 gcc_dump_printf_format_type,
47 gcc_objc_string_format_type, 50 gcc_objc_string_format_type,
48 format_type_error = -1}; 51 format_type_error = -1};
49 52
50 struct function_format_info 53 struct function_format_info
51 { 54 {
54 unsigned HOST_WIDE_INT first_arg_num; /* number of first arg (zero for varargs) */ 57 unsigned HOST_WIDE_INT first_arg_num; /* number of first arg (zero for varargs) */
55 }; 58 };
56 59
57 /* Initialized in init_dynamic_diag_info. */ 60 /* Initialized in init_dynamic_diag_info. */
58 static GTY(()) tree local_tree_type_node; 61 static GTY(()) tree local_tree_type_node;
59 static GTY(()) tree local_gcall_ptr_node; 62 static GTY(()) tree local_gimple_ptr_node;
60 static GTY(()) tree locus; 63 static GTY(()) tree locus;
61 64
62 static bool decode_format_attr (tree, function_format_info *, int); 65 static bool decode_format_attr (tree, function_format_info *, int);
63 static int decode_format_type (const char *); 66 static int decode_format_type (const char *);
64 67
95 be emitted. Fix it. */ 98 be emitted. Fix it. */
96 char_idx -= 1; 99 char_idx -= 1;
97 100
98 substring_loc fmt_loc (fmt_string_loc, string_type, char_idx, char_idx, 101 substring_loc fmt_loc (fmt_string_loc, string_type, char_idx, char_idx,
99 char_idx); 102 char_idx);
100 bool warned = format_warning_va (fmt_loc, UNKNOWN_LOCATION, NULL, opt, 103 format_string_diagnostic_t diag (fmt_loc, NULL, UNKNOWN_LOCATION, NULL,
101 gmsgid, &ap); 104 NULL);
105 bool warned = diag.emit_warning_va (opt, gmsgid, &ap);
102 va_end (ap); 106 va_end (ap);
103 107
104 return warned; 108 return warned;
105 } 109 }
106 110
459 463
460 /* The custom diagnostics all accept the same length specifiers. */ 464 /* The custom diagnostics all accept the same length specifiers. */
461 #define gcc_tdiag_length_specs gcc_diag_length_specs 465 #define gcc_tdiag_length_specs gcc_diag_length_specs
462 #define gcc_cdiag_length_specs gcc_diag_length_specs 466 #define gcc_cdiag_length_specs gcc_diag_length_specs
463 #define gcc_cxxdiag_length_specs gcc_diag_length_specs 467 #define gcc_cxxdiag_length_specs gcc_diag_length_specs
468 #define gcc_dump_printf_length_specs gcc_diag_length_specs
464 469
465 /* This differs from printf_length_specs only in that "Z" is not accepted. */ 470 /* This differs from printf_length_specs only in that "Z" is not accepted. */
466 static const format_length_info scanf_length_specs[] = 471 static const format_length_info scanf_length_specs[] =
467 { 472 {
468 { "h", FMT_LEN_h, STD_C89, "hh", FMT_LEN_hh, STD_C99, 0 }, 473 { "h", FMT_LEN_h, STD_C89, "hh", FMT_LEN_hh, STD_C99, 0 },
548 553
549 #define gcc_tdiag_flag_pairs gcc_diag_flag_pairs 554 #define gcc_tdiag_flag_pairs gcc_diag_flag_pairs
550 #define gcc_cdiag_flag_pairs gcc_diag_flag_pairs 555 #define gcc_cdiag_flag_pairs gcc_diag_flag_pairs
551 #define gcc_cxxdiag_flag_pairs gcc_diag_flag_pairs 556 #define gcc_cxxdiag_flag_pairs gcc_diag_flag_pairs
552 #define gcc_gfc_flag_pairs gcc_diag_flag_pairs 557 #define gcc_gfc_flag_pairs gcc_diag_flag_pairs
558 #define gcc_dump_printf_flag_pairs gcc_diag_flag_pairs
553 559
554 static const format_flag_spec gcc_diag_flag_specs[] = 560 static const format_flag_spec gcc_diag_flag_specs[] =
555 { 561 {
556 { '+', 0, 0, 0, N_("'+' flag"), N_("the '+' printf flag"), STD_C89 }, 562 { '+', 0, 0, 0, N_("'+' flag"), N_("the '+' printf flag"), STD_C89 },
557 { '#', 0, 0, 0, N_("'#' flag"), N_("the '#' printf flag"), STD_C89 }, 563 { '#', 0, 0, 0, N_("'#' flag"), N_("the '#' printf flag"), STD_C89 },
563 569
564 #define gcc_tdiag_flag_specs gcc_diag_flag_specs 570 #define gcc_tdiag_flag_specs gcc_diag_flag_specs
565 #define gcc_cdiag_flag_specs gcc_diag_flag_specs 571 #define gcc_cdiag_flag_specs gcc_diag_flag_specs
566 #define gcc_cxxdiag_flag_specs gcc_diag_flag_specs 572 #define gcc_cxxdiag_flag_specs gcc_diag_flag_specs
567 #define gcc_gfc_flag_specs gcc_diag_flag_specs 573 #define gcc_gfc_flag_specs gcc_diag_flag_specs
574 #define gcc_dump_printf_flag_specs gcc_diag_flag_specs
568 575
569 static const format_flag_spec scanf_flag_specs[] = 576 static const format_flag_spec scanf_flag_specs[] =
570 { 577 {
571 { '*', 0, 0, 0, N_("assignment suppression"), N_("the assignment suppression scanf feature"), STD_C89 }, 578 { '*', 0, 0, 0, N_("assignment suppression"), N_("the assignment suppression scanf feature"), STD_C89 },
572 { 'a', 0, 0, 0, N_("'a' flag"), N_("the 'a' scanf flag"), STD_EXT }, 579 { 'a', 0, 0, 0, N_("'a' flag"), N_("the 'a' scanf flag"), STD_EXT },
677 { "z", 0, STD_C89, NOARGUMENTS, "", "", NULL }, 684 { "z", 0, STD_C89, NOARGUMENTS, "", "", NULL },
678 { "@", 0, STD_C89, NOARGUMENTS, "", "", NULL }, 685 { "@", 0, STD_C89, NOARGUMENTS, "", "", NULL },
679 { NULL, 0, STD_C89, NOLENGTHS, NULL, NULL, NULL } 686 { NULL, 0, STD_C89, NOLENGTHS, NULL, NULL, NULL }
680 }; 687 };
681 688
689 /* GCC-specific format_char_info arrays. */
690
691 /* The conversion specifiers implemented within pp_format, and thus supported
692 by all pretty_printer instances within GCC. */
693
694 #define PP_FORMAT_CHAR_TABLE \
695 { "di", 0, STD_C89, { T89_I, BADLEN, BADLEN, T89_L, T9L_LL, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN }, "q", "", NULL }, \
696 { "ox", 0, STD_C89, { T89_UI, BADLEN, BADLEN, T89_UL, T9L_ULL, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN }, "q", "", NULL }, \
697 { "u", 0, STD_C89, { T89_UI, BADLEN, BADLEN, T89_UL, T9L_ULL, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN }, "q", "", NULL }, \
698 { "c", 0, STD_C89, { T89_I, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN }, "q", "", NULL }, \
699 { "s", 1, STD_C89, { T89_C, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN }, "pq", "cR", NULL }, \
700 { "p", 1, STD_C89, { T89_V, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN }, "q", "c", NULL }, \
701 { "r", 1, STD_C89, { T89_C, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN }, "", "//cR", NULL }, \
702 { "<", 0, STD_C89, NOARGUMENTS, "", "<", NULL }, \
703 { ">", 0, STD_C89, NOARGUMENTS, "", ">", NULL }, \
704 { "'" , 0, STD_C89, NOARGUMENTS, "", "", NULL }, \
705 { "R", 0, STD_C89, NOARGUMENTS, "", "\\", NULL }, \
706 { "m", 0, STD_C89, NOARGUMENTS, "q", "", NULL }, \
707 { "Z", 1, STD_C89, { T89_I, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN }, "", "", &gcc_diag_char_table[0] }
708
682 static const format_char_info gcc_diag_char_table[] = 709 static const format_char_info gcc_diag_char_table[] =
683 { 710 {
684 /* C89 conversion specifiers. */ 711 /* The conversion specifiers implemented within pp_format. */
685 { "di", 0, STD_C89, { T89_I, BADLEN, BADLEN, T89_L, T9L_LL, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN }, "q", "", NULL }, 712 PP_FORMAT_CHAR_TABLE,
686 { "ox", 0, STD_C89, { T89_UI, BADLEN, BADLEN, T89_UL, T9L_ULL, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN }, "q", "", NULL }, 713
687 { "u", 0, STD_C89, { T89_UI, BADLEN, BADLEN, T89_UL, T9L_ULL, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN }, "q", "", NULL },
688 { "c", 0, STD_C89, { T89_I, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN }, "q", "", NULL },
689 { "s", 1, STD_C89, { T89_C, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN }, "pq", "cR", NULL },
690 { "p", 1, STD_C89, { T89_V, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN }, "q", "c", NULL },
691
692 /* Custom conversion specifiers. */
693
694 /* G requires a "gcall*" argument at runtime. */
695 { "G", 1, STD_C89, { T89_G, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN }, "", "\"", NULL },
696 /* K requires a "tree" argument at runtime. */
697 { "K", 1, STD_C89, { T89_T, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN }, "", "\"", NULL },
698
699 { "r", 1, STD_C89, { T89_C, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN }, "", "//cR", NULL },
700 { "<", 0, STD_C89, NOARGUMENTS, "", "<", NULL },
701 { ">", 0, STD_C89, NOARGUMENTS, "", ">", NULL },
702 { "'" , 0, STD_C89, NOARGUMENTS, "", "", NULL },
703 { "R", 0, STD_C89, NOARGUMENTS, "", "\\", NULL },
704 { "m", 0, STD_C89, NOARGUMENTS, "q", "", NULL },
705 { NULL, 0, STD_C89, NOLENGTHS, NULL, NULL, NULL } 714 { NULL, 0, STD_C89, NOLENGTHS, NULL, NULL, NULL }
706 }; 715 };
707 716
708 static const format_char_info gcc_tdiag_char_table[] = 717 static const format_char_info gcc_tdiag_char_table[] =
709 { 718 {
710 /* C89 conversion specifiers. */ 719 /* The conversion specifiers implemented within pp_format. */
711 { "di", 0, STD_C89, { T89_I, BADLEN, BADLEN, T89_L, T9L_LL, BADLEN, BADLEN, BADLEN, BADLEN }, "q", "", NULL }, 720 PP_FORMAT_CHAR_TABLE,
712 { "ox", 0, STD_C89, { T89_UI, BADLEN, BADLEN, T89_UL, T9L_ULL, BADLEN, BADLEN, BADLEN, BADLEN }, "q", "", NULL }, 721
713 { "u", 0, STD_C89, { T89_UI, BADLEN, BADLEN, T89_UL, T9L_ULL, BADLEN, BADLEN, BADLEN, BADLEN }, "q", "", NULL }, 722 /* Custom conversion specifiers implemented by default_tree_printer. */
714 { "c", 0, STD_C89, { T89_I, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN }, "q", "", NULL },
715 { "s", 1, STD_C89, { T89_C, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN }, "pq", "cR", NULL },
716 { "p", 1, STD_C89, { T89_V, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN }, "q", "c", NULL },
717
718 /* Custom conversion specifiers. */
719 723
720 /* These will require a "tree" at runtime. */ 724 /* These will require a "tree" at runtime. */
721 { "DFTV", 1, STD_C89, { T89_T, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN }, "q+", "'", NULL }, 725 { "DFTV", 1, STD_C89, { T89_T, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN }, "q+", "'", NULL },
722 { "E", 1, STD_C89, { T89_T, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN }, "q+", "", NULL }, 726 { "E", 1, STD_C89, { T89_T, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN }, "q+", "", NULL },
723 { "K", 1, STD_C89, { T89_T, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN }, "", "\"", NULL }, 727 { "K", 1, STD_C89, { T89_T, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN }, "", "\"", NULL },
724 728
725 /* G requires a "gcall*" argument at runtime. */ 729 /* G requires a "gimple*" argument at runtime. */
726 { "G", 1, STD_C89, { T89_G, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN }, "", "\"", NULL }, 730 { "G", 1, STD_C89, { T89_G, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN }, "", "\"", NULL },
727 731
728 { "v", 0, STD_C89, { T89_I, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN }, "q#", "", NULL },
729
730 { "r", 1, STD_C89, { T89_C, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN }, "", "/cR", NULL },
731 { "<", 0, STD_C89, NOARGUMENTS, "", "<", NULL },
732 { ">", 0, STD_C89, NOARGUMENTS, "", ">", NULL },
733 { "'", 0, STD_C89, NOARGUMENTS, "", "", NULL },
734 { "R", 0, STD_C89, NOARGUMENTS, "", "\\", NULL },
735 { "m", 0, STD_C89, NOARGUMENTS, "q", "", NULL },
736 { "Z", 1, STD_C89, { T89_I, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN }, "", "", &gcc_tdiag_char_table[0] },
737 { NULL, 0, STD_C89, NOLENGTHS, NULL, NULL, NULL } 732 { NULL, 0, STD_C89, NOLENGTHS, NULL, NULL, NULL }
738 }; 733 };
739 734
740 static const format_char_info gcc_cdiag_char_table[] = 735 static const format_char_info gcc_cdiag_char_table[] =
741 { 736 {
742 /* C89 conversion specifiers. */ 737 /* The conversion specifiers implemented within pp_format. */
743 { "di", 0, STD_C89, { T89_I, BADLEN, BADLEN, T89_L, T9L_LL, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN }, "q", "", NULL }, 738 PP_FORMAT_CHAR_TABLE,
744 { "ox", 0, STD_C89, { T89_UI, BADLEN, BADLEN, T89_UL, T9L_ULL, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN }, "q", "", NULL }, 739
745 { "u", 0, STD_C89, { T89_UI, BADLEN, BADLEN, T89_UL, T9L_ULL, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN }, "q", "", NULL }, 740 /* Custom conversion specifiers implemented by c_tree_printer. */
746 { "c", 0, STD_C89, { T89_I, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN }, "q", "", NULL },
747 { "s", 1, STD_C89, { T89_C, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN }, "pq", "cR", NULL },
748 { "p", 1, STD_C89, { T89_V, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN }, "q", "c", NULL },
749
750 /* Custom conversion specifiers. */
751 741
752 /* These will require a "tree" at runtime. */ 742 /* These will require a "tree" at runtime. */
753 { "DFTV", 1, STD_C89, { T89_T, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN }, "q+", "'", NULL }, 743 { "DFTV", 1, STD_C89, { T89_T, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN }, "q+", "'", NULL },
754 { "E", 1, STD_C89, { T89_T, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN }, "q+", "", NULL }, 744 { "E", 1, STD_C89, { T89_T, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN }, "q+", "", NULL },
755 { "K", 1, STD_C89, { T89_T, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN }, "", "\"", NULL }, 745 { "K", 1, STD_C89, { T89_T, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN }, "", "\"", NULL },
756 746
757 /* G requires a "gcall*" argument at runtime. */ 747 /* G requires a "gimple*" argument at runtime. */
758 { "G", 1, STD_C89, { T89_G, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN }, "", "\"", NULL }, 748 { "G", 1, STD_C89, { T89_G, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN }, "", "\"", NULL },
759 749
760 { "v", 0, STD_C89, { T89_I, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN }, "q#", "", NULL }, 750 { "v", 0, STD_C89, { T89_I, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN }, "q#", "", NULL },
761 751
762 { "r", 1, STD_C89, { T89_C, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN }, "", "/cR", NULL },
763 { "<", 0, STD_C89, NOARGUMENTS, "", "<", NULL },
764 { ">", 0, STD_C89, NOARGUMENTS, "", ">", NULL },
765 { "'", 0, STD_C89, NOARGUMENTS, "", "", NULL },
766 { "R", 0, STD_C89, NOARGUMENTS, "", "\\", NULL },
767 { "m", 0, STD_C89, NOARGUMENTS, "q", "", NULL },
768 { "Z", 1, STD_C89, { T89_I, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN }, "", "", &gcc_tdiag_char_table[0] },
769 { NULL, 0, STD_C89, NOLENGTHS, NULL, NULL, NULL } 752 { NULL, 0, STD_C89, NOLENGTHS, NULL, NULL, NULL }
770 }; 753 };
771 754
772 static const format_char_info gcc_cxxdiag_char_table[] = 755 static const format_char_info gcc_cxxdiag_char_table[] =
773 { 756 {
774 /* C89 conversion specifiers. */ 757 /* The conversion specifiers implemented within pp_format. */
775 { "di", 0, STD_C89, { T89_I, BADLEN, BADLEN, T89_L, T9L_LL, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN }, "q", "", NULL }, 758 PP_FORMAT_CHAR_TABLE,
776 { "ox", 0, STD_C89, { T89_UI, BADLEN, BADLEN, T89_UL, T9L_ULL, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN }, "q", "", NULL }, 759
777 { "u", 0, STD_C89, { T89_UI, BADLEN, BADLEN, T89_UL, T9L_ULL, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN }, "q", "", NULL }, 760 /* Custom conversion specifiers implemented by cp_printer. */
778 { "c", 0, STD_C89, { T89_I, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN }, "q", "", NULL },
779 { "s", 1, STD_C89, { T89_C, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN }, "pq", "cR", NULL },
780 { "p", 1, STD_C89, { T89_V, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN }, "q", "c", NULL },
781
782 /* Custom conversion specifiers. */
783 761
784 /* These will require a "tree" at runtime. */ 762 /* These will require a "tree" at runtime. */
785 { "ADFHISTVX",1,STD_C89,{ T89_T, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN }, "q+#", "'", NULL }, 763 { "ADFHISTVX",1,STD_C89,{ T89_T, BADLEN, BADLEN, BADLEN, 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, BADLEN, BADLEN, BADLEN }, "q+#", "", NULL }, 764 { "E", 1,STD_C89,{ T89_T, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN }, "q+#", "", NULL },
787 { "K", 1, STD_C89,{ T89_T, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN }, "", "\"", NULL }, 765 { "K", 1, STD_C89,{ T89_T, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN }, "", "\"", NULL },
788 { "v", 0,STD_C89, { T89_I, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN }, "q#", "", NULL }, 766
789 767 /* G requires a "gimple*" argument at runtime. */
790 /* G requires a "gcall*" argument at runtime. */
791 { "G", 1, STD_C89,{ T89_G, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN }, "", "\"", NULL }, 768 { "G", 1, STD_C89,{ T89_G, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN }, "", "\"", NULL },
792 769
793 /* These accept either an 'int' or an 'enum tree_code' (which is handled as an 'int'.) */ 770 /* These accept either an 'int' or an 'enum tree_code' (which is handled as an 'int'.) */
794 { "CLOPQ",0,STD_C89, { T89_I, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN }, "q", "", NULL }, 771 { "CLOPQ",0,STD_C89, { T89_I, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN }, "q", "", NULL },
795 772
796 { "r", 1, STD_C89, { T89_C, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN }, "", "/cR", NULL },
797 { "<", 0, STD_C89, NOARGUMENTS, "", "<", NULL },
798 { ">", 0, STD_C89, NOARGUMENTS, "", ">", NULL },
799 { "'", 0, STD_C89, NOARGUMENTS, "", "", NULL },
800 { "R", 0, STD_C89, NOARGUMENTS, "", "\\", NULL },
801 { "m", 0, STD_C89, NOARGUMENTS, "q", "", NULL },
802 { "Z", 1, STD_C89, { T89_I, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN }, "", "", &gcc_tdiag_char_table[0] },
803 { NULL, 0, STD_C89, NOLENGTHS, NULL, NULL, NULL } 773 { NULL, 0, STD_C89, NOLENGTHS, NULL, NULL, NULL }
804 }; 774 };
805 775
806 static const format_char_info gcc_gfc_char_table[] = 776 static const format_char_info gcc_gfc_char_table[] =
807 { 777 {
818 /* This will require a "locus" at runtime. */ 788 /* This will require a "locus" at runtime. */
819 { "L", 0, STD_C89, { T89_V, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN }, "", "R", NULL }, 789 { "L", 0, STD_C89, { T89_V, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN }, "", "R", NULL },
820 790
821 /* These will require nothing. */ 791 /* These will require nothing. */
822 { "<>",0, STD_C89, NOARGUMENTS, "", "", NULL }, 792 { "<>",0, STD_C89, NOARGUMENTS, "", "", NULL },
793 { NULL, 0, STD_C89, NOLENGTHS, NULL, NULL, NULL }
794 };
795
796 static const format_char_info gcc_dump_printf_char_table[] =
797 {
798 /* The conversion specifiers implemented within pp_format. */
799 PP_FORMAT_CHAR_TABLE,
800
801 /* Custom conversion specifiers implemented by dump_pretty_printer. */
802
803 /* E and G require a "gimple *" argument at runtime. */
804 { "EG", 1, STD_C89, { T89_G, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN }, "", "\"", NULL },
805
806 /* T requires a "tree" at runtime. */
807 { "T", 1, STD_C89, { T89_T, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN }, "", "\"", NULL },
808
823 { NULL, 0, STD_C89, NOLENGTHS, NULL, NULL, NULL } 809 { NULL, 0, STD_C89, NOLENGTHS, NULL, NULL, NULL }
824 }; 810 };
825 811
826 static const format_char_info scan_char_table[] = 812 static const format_char_info scan_char_table[] =
827 { 813 {
920 gcc_gfc_flag_specs, gcc_gfc_flag_pairs, 906 gcc_gfc_flag_specs, gcc_gfc_flag_pairs,
921 FMT_FLAG_ARG_CONVERT, 907 FMT_FLAG_ARG_CONVERT,
922 0, 0, 0, 0, 0, 0, 908 0, 0, 0, 0, 0, 0,
923 NULL, NULL 909 NULL, NULL
924 }, 910 },
911 { "gcc_dump_printf", gcc_dump_printf_length_specs,
912 gcc_dump_printf_char_table, "q+#", NULL,
913 gcc_dump_printf_flag_specs, gcc_dump_printf_flag_pairs,
914 FMT_FLAG_ARG_CONVERT,
915 0, 0, 'p', 0, 'L', 0,
916 NULL, &integer_type_node
917 },
925 { "NSString", NULL, NULL, NULL, NULL, 918 { "NSString", NULL, NULL, NULL, NULL,
926 NULL, NULL, 919 NULL, NULL,
927 FMT_FLAG_ARG_CONVERT|FMT_FLAG_PARSE_ARG_CONVERT_EXTERNAL, 0, 0, 0, 0, 0, 0, 920 FMT_FLAG_ARG_CONVERT|FMT_FLAG_PARSE_ARG_CONVERT_EXTERNAL, 0, 0, 0, 0, 0, 0,
928 NULL, NULL 921 NULL, NULL
929 }, 922 },
972 numbers. */ 965 numbers. */
973 int number_dollar_extra_args; 966 int number_dollar_extra_args;
974 /* Number of leaves of the format argument that were wide string 967 /* Number of leaves of the format argument that were wide string
975 literals. */ 968 literals. */
976 int number_wide; 969 int number_wide;
970 /* Number of leaves of the format argument that are not array of "char". */
971 int number_non_char;
977 /* Number of leaves of the format argument that were empty strings. */ 972 /* Number of leaves of the format argument that were empty strings. */
978 int number_empty; 973 int number_empty;
979 /* Number of leaves of the format argument that were unterminated 974 /* Number of leaves of the format argument that were unterminated
980 strings. */ 975 strings. */
981 int number_unterminated; 976 int number_unterminated;
1108 1103
1109 /* Attempt to detect whether the current function might benefit 1104 /* Attempt to detect whether the current function might benefit
1110 from the format attribute if the called function is decorated 1105 from the format attribute if the called function is decorated
1111 with it. Avoid using calls with string literal formats for 1106 with it. Avoid using calls with string literal formats for
1112 guidance since those are unlikely to be viable candidates. */ 1107 guidance since those are unlikely to be viable candidates. */
1113 if (warn_suggest_attribute_format && info.first_arg_num == 0 1108 if (warn_suggest_attribute_format
1109 && current_function_decl != NULL_TREE
1110 && info.first_arg_num == 0
1114 && (format_types[info.format_type].flags 1111 && (format_types[info.format_type].flags
1115 & (int) FMT_FLAG_ARG_CONVERT) 1112 & (int) FMT_FLAG_ARG_CONVERT)
1116 /* c_strlen will fail for a function parameter but succeed 1113 /* c_strlen will fail for a function parameter but succeed
1117 for a literal or constant array. */ 1114 for a literal or constant array. */
1118 && !c_strlen (argarray[info.format_num - 1], 1)) 1115 && !c_strlen (argarray[info.format_num - 1], 1))
1431 res.number_non_literal = 0; 1428 res.number_non_literal = 0;
1432 res.number_extra_args = 0; 1429 res.number_extra_args = 0;
1433 res.extra_arg_loc = UNKNOWN_LOCATION; 1430 res.extra_arg_loc = UNKNOWN_LOCATION;
1434 res.number_dollar_extra_args = 0; 1431 res.number_dollar_extra_args = 0;
1435 res.number_wide = 0; 1432 res.number_wide = 0;
1433 res.number_non_char = 0;
1436 res.number_empty = 0; 1434 res.number_empty = 0;
1437 res.number_unterminated = 0; 1435 res.number_unterminated = 0;
1438 res.number_other = 0; 1436 res.number_other = 0;
1439 res.format_string_loc = input_location; 1437 res.format_string_loc = input_location;
1440 1438
1507 format_types[info->format_type].name); 1505 format_types[info->format_type].name);
1508 1506
1509 if (res.number_wide > 0) 1507 if (res.number_wide > 0)
1510 warning_at (loc, OPT_Wformat_, "format is a wide character string"); 1508 warning_at (loc, OPT_Wformat_, "format is a wide character string");
1511 1509
1510 if (res.number_non_char > 0)
1511 warning_at (loc, OPT_Wformat_,
1512 "format string is not an array of type %qs", "char");
1513
1512 if (res.number_unterminated > 0) 1514 if (res.number_unterminated > 0)
1513 warning_at (loc, OPT_Wformat_, "unterminated format string"); 1515 warning_at (loc, OPT_Wformat_, "unterminated format string");
1514 } 1516 }
1515 1517
1516 /* Callback from check_function_arguments_recurse to check a 1518 /* Callback from check_function_arguments_recurse to check a
1534 tree array_size = 0; 1536 tree array_size = 0;
1535 tree array_init; 1537 tree array_init;
1536 1538
1537 location_t fmt_param_loc = EXPR_LOC_OR_LOC (format_tree, input_location); 1539 location_t fmt_param_loc = EXPR_LOC_OR_LOC (format_tree, input_location);
1538 1540
1539 if (VAR_P (format_tree)) 1541 /* Pull out a constant value if the front end didn't, and handle location
1540 { 1542 wrappers. */
1541 /* Pull out a constant value if the front end didn't. */ 1543 format_tree = fold_for_warn (format_tree);
1542 format_tree = decl_constant_value (format_tree); 1544 STRIP_NOPS (format_tree);
1543 STRIP_NOPS (format_tree);
1544 }
1545 1545
1546 if (integer_zerop (format_tree)) 1546 if (integer_zerop (format_tree))
1547 { 1547 {
1548 /* Skip to first argument to check, so we can see if this format 1548 /* Skip to first argument to check, so we can see if this format
1549 has any arguments (it shouldn't). */ 1549 has any arguments (it shouldn't). */
1654 if (TREE_CODE (format_tree) != STRING_CST) 1654 if (TREE_CODE (format_tree) != STRING_CST)
1655 { 1655 {
1656 res->number_non_literal++; 1656 res->number_non_literal++;
1657 return; 1657 return;
1658 } 1658 }
1659 if (TYPE_MAIN_VARIANT (TREE_TYPE (TREE_TYPE (format_tree))) != char_type_node) 1659 tree underlying_type
1660 { 1660 = TYPE_MAIN_VARIANT (TREE_TYPE (TREE_TYPE (format_tree)));
1661 res->number_wide++; 1661 if (underlying_type != char_type_node)
1662 {
1663 if (underlying_type == char16_type_node
1664 || underlying_type == char32_type_node
1665 || underlying_type == wchar_type_node)
1666 res->number_wide++;
1667 else
1668 res->number_non_char++;
1662 return; 1669 return;
1663 } 1670 }
1664 format_chars = TREE_STRING_POINTER (format_tree); 1671 format_chars = TREE_STRING_POINTER (format_tree);
1665 format_length = TREE_STRING_LENGTH (format_tree); 1672 format_length = TREE_STRING_LENGTH (format_tree);
1666 if (array_size != 0) 1673 if (array_size != 0)
3497 if (start.column > finish.column) 3504 if (start.column > finish.column)
3498 return NULL; 3505 return NULL;
3499 if (caret.column > finish.column) 3506 if (caret.column > finish.column)
3500 return NULL; 3507 return NULL;
3501 3508
3502 int line_width; 3509 char_span line = location_get_source_line (start.file, start.line);
3503 const char *line = location_get_source_line (start.file, start.line, 3510 if (!line)
3504 &line_width);
3505 if (line == NULL)
3506 return NULL; 3511 return NULL;
3507 3512
3508 /* If we got this far, then we have the line containing the 3513 /* If we got this far, then we have the line containing the
3509 existing conversion specification. 3514 existing conversion specification.
3510 3515
3511 Generate a trimmed copy, containing the prefix part of the conversion 3516 Generate a trimmed copy, containing the prefix part of the conversion
3512 specification, up to the (but not including) the length modifier. 3517 specification, up to the (but not including) the length modifier.
3513 In the above example, this would be "%-+*.*". */ 3518 In the above example, this would be "%-+*.*". */
3514 const char *current_content = line + start.column - 1;
3515 int length_up_to_type = caret.column - start.column; 3519 int length_up_to_type = caret.column - start.column;
3516 char *prefix = xstrndup (current_content, length_up_to_type); 3520 char_span prefix_span = line.subspan (start.column - 1, length_up_to_type);
3521 char *prefix = prefix_span.xstrdup ();
3517 3522
3518 /* Now attempt to generate a suggestion for the rest of the specification 3523 /* Now attempt to generate a suggestion for the rest of the specification
3519 (length modifier and conversion char), based on ARG_TYPE and 3524 (length modifier and conversion char), based on ARG_TYPE and
3520 CONVERSION_CHAR. 3525 CONVERSION_CHAR.
3521 In the above example, this would be "ld". */ 3526 In the above example, this would be "ld". */
3532 char *result = concat (prefix, format_for_type, NULL); 3537 char *result = concat (prefix, format_for_type, NULL);
3533 free (format_for_type); 3538 free (format_for_type);
3534 free (prefix); 3539 free (prefix);
3535 return result; 3540 return result;
3536 } 3541 }
3542
3543 /* Helper class for adding zero or more trailing '*' to types.
3544
3545 The format type and name exclude any '*' for pointers, so those
3546 must be formatted manually. For all the types we currently have,
3547 this is adequate, but formats taking pointers to functions or
3548 arrays would require the full type to be built up in order to
3549 print it with %T. */
3550
3551 class indirection_suffix
3552 {
3553 public:
3554 indirection_suffix (int pointer_count) : m_pointer_count (pointer_count) {}
3555
3556 /* Determine the size of the buffer (including NUL-terminator). */
3557
3558 size_t get_buffer_size () const
3559 {
3560 return m_pointer_count + 2;
3561 }
3562
3563 /* Write the '*' to DST and add a NUL-terminator. */
3564
3565 void fill_buffer (char *dst) const
3566 {
3567 if (m_pointer_count == 0)
3568 dst[0] = 0;
3569 else if (c_dialect_cxx ())
3570 {
3571 memset (dst, '*', m_pointer_count);
3572 dst[m_pointer_count] = 0;
3573 }
3574 else
3575 {
3576 dst[0] = ' ';
3577 memset (dst + 1, '*', m_pointer_count);
3578 dst[m_pointer_count + 1] = 0;
3579 }
3580 }
3581
3582 private:
3583 int m_pointer_count;
3584 };
3585
3586 /* Subclass of range_label for labelling the range in the format string
3587 with the type in question, adding trailing '*' for pointer_count. */
3588
3589 class range_label_for_format_type_mismatch
3590 : public range_label_for_type_mismatch
3591 {
3592 public:
3593 range_label_for_format_type_mismatch (tree labelled_type, tree other_type,
3594 int pointer_count)
3595 : range_label_for_type_mismatch (labelled_type, other_type),
3596 m_pointer_count (pointer_count)
3597 {
3598 }
3599
3600 label_text get_text (unsigned range_idx) const FINAL OVERRIDE
3601 {
3602 label_text text = range_label_for_type_mismatch::get_text (range_idx);
3603 if (text.m_buffer == NULL)
3604 return text;
3605
3606 indirection_suffix suffix (m_pointer_count);
3607 char *p = (char *) alloca (suffix.get_buffer_size ());
3608 suffix.fill_buffer (p);
3609
3610 char *result = concat (text.m_buffer, p, NULL);
3611 text.maybe_free ();
3612 return label_text (result, true);
3613 }
3614
3615 private:
3616 int m_pointer_count;
3617 };
3537 3618
3538 /* Give a warning about a format argument of different type from that expected. 3619 /* Give a warning about a format argument of different type from that expected.
3539 The range of the diagnostic is taken from WHOLE_FMT_LOC; the caret location 3620 The range of the diagnostic is taken from WHOLE_FMT_LOC; the caret location
3540 is based on the location of the char at TYPE->offset_loc. 3621 is based on the location of the char at TYPE->offset_loc.
3541 PARAM_LOC is the location of the relevant argument, or UNKNOWN_LOCATION 3622 PARAM_LOC is the location of the relevant argument, or UNKNOWN_LOCATION
3581 const char *format_start = type->format_start; 3662 const char *format_start = type->format_start;
3582 int format_length = type->format_length; 3663 int format_length = type->format_length;
3583 int pointer_count = type->pointer_count; 3664 int pointer_count = type->pointer_count;
3584 int arg_num = type->arg_num; 3665 int arg_num = type->arg_num;
3585 3666
3586 char *p;
3587 /* If ARG_TYPE is a typedef with a misleading name (for example, 3667 /* If ARG_TYPE is a typedef with a misleading name (for example,
3588 size_t but not the standard size_t expected by printf %zu), avoid 3668 size_t but not the standard size_t expected by printf %zu), avoid
3589 printing the typedef name. */ 3669 printing the typedef name. */
3590 if (wanted_type_name 3670 if (wanted_type_name
3591 && arg_type 3671 && arg_type
3593 && TREE_CODE (TYPE_NAME (arg_type)) == TYPE_DECL 3673 && TREE_CODE (TYPE_NAME (arg_type)) == TYPE_DECL
3594 && DECL_NAME (TYPE_NAME (arg_type)) 3674 && DECL_NAME (TYPE_NAME (arg_type))
3595 && !strcmp (wanted_type_name, 3675 && !strcmp (wanted_type_name,
3596 lang_hooks.decl_printable_name (TYPE_NAME (arg_type), 2))) 3676 lang_hooks.decl_printable_name (TYPE_NAME (arg_type), 2)))
3597 arg_type = TYPE_MAIN_VARIANT (arg_type); 3677 arg_type = TYPE_MAIN_VARIANT (arg_type);
3598 /* The format type and name exclude any '*' for pointers, so those 3678
3599 must be formatted manually. For all the types we currently have, 3679 indirection_suffix suffix (pointer_count);
3600 this is adequate, but formats taking pointers to functions or 3680 char *p = (char *) alloca (suffix.get_buffer_size ());
3601 arrays would require the full type to be built up in order to 3681 suffix.fill_buffer (p);
3602 print it with %T. */
3603 p = (char *) alloca (pointer_count + 2);
3604 if (pointer_count == 0)
3605 p[0] = 0;
3606 else if (c_dialect_cxx ())
3607 {
3608 memset (p, '*', pointer_count);
3609 p[pointer_count] = 0;
3610 }
3611 else
3612 {
3613 p[0] = ' ';
3614 memset (p + 1, '*', pointer_count);
3615 p[pointer_count + 1] = 0;
3616 }
3617 3682
3618 /* WHOLE_FMT_LOC has the caret at the end of the range. 3683 /* WHOLE_FMT_LOC has the caret at the end of the range.
3619 Set the caret to be at the offset from TYPE. Subtract one 3684 Set the caret to be at the offset from TYPE. Subtract one
3620 from the offset for the same reason as in format_warning_at_char. */ 3685 from the offset for the same reason as in format_warning_at_char. */
3621 substring_loc fmt_loc (whole_fmt_loc); 3686 substring_loc fmt_loc (whole_fmt_loc);
3622 fmt_loc.set_caret_index (type->offset_loc - 1); 3687 fmt_loc.set_caret_index (type->offset_loc - 1);
3623 3688
3689 range_label_for_format_type_mismatch fmt_label (wanted_type, arg_type,
3690 pointer_count);
3691 range_label_for_type_mismatch param_label (arg_type, wanted_type);
3692
3624 /* Get a string for use as a replacement fix-it hint for the range in 3693 /* Get a string for use as a replacement fix-it hint for the range in
3625 fmt_loc, or NULL. */ 3694 fmt_loc, or NULL. */
3626 char *corrected_substring 3695 char *corrected_substring
3627 = get_corrected_substring (fmt_loc, type, arg_type, fki, 3696 = get_corrected_substring (fmt_loc, type, arg_type, fki,
3628 offset_to_type_start, conversion_char); 3697 offset_to_type_start, conversion_char);
3629 3698 format_string_diagnostic_t diag (fmt_loc, &fmt_label, param_loc, &param_label,
3699 corrected_substring);
3630 if (wanted_type_name) 3700 if (wanted_type_name)
3631 { 3701 {
3632 if (arg_type) 3702 if (arg_type)
3633 format_warning_at_substring 3703 diag.emit_warning
3634 (fmt_loc, param_loc, 3704 (OPT_Wformat_,
3635 corrected_substring, OPT_Wformat_,
3636 "%s %<%s%.*s%> expects argument of type %<%s%s%>, " 3705 "%s %<%s%.*s%> expects argument of type %<%s%s%>, "
3637 "but argument %d has type %qT", 3706 "but argument %d has type %qT",
3638 gettext (kind_descriptions[kind]), 3707 gettext (kind_descriptions[kind]),
3639 (kind == CF_KIND_FORMAT ? "%" : ""), 3708 (kind == CF_KIND_FORMAT ? "%" : ""),
3640 format_length, format_start, 3709 format_length, format_start,
3641 wanted_type_name, p, arg_num, arg_type); 3710 wanted_type_name, p, arg_num, arg_type);
3642 else 3711 else
3643 format_warning_at_substring 3712 diag.emit_warning
3644 (fmt_loc, param_loc, 3713 (OPT_Wformat_,
3645 corrected_substring, OPT_Wformat_,
3646 "%s %<%s%.*s%> expects a matching %<%s%s%> argument", 3714 "%s %<%s%.*s%> expects a matching %<%s%s%> argument",
3647 gettext (kind_descriptions[kind]), 3715 gettext (kind_descriptions[kind]),
3648 (kind == CF_KIND_FORMAT ? "%" : ""), 3716 (kind == CF_KIND_FORMAT ? "%" : ""),
3649 format_length, format_start, wanted_type_name, p); 3717 format_length, format_start, wanted_type_name, p);
3650 } 3718 }
3651 else 3719 else
3652 { 3720 {
3653 if (arg_type) 3721 if (arg_type)
3654 format_warning_at_substring 3722 diag.emit_warning
3655 (fmt_loc, param_loc, 3723 (OPT_Wformat_,
3656 corrected_substring, OPT_Wformat_,
3657 "%s %<%s%.*s%> expects argument of type %<%T%s%>, " 3724 "%s %<%s%.*s%> expects argument of type %<%T%s%>, "
3658 "but argument %d has type %qT", 3725 "but argument %d has type %qT",
3659 gettext (kind_descriptions[kind]), 3726 gettext (kind_descriptions[kind]),
3660 (kind == CF_KIND_FORMAT ? "%" : ""), 3727 (kind == CF_KIND_FORMAT ? "%" : ""),
3661 format_length, format_start, 3728 format_length, format_start,
3662 wanted_type, p, arg_num, arg_type); 3729 wanted_type, p, arg_num, arg_type);
3663 else 3730 else
3664 format_warning_at_substring 3731 diag.emit_warning
3665 (fmt_loc, param_loc, 3732 (OPT_Wformat_,
3666 corrected_substring, OPT_Wformat_,
3667 "%s %<%s%.*s%> expects a matching %<%T%s%> argument", 3733 "%s %<%s%.*s%> expects a matching %<%T%s%> argument",
3668 gettext (kind_descriptions[kind]), 3734 gettext (kind_descriptions[kind]),
3669 (kind == CF_KIND_FORMAT ? "%" : ""), 3735 (kind == CF_KIND_FORMAT ? "%" : ""),
3670 format_length, format_start, wanted_type, p); 3736 format_length, format_start, wanted_type, p);
3671 } 3737 }
3861 } 3927 }
3862 else 3928 else
3863 local_tree_type_node = void_type_node; 3929 local_tree_type_node = void_type_node;
3864 } 3930 }
3865 3931
3866 /* Similar to the above but for gcall*. */ 3932 /* Similar to the above but for gimple*. */
3867 if (!local_gcall_ptr_node 3933 if (!local_gimple_ptr_node
3868 || local_gcall_ptr_node == void_type_node) 3934 || local_gimple_ptr_node == void_type_node)
3869 { 3935 {
3870 if ((local_gcall_ptr_node = maybe_get_identifier ("gcall"))) 3936 if ((local_gimple_ptr_node = maybe_get_identifier ("gimple")))
3871 { 3937 {
3872 local_gcall_ptr_node 3938 local_gimple_ptr_node
3873 = identifier_global_value (local_gcall_ptr_node); 3939 = identifier_global_value (local_gimple_ptr_node);
3874 if (local_gcall_ptr_node) 3940 if (local_gimple_ptr_node)
3875 { 3941 {
3876 if (TREE_CODE (local_gcall_ptr_node) != TYPE_DECL) 3942 if (TREE_CODE (local_gimple_ptr_node) != TYPE_DECL)
3877 { 3943 {
3878 error ("%<gcall%> is not defined as a type"); 3944 error ("%<gimple%> is not defined as a type");
3879 local_gcall_ptr_node = 0; 3945 local_gimple_ptr_node = 0;
3880 } 3946 }
3881 else 3947 else
3882 local_gcall_ptr_node = TREE_TYPE (local_gcall_ptr_node); 3948 local_gimple_ptr_node = TREE_TYPE (local_gimple_ptr_node);
3883 } 3949 }
3884 } 3950 }
3885 else 3951 else
3886 local_gcall_ptr_node = void_type_node; 3952 local_gimple_ptr_node = void_type_node;
3887 } 3953 }
3888 3954
3889 static tree hwi; 3955 static tree hwi;
3890 3956
3891 if (!hwi) 3957 if (!hwi)
3928 if (!diag_ls) 3994 if (!diag_ls)
3929 dynamic_format_types[gcc_diag_format_type].length_char_specs = 3995 dynamic_format_types[gcc_diag_format_type].length_char_specs =
3930 dynamic_format_types[gcc_tdiag_format_type].length_char_specs = 3996 dynamic_format_types[gcc_tdiag_format_type].length_char_specs =
3931 dynamic_format_types[gcc_cdiag_format_type].length_char_specs = 3997 dynamic_format_types[gcc_cdiag_format_type].length_char_specs =
3932 dynamic_format_types[gcc_cxxdiag_format_type].length_char_specs = 3998 dynamic_format_types[gcc_cxxdiag_format_type].length_char_specs =
3999 dynamic_format_types[gcc_dump_printf_format_type].length_char_specs =
3933 diag_ls = (format_length_info *) 4000 diag_ls = (format_length_info *)
3934 xmemdup (gcc_diag_length_specs, 4001 xmemdup (gcc_diag_length_specs,
3935 sizeof (gcc_diag_length_specs), 4002 sizeof (gcc_diag_length_specs),
3936 sizeof (gcc_diag_length_specs)); 4003 sizeof (gcc_diag_length_specs));
3937 if (hwi) 4004 if (hwi)
3954 gcc_tdiag_char_table; 4021 gcc_tdiag_char_table;
3955 dynamic_format_types[gcc_cdiag_format_type].conversion_specs = 4022 dynamic_format_types[gcc_cdiag_format_type].conversion_specs =
3956 gcc_cdiag_char_table; 4023 gcc_cdiag_char_table;
3957 dynamic_format_types[gcc_cxxdiag_format_type].conversion_specs = 4024 dynamic_format_types[gcc_cxxdiag_format_type].conversion_specs =
3958 gcc_cxxdiag_char_table; 4025 gcc_cxxdiag_char_table;
4026 dynamic_format_types[gcc_dump_printf_format_type].conversion_specs =
4027 gcc_dump_printf_char_table;
3959 } 4028 }
3960 4029
3961 #ifdef TARGET_FORMAT_TYPES 4030 #ifdef TARGET_FORMAT_TYPES
3962 extern const format_kind_info TARGET_FORMAT_TYPES[]; 4031 extern const format_kind_info TARGET_FORMAT_TYPES[];
3963 #endif 4032 #endif
4108 if (info.format_type == asm_fprintf_format_type 4177 if (info.format_type == asm_fprintf_format_type
4109 || info.format_type == gcc_gfc_format_type 4178 || info.format_type == gcc_gfc_format_type
4110 || info.format_type == gcc_diag_format_type 4179 || info.format_type == gcc_diag_format_type
4111 || info.format_type == gcc_tdiag_format_type 4180 || info.format_type == gcc_tdiag_format_type
4112 || info.format_type == gcc_cdiag_format_type 4181 || info.format_type == gcc_cdiag_format_type
4113 || info.format_type == gcc_cxxdiag_format_type) 4182 || info.format_type == gcc_cxxdiag_format_type
4183 || info.format_type == gcc_dump_printf_format_type)
4114 { 4184 {
4115 /* Our first time through, we have to make sure that our 4185 /* Our first time through, we have to make sure that our
4116 format_type data is allocated dynamically and is modifiable. */ 4186 format_type data is allocated dynamically and is modifiable. */
4117 if (!dynamic_format_types) 4187 if (!dynamic_format_types)
4118 format_types = dynamic_format_types = (format_kind_info *) 4188 format_types = dynamic_format_types = (format_kind_info *)
4130 /* If this is one of the diagnostic attributes, then we have to 4200 /* If this is one of the diagnostic attributes, then we have to
4131 initialize 'location_t' and 'tree' at runtime. */ 4201 initialize 'location_t' and 'tree' at runtime. */
4132 else if (info.format_type == gcc_diag_format_type 4202 else if (info.format_type == gcc_diag_format_type
4133 || info.format_type == gcc_tdiag_format_type 4203 || info.format_type == gcc_tdiag_format_type
4134 || info.format_type == gcc_cdiag_format_type 4204 || info.format_type == gcc_cdiag_format_type
4135 || info.format_type == gcc_cxxdiag_format_type) 4205 || info.format_type == gcc_cxxdiag_format_type
4206 || info.format_type == gcc_dump_printf_format_type)
4136 init_dynamic_diag_info (); 4207 init_dynamic_diag_info ();
4137 else 4208 else
4138 gcc_unreachable (); 4209 gcc_unreachable ();
4139 } 4210 }
4140 4211
4240 ASSERT_FORMAT_FOR_TYPE_STREQ ("le", build_pointer_type (double_type_node), 'e'); 4311 ASSERT_FORMAT_FOR_TYPE_STREQ ("le", build_pointer_type (double_type_node), 'e');
4241 } 4312 }
4242 4313
4243 #undef ASSERT_FORMAT_FOR_TYPE_STREQ 4314 #undef ASSERT_FORMAT_FOR_TYPE_STREQ
4244 4315
4316 /* Exercise the type-printing label code, to give some coverage
4317 under "make selftest-valgrind" (in particular, to ensure that
4318 the label-printing machinery doesn't leak). */
4319
4320 static void
4321 test_type_mismatch_range_labels ()
4322 {
4323 /* Create a tempfile and write some text to it.
4324 ....................0000000001 11111111 12 22222222
4325 ....................1234567890 12345678 90 12345678. */
4326 const char *content = " printf (\"msg: %i\\n\", msg);\n";
4327 temp_source_file tmp (SELFTEST_LOCATION, ".c", content);
4328 line_table_test ltt;
4329
4330 linemap_add (line_table, LC_ENTER, false, tmp.get_filename (), 1);
4331
4332 location_t c17 = linemap_position_for_column (line_table, 17);
4333 ASSERT_EQ (LOCATION_COLUMN (c17), 17);
4334 location_t c18 = linemap_position_for_column (line_table, 18);
4335 location_t c24 = linemap_position_for_column (line_table, 24);
4336 location_t c26 = linemap_position_for_column (line_table, 26);
4337
4338 /* Don't attempt to run the tests if column data might be unavailable. */
4339 if (c26 > LINE_MAP_MAX_LOCATION_WITH_COLS)
4340 return;
4341
4342 location_t fmt = make_location (c18, c17, c18);
4343 ASSERT_EQ (LOCATION_COLUMN (fmt), 18);
4344
4345 location_t param = make_location (c24, c24, c26);
4346 ASSERT_EQ (LOCATION_COLUMN (param), 24);
4347
4348 range_label_for_format_type_mismatch fmt_label (char_type_node,
4349 integer_type_node, 1);
4350 range_label_for_type_mismatch param_label (integer_type_node,
4351 char_type_node);
4352 gcc_rich_location richloc (fmt, &fmt_label);
4353 richloc.add_range (param, SHOW_RANGE_WITHOUT_CARET, &param_label);
4354
4355 test_diagnostic_context dc;
4356 diagnostic_show_locus (&dc, &richloc, DK_ERROR);
4357 if (c_dialect_cxx ())
4358 /* "char*", without a space. */
4359 ASSERT_STREQ ("\n"
4360 " printf (\"msg: %i\\n\", msg);\n"
4361 " ~^ ~~~\n"
4362 " | |\n"
4363 " char* int\n",
4364 pp_formatted_text (dc.printer));
4365 else
4366 /* "char *", with a space. */
4367 ASSERT_STREQ ("\n"
4368 " printf (\"msg: %i\\n\", msg);\n"
4369 " ~^ ~~~\n"
4370 " | |\n"
4371 " | int\n"
4372 " char *\n",
4373 pp_formatted_text (dc.printer));
4374 }
4375
4245 /* Run all of the selftests within this file. */ 4376 /* Run all of the selftests within this file. */
4246 4377
4247 void 4378 void
4248 c_format_c_tests () 4379 c_format_c_tests ()
4249 { 4380 {
4250 test_get_modifier_for_format_len (); 4381 test_get_modifier_for_format_len ();
4251 test_get_format_for_type_printf (); 4382 test_get_format_for_type_printf ();
4252 test_get_format_for_type_scanf (); 4383 test_get_format_for_type_scanf ();
4384 test_type_mismatch_range_labels ();
4253 } 4385 }
4254 4386
4255 } // namespace selftest 4387 } // namespace selftest
4256 4388
4257 #endif /* CHECKING_P */ 4389 #endif /* CHECKING_P */