Mercurial > hg > CbC > CbC_gcc
comparison gcc/builtins.c @ 146:351920fa3827
merge
author | anatofuz <anatofuz@cr.ie.u-ryukyu.ac.jp> |
---|---|
date | Sun, 01 Mar 2020 16:13:28 +0900 |
parents | 1830386684a0 |
children |
comparison
equal
deleted
inserted
replaced
144:8f4e72ab4e11 | 146:351920fa3827 |
---|---|
1 /* Expand builtin functions. | 1 /* Expand builtin functions. |
2 Copyright (C) 1988-2018 Free Software Foundation, Inc. | 2 Copyright (C) 1988-2020 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 |
29 #include "rtl.h" | 29 #include "rtl.h" |
30 #include "tree.h" | 30 #include "tree.h" |
31 #include "memmodel.h" | 31 #include "memmodel.h" |
32 #include "gimple.h" | 32 #include "gimple.h" |
33 #include "predict.h" | 33 #include "predict.h" |
34 #include "params.h" | |
35 #include "tm_p.h" | 34 #include "tm_p.h" |
36 #include "stringpool.h" | 35 #include "stringpool.h" |
37 #include "tree-vrp.h" | 36 #include "tree-vrp.h" |
38 #include "tree-ssanames.h" | 37 #include "tree-ssanames.h" |
39 #include "expmed.h" | 38 #include "expmed.h" |
47 #include "gimple-ssa-warn-restrict.h" | 46 #include "gimple-ssa-warn-restrict.h" |
48 #include "stor-layout.h" | 47 #include "stor-layout.h" |
49 #include "calls.h" | 48 #include "calls.h" |
50 #include "varasm.h" | 49 #include "varasm.h" |
51 #include "tree-object-size.h" | 50 #include "tree-object-size.h" |
51 #include "tree-ssa-strlen.h" | |
52 #include "realmpfr.h" | 52 #include "realmpfr.h" |
53 #include "cfgrtl.h" | 53 #include "cfgrtl.h" |
54 #include "except.h" | 54 #include "except.h" |
55 #include "dojump.h" | 55 #include "dojump.h" |
56 #include "explow.h" | 56 #include "explow.h" |
70 #include "gimple-fold.h" | 70 #include "gimple-fold.h" |
71 #include "intl.h" | 71 #include "intl.h" |
72 #include "file-prefix-map.h" /* remap_macro_filename() */ | 72 #include "file-prefix-map.h" /* remap_macro_filename() */ |
73 #include "gomp-constants.h" | 73 #include "gomp-constants.h" |
74 #include "omp-general.h" | 74 #include "omp-general.h" |
75 #include "tree-dfa.h" | |
75 | 76 |
76 struct target_builtins default_target_builtins; | 77 struct target_builtins default_target_builtins; |
77 #if SWITCHABLE_TARGET | 78 #if SWITCHABLE_TARGET |
78 struct target_builtins *this_target_builtins = &default_target_builtins; | 79 struct target_builtins *this_target_builtins = &default_target_builtins; |
79 #endif | 80 #endif |
93 builtin_info_type builtin_info[(int)END_BUILTINS]; | 94 builtin_info_type builtin_info[(int)END_BUILTINS]; |
94 | 95 |
95 /* Non-zero if __builtin_constant_p should be folded right away. */ | 96 /* Non-zero if __builtin_constant_p should be folded right away. */ |
96 bool force_folding_builtin_constant_p; | 97 bool force_folding_builtin_constant_p; |
97 | 98 |
98 static rtx c_readstr (const char *, scalar_int_mode); | |
99 static int target_char_cast (tree, char *); | 99 static int target_char_cast (tree, char *); |
100 static rtx get_memory_rtx (tree, tree); | 100 static rtx get_memory_rtx (tree, tree); |
101 static int apply_args_size (void); | 101 static int apply_args_size (void); |
102 static int apply_result_size (void); | 102 static int apply_result_size (void); |
103 static rtx result_vector (int, rtx); | 103 static rtx result_vector (int, rtx); |
124 static rtx expand_builtin_strncmp (tree, rtx, machine_mode); | 124 static rtx expand_builtin_strncmp (tree, rtx, machine_mode); |
125 static rtx builtin_memcpy_read_str (void *, HOST_WIDE_INT, scalar_int_mode); | 125 static rtx builtin_memcpy_read_str (void *, HOST_WIDE_INT, scalar_int_mode); |
126 static rtx expand_builtin_memchr (tree, rtx); | 126 static rtx expand_builtin_memchr (tree, rtx); |
127 static rtx expand_builtin_memcpy (tree, rtx); | 127 static rtx expand_builtin_memcpy (tree, rtx); |
128 static rtx expand_builtin_memory_copy_args (tree dest, tree src, tree len, | 128 static rtx expand_builtin_memory_copy_args (tree dest, tree src, tree len, |
129 rtx target, tree exp, int endp); | 129 rtx target, tree exp, |
130 memop_ret retmode, | |
131 bool might_overlap); | |
130 static rtx expand_builtin_memmove (tree, rtx); | 132 static rtx expand_builtin_memmove (tree, rtx); |
131 static rtx expand_builtin_mempcpy (tree, rtx); | 133 static rtx expand_builtin_mempcpy (tree, rtx); |
132 static rtx expand_builtin_mempcpy_args (tree, tree, tree, rtx, tree, int); | 134 static rtx expand_builtin_mempcpy_args (tree, tree, tree, rtx, tree, memop_ret); |
133 static rtx expand_builtin_strcat (tree, rtx); | 135 static rtx expand_builtin_strcat (tree); |
134 static rtx expand_builtin_strcpy (tree, rtx); | 136 static rtx expand_builtin_strcpy (tree, rtx); |
135 static rtx expand_builtin_strcpy_args (tree, tree, tree, rtx); | 137 static rtx expand_builtin_strcpy_args (tree, tree, tree, rtx); |
136 static rtx expand_builtin_stpcpy (tree, rtx, machine_mode); | 138 static rtx expand_builtin_stpcpy (tree, rtx, machine_mode); |
137 static rtx expand_builtin_stpncpy (tree, rtx); | 139 static rtx expand_builtin_stpncpy (tree, rtx); |
138 static rtx expand_builtin_strncat (tree, rtx); | 140 static rtx expand_builtin_strncat (tree, rtx); |
163 static tree fold_builtin_isdigit (location_t, tree); | 165 static tree fold_builtin_isdigit (location_t, tree); |
164 static tree fold_builtin_fabs (location_t, tree, tree); | 166 static tree fold_builtin_fabs (location_t, tree, tree); |
165 static tree fold_builtin_abs (location_t, tree, tree); | 167 static tree fold_builtin_abs (location_t, tree, tree); |
166 static tree fold_builtin_unordered_cmp (location_t, tree, tree, tree, enum tree_code, | 168 static tree fold_builtin_unordered_cmp (location_t, tree, tree, tree, enum tree_code, |
167 enum tree_code); | 169 enum tree_code); |
168 static tree fold_builtin_0 (location_t, tree); | |
169 static tree fold_builtin_1 (location_t, tree, tree); | |
170 static tree fold_builtin_2 (location_t, tree, tree, tree); | |
171 static tree fold_builtin_3 (location_t, tree, tree, tree, tree); | |
172 static tree fold_builtin_varargs (location_t, tree, tree*, int); | 170 static tree fold_builtin_varargs (location_t, tree, tree*, int); |
173 | 171 |
174 static tree fold_builtin_strpbrk (location_t, tree, tree, tree); | 172 static tree fold_builtin_strpbrk (location_t, tree, tree, tree, tree); |
175 static tree fold_builtin_strspn (location_t, tree, tree); | 173 static tree fold_builtin_strspn (location_t, tree, tree, tree); |
176 static tree fold_builtin_strcspn (location_t, tree, tree); | 174 static tree fold_builtin_strcspn (location_t, tree, tree, tree); |
177 | 175 |
178 static rtx expand_builtin_object_size (tree); | 176 static rtx expand_builtin_object_size (tree); |
179 static rtx expand_builtin_memory_chk (tree, rtx, machine_mode, | 177 static rtx expand_builtin_memory_chk (tree, rtx, machine_mode, |
180 enum built_in_function); | 178 enum built_in_function); |
181 static void maybe_emit_chk_warning (tree, enum built_in_function); | 179 static void maybe_emit_chk_warning (tree, enum built_in_function); |
561 "referenced argument declared here"); | 559 "referenced argument declared here"); |
562 TREE_NO_WARNING (arg) = 1; | 560 TREE_NO_WARNING (arg) = 1; |
563 } | 561 } |
564 } | 562 } |
565 | 563 |
564 /* For a call EXPR (which may be null) that expects a string argument | |
565 and SRC as the argument, returns false if SRC is a character array | |
566 with no terminating NUL. When nonnull, BOUND is the number of | |
567 characters in which to expect the terminating NUL. | |
568 When EXPR is nonnull also issues a warning. */ | |
569 | |
570 bool | |
571 check_nul_terminated_array (tree expr, tree src, tree bound /* = NULL_TREE */) | |
572 { | |
573 tree size; | |
574 bool exact; | |
575 tree nonstr = unterminated_array (src, &size, &exact); | |
576 if (!nonstr) | |
577 return true; | |
578 | |
579 /* NONSTR refers to the non-nul terminated constant array and SIZE | |
580 is the constant size of the array in bytes. EXACT is true when | |
581 SIZE is exact. */ | |
582 | |
583 if (bound) | |
584 { | |
585 wide_int min, max; | |
586 if (TREE_CODE (bound) == INTEGER_CST) | |
587 min = max = wi::to_wide (bound); | |
588 else | |
589 { | |
590 value_range_kind rng = get_range_info (bound, &min, &max); | |
591 if (rng != VR_RANGE) | |
592 return true; | |
593 } | |
594 | |
595 if (wi::leu_p (min, wi::to_wide (size))) | |
596 return true; | |
597 } | |
598 | |
599 if (expr && !TREE_NO_WARNING (expr)) | |
600 { | |
601 tree fndecl = get_callee_fndecl (expr); | |
602 const char *fname = IDENTIFIER_POINTER (DECL_NAME (fndecl)); | |
603 warn_string_no_nul (EXPR_LOCATION (expr), fname, src, nonstr); | |
604 } | |
605 | |
606 return false; | |
607 } | |
608 | |
566 /* If EXP refers to an unterminated constant character array return | 609 /* If EXP refers to an unterminated constant character array return |
567 the declaration of the object of which the array is a member or | 610 the declaration of the object of which the array is a member or |
568 element and if SIZE is not null, set *SIZE to the size of | 611 element and if SIZE is not null, set *SIZE to the size of |
569 the unterminated array and set *EXACT if the size is exact or | 612 the unterminated array and set *EXACT if the size is exact or |
570 clear it otherwise. Otherwise return null. */ | 613 clear it otherwise. Otherwise return null. */ |
572 tree | 615 tree |
573 unterminated_array (tree exp, tree *size /* = NULL */, bool *exact /* = NULL */) | 616 unterminated_array (tree exp, tree *size /* = NULL */, bool *exact /* = NULL */) |
574 { | 617 { |
575 /* C_STRLEN will return NULL and set DECL in the info | 618 /* C_STRLEN will return NULL and set DECL in the info |
576 structure if EXP references a unterminated array. */ | 619 structure if EXP references a unterminated array. */ |
577 c_strlen_data data; | 620 c_strlen_data lendata = { }; |
578 memset (&data, 0, sizeof (c_strlen_data)); | 621 tree len = c_strlen (exp, 1, &lendata); |
579 tree len = c_strlen (exp, 1, &data); | 622 if (len == NULL_TREE && lendata.minlen && lendata.decl) |
580 if (len == NULL_TREE && data.len && data.decl) | |
581 { | 623 { |
582 if (size) | 624 if (size) |
583 { | 625 { |
584 len = data.len; | 626 len = lendata.minlen; |
585 if (data.off) | 627 if (lendata.off) |
586 { | 628 { |
587 /* Constant offsets are already accounted for in data.len, but | 629 /* Constant offsets are already accounted for in LENDATA.MINLEN, |
588 not in a SSA_NAME + CST expression. */ | 630 but not in a SSA_NAME + CST expression. */ |
589 if (TREE_CODE (data.off) == INTEGER_CST) | 631 if (TREE_CODE (lendata.off) == INTEGER_CST) |
590 *exact = true; | 632 *exact = true; |
591 else if (TREE_CODE (data.off) == PLUS_EXPR | 633 else if (TREE_CODE (lendata.off) == PLUS_EXPR |
592 && TREE_CODE (TREE_OPERAND (data.off, 1)) == INTEGER_CST) | 634 && TREE_CODE (TREE_OPERAND (lendata.off, 1)) == INTEGER_CST) |
593 { | 635 { |
594 /* Subtract the offset from the size of the array. */ | 636 /* Subtract the offset from the size of the array. */ |
595 *exact = false; | 637 *exact = false; |
596 tree temp = TREE_OPERAND (data.off, 1); | 638 tree temp = TREE_OPERAND (lendata.off, 1); |
597 temp = fold_convert (ssizetype, temp); | 639 temp = fold_convert (ssizetype, temp); |
598 len = fold_build2 (MINUS_EXPR, ssizetype, len, temp); | 640 len = fold_build2 (MINUS_EXPR, ssizetype, len, temp); |
599 } | 641 } |
600 else | 642 else |
601 *exact = false; | 643 *exact = false; |
603 else | 645 else |
604 *exact = true; | 646 *exact = true; |
605 | 647 |
606 *size = len; | 648 *size = len; |
607 } | 649 } |
608 return data.decl; | 650 return lendata.decl; |
609 } | 651 } |
610 | 652 |
611 return NULL_TREE; | 653 return NULL_TREE; |
612 } | 654 } |
613 | 655 |
619 | 661 |
620 ONLY_VALUE should be nonzero if the result is not going to be emitted | 662 ONLY_VALUE should be nonzero if the result is not going to be emitted |
621 into the instruction stream and zero if it is going to be expanded. | 663 into the instruction stream and zero if it is going to be expanded. |
622 E.g. with i++ ? "foo" : "bar", if ONLY_VALUE is nonzero, constant 3 | 664 E.g. with i++ ? "foo" : "bar", if ONLY_VALUE is nonzero, constant 3 |
623 is returned, otherwise NULL, since | 665 is returned, otherwise NULL, since |
624 len = c_strlen (src, 1); if (len) expand_expr (len, ...); would not | 666 len = c_strlen (ARG, 1); if (len) expand_expr (len, ...); would not |
625 evaluate the side-effects. | 667 evaluate the side-effects. |
626 | 668 |
627 If ONLY_VALUE is two then we do not emit warnings about out-of-bound | 669 If ONLY_VALUE is two then we do not emit warnings about out-of-bound |
628 accesses. Note that this implies the result is not going to be emitted | 670 accesses. Note that this implies the result is not going to be emitted |
629 into the instruction stream. | 671 into the instruction stream. |
630 | 672 |
631 Additional information about the string accessed may be recorded | 673 Additional information about the string accessed may be recorded |
632 in DATA. For example, if SRC references an unterminated string, | 674 in DATA. For example, if ARG references an unterminated string, |
633 then the declaration will be stored in the DECL field. If the | 675 then the declaration will be stored in the DECL field. If the |
634 length of the unterminated string can be determined, it'll be | 676 length of the unterminated string can be determined, it'll be |
635 stored in the LEN field. Note this length could well be different | 677 stored in the LEN field. Note this length could well be different |
636 than what a C strlen call would return. | 678 than what a C strlen call would return. |
637 | 679 |
639 4 for wide characer strings. ELTSIZE is by default 1. | 681 4 for wide characer strings. ELTSIZE is by default 1. |
640 | 682 |
641 The value returned is of type `ssizetype'. */ | 683 The value returned is of type `ssizetype'. */ |
642 | 684 |
643 tree | 685 tree |
644 c_strlen (tree src, int only_value, c_strlen_data *data, unsigned eltsize) | 686 c_strlen (tree arg, int only_value, c_strlen_data *data, unsigned eltsize) |
645 { | 687 { |
646 /* If we were not passed a DATA pointer, then get one to a local | 688 /* If we were not passed a DATA pointer, then get one to a local |
647 structure. That avoids having to check DATA for NULL before | 689 structure. That avoids having to check DATA for NULL before |
648 each time we want to use it. */ | 690 each time we want to use it. */ |
649 c_strlen_data local_strlen_data; | 691 c_strlen_data local_strlen_data = { }; |
650 memset (&local_strlen_data, 0, sizeof (c_strlen_data)); | |
651 if (!data) | 692 if (!data) |
652 data = &local_strlen_data; | 693 data = &local_strlen_data; |
653 | 694 |
654 gcc_checking_assert (eltsize == 1 || eltsize == 2 || eltsize == 4); | 695 gcc_checking_assert (eltsize == 1 || eltsize == 2 || eltsize == 4); |
655 STRIP_NOPS (src); | 696 |
697 tree src = STRIP_NOPS (arg); | |
656 if (TREE_CODE (src) == COND_EXPR | 698 if (TREE_CODE (src) == COND_EXPR |
657 && (only_value || !TREE_SIDE_EFFECTS (TREE_OPERAND (src, 0)))) | 699 && (only_value || !TREE_SIDE_EFFECTS (TREE_OPERAND (src, 0)))) |
658 { | 700 { |
659 tree len1, len2; | 701 tree len1, len2; |
660 | 702 |
719 return NULL_TREE; | 761 return NULL_TREE; |
720 else if (len >= maxelts) | 762 else if (len >= maxelts) |
721 { | 763 { |
722 data->decl = decl; | 764 data->decl = decl; |
723 data->off = byteoff; | 765 data->off = byteoff; |
724 data->len = ssize_int (len); | 766 data->minlen = ssize_int (len); |
725 return NULL_TREE; | 767 return NULL_TREE; |
726 } | 768 } |
727 | 769 |
728 /* For empty strings the result should be zero. */ | 770 /* For empty strings the result should be zero. */ |
729 if (len == 0) | 771 if (len == 0) |
732 /* We don't know the starting offset, but we do know that the string | 774 /* We don't know the starting offset, but we do know that the string |
733 has no internal zero bytes. If the offset falls within the bounds | 775 has no internal zero bytes. If the offset falls within the bounds |
734 of the string subtract the offset from the length of the string, | 776 of the string subtract the offset from the length of the string, |
735 and return that. Otherwise the length is zero. Take care to | 777 and return that. Otherwise the length is zero. Take care to |
736 use SAVE_EXPR in case the OFFSET has side-effects. */ | 778 use SAVE_EXPR in case the OFFSET has side-effects. */ |
737 tree offsave = TREE_SIDE_EFFECTS (byteoff) ? save_expr (byteoff) : byteoff; | 779 tree offsave = TREE_SIDE_EFFECTS (byteoff) ? save_expr (byteoff) |
738 offsave = fold_convert (ssizetype, offsave); | 780 : byteoff; |
781 offsave = fold_convert_loc (loc, sizetype, offsave); | |
739 tree condexp = fold_build2_loc (loc, LE_EXPR, boolean_type_node, offsave, | 782 tree condexp = fold_build2_loc (loc, LE_EXPR, boolean_type_node, offsave, |
740 build_int_cst (ssizetype, len)); | 783 size_int (len)); |
741 tree lenexp = size_diffop_loc (loc, ssize_int (len), offsave); | 784 tree lenexp = fold_build2_loc (loc, MINUS_EXPR, sizetype, size_int (len), |
785 offsave); | |
786 lenexp = fold_convert_loc (loc, ssizetype, lenexp); | |
742 return fold_build3_loc (loc, COND_EXPR, ssizetype, condexp, lenexp, | 787 return fold_build3_loc (loc, COND_EXPR, ssizetype, condexp, lenexp, |
743 build_zero_cst (ssizetype)); | 788 build_zero_cst (ssizetype)); |
744 } | 789 } |
745 | 790 |
746 /* Offset from the beginning of the string in elements. */ | 791 /* Offset from the beginning of the string in elements. */ |
757 | 802 |
758 /* If the offset is known to be out of bounds, warn, and call strlen at | 803 /* If the offset is known to be out of bounds, warn, and call strlen at |
759 runtime. */ | 804 runtime. */ |
760 if (eltoff < 0 || eltoff >= maxelts) | 805 if (eltoff < 0 || eltoff >= maxelts) |
761 { | 806 { |
762 /* Suppress multiple warnings for propagated constant strings. */ | 807 /* Suppress multiple warnings for propagated constant strings. */ |
763 if (only_value != 2 | 808 if (only_value != 2 |
764 && !TREE_NO_WARNING (src)) | 809 && !TREE_NO_WARNING (arg) |
765 { | 810 && warning_at (loc, OPT_Warray_bounds, |
766 warning_at (loc, OPT_Warray_bounds, | 811 "offset %qwi outside bounds of constant string", |
767 "offset %qwi outside bounds of constant string", | 812 eltoff)) |
768 eltoff); | 813 { |
769 TREE_NO_WARNING (src) = 1; | 814 if (decl) |
770 } | 815 inform (DECL_SOURCE_LOCATION (decl), "%qE declared here", decl); |
816 TREE_NO_WARNING (arg) = 1; | |
817 } | |
771 return NULL_TREE; | 818 return NULL_TREE; |
772 } | 819 } |
773 | 820 |
774 /* If eltoff is larger than strelts but less than maxelts the | 821 /* If eltoff is larger than strelts but less than maxelts the |
775 string length is zero, since the excess memory will be zero. */ | 822 string length is zero, since the excess memory will be zero. */ |
790 Set DECL/LEN so callers can examine them. */ | 837 Set DECL/LEN so callers can examine them. */ |
791 if (len >= maxelts - eltoff) | 838 if (len >= maxelts - eltoff) |
792 { | 839 { |
793 data->decl = decl; | 840 data->decl = decl; |
794 data->off = byteoff; | 841 data->off = byteoff; |
795 data->len = ssize_int (len); | 842 data->minlen = ssize_int (len); |
796 return NULL_TREE; | 843 return NULL_TREE; |
797 } | 844 } |
798 | 845 |
799 return ssize_int (len); | 846 return ssize_int (len); |
800 } | 847 } |
801 | 848 |
802 /* Return a constant integer corresponding to target reading | 849 /* Return a constant integer corresponding to target reading |
803 GET_MODE_BITSIZE (MODE) bits from string constant STR. */ | 850 GET_MODE_BITSIZE (MODE) bits from string constant STR. If |
804 | 851 NULL_TERMINATED_P, reading stops after '\0' character, all further ones |
805 static rtx | 852 are assumed to be zero, otherwise it reads as many characters |
806 c_readstr (const char *str, scalar_int_mode mode) | 853 as needed. */ |
854 | |
855 rtx | |
856 c_readstr (const char *str, scalar_int_mode mode, | |
857 bool null_terminated_p/*=true*/) | |
807 { | 858 { |
808 HOST_WIDE_INT ch; | 859 HOST_WIDE_INT ch; |
809 unsigned int i, j; | 860 unsigned int i, j; |
810 HOST_WIDE_INT tmp[MAX_BITSIZE_MODE_ANY_INT / HOST_BITS_PER_WIDE_INT]; | 861 HOST_WIDE_INT tmp[MAX_BITSIZE_MODE_ANY_INT / HOST_BITS_PER_WIDE_INT]; |
811 | 862 |
826 if (BYTES_BIG_ENDIAN != WORDS_BIG_ENDIAN | 877 if (BYTES_BIG_ENDIAN != WORDS_BIG_ENDIAN |
827 && GET_MODE_SIZE (mode) >= UNITS_PER_WORD) | 878 && GET_MODE_SIZE (mode) >= UNITS_PER_WORD) |
828 j = j + UNITS_PER_WORD - 2 * (j % UNITS_PER_WORD) - 1; | 879 j = j + UNITS_PER_WORD - 2 * (j % UNITS_PER_WORD) - 1; |
829 j *= BITS_PER_UNIT; | 880 j *= BITS_PER_UNIT; |
830 | 881 |
831 if (ch) | 882 if (ch || !null_terminated_p) |
832 ch = (unsigned char) str[i]; | 883 ch = (unsigned char) str[i]; |
833 tmp[j / HOST_BITS_PER_WIDE_INT] |= ch << (j % HOST_BITS_PER_WIDE_INT); | 884 tmp[j / HOST_BITS_PER_WIDE_INT] |= ch << (j % HOST_BITS_PER_WIDE_INT); |
834 } | 885 } |
835 | 886 |
836 wide_int c = wide_int::from_array (tmp, len, GET_MODE_PRECISION (mode)); | 887 wide_int c = wide_int::from_array (tmp, len, GET_MODE_PRECISION (mode)); |
976 the buffer and use the rest of it for the stack save area, which | 1027 the buffer and use the rest of it for the stack save area, which |
977 is machine-dependent. */ | 1028 is machine-dependent. */ |
978 | 1029 |
979 mem = gen_rtx_MEM (Pmode, buf_addr); | 1030 mem = gen_rtx_MEM (Pmode, buf_addr); |
980 set_mem_alias_set (mem, setjmp_alias_set); | 1031 set_mem_alias_set (mem, setjmp_alias_set); |
981 emit_move_insn (mem, targetm.builtin_setjmp_frame_value ()); | 1032 emit_move_insn (mem, hard_frame_pointer_rtx); |
982 | 1033 |
983 mem = gen_rtx_MEM (Pmode, plus_constant (Pmode, buf_addr, | 1034 mem = gen_rtx_MEM (Pmode, plus_constant (Pmode, buf_addr, |
984 GET_MODE_SIZE (Pmode))), | 1035 GET_MODE_SIZE (Pmode))), |
985 set_mem_alias_set (mem, setjmp_alias_set); | 1036 set_mem_alias_set (mem, setjmp_alias_set); |
986 | 1037 |
1017 /* Mark the static chain as clobbered here so life information | 1068 /* Mark the static chain as clobbered here so life information |
1018 doesn't get messed up for it. */ | 1069 doesn't get messed up for it. */ |
1019 chain = rtx_for_static_chain (current_function_decl, true); | 1070 chain = rtx_for_static_chain (current_function_decl, true); |
1020 if (chain && REG_P (chain)) | 1071 if (chain && REG_P (chain)) |
1021 emit_clobber (chain); | 1072 emit_clobber (chain); |
1022 | |
1023 /* Now put in the code to restore the frame pointer, and argument | |
1024 pointer, if needed. */ | |
1025 if (! targetm.have_nonlocal_goto ()) | |
1026 { | |
1027 /* First adjust our frame pointer to its actual value. It was | |
1028 previously set to the start of the virtual area corresponding to | |
1029 the stacked variables when we branched here and now needs to be | |
1030 adjusted to the actual hardware fp value. | |
1031 | |
1032 Assignments to virtual registers are converted by | |
1033 instantiate_virtual_regs into the corresponding assignment | |
1034 to the underlying register (fp in this case) that makes | |
1035 the original assignment true. | |
1036 So the following insn will actually be decrementing fp by | |
1037 TARGET_STARTING_FRAME_OFFSET. */ | |
1038 emit_move_insn (virtual_stack_vars_rtx, hard_frame_pointer_rtx); | |
1039 | |
1040 /* Restoring the frame pointer also modifies the hard frame pointer. | |
1041 Mark it used (so that the previous assignment remains live once | |
1042 the frame pointer is eliminated) and clobbered (to represent the | |
1043 implicit update from the assignment). */ | |
1044 emit_use (hard_frame_pointer_rtx); | |
1045 emit_clobber (hard_frame_pointer_rtx); | |
1046 } | |
1047 | 1073 |
1048 if (!HARD_FRAME_POINTER_IS_ARG_POINTER && fixed_regs[ARG_POINTER_REGNUM]) | 1074 if (!HARD_FRAME_POINTER_IS_ARG_POINTER && fixed_regs[ARG_POINTER_REGNUM]) |
1049 { | 1075 { |
1050 /* If the argument pointer can be eliminated in favor of the | 1076 /* If the argument pointer can be eliminated in favor of the |
1051 frame pointer, we don't need to restore it. We assume here | 1077 frame pointer, we don't need to restore it. We assume here |
1132 get copied into the static_chain pointer, but it does not matter | 1158 get copied into the static_chain pointer, but it does not matter |
1133 what that value is, because builtin_setjmp does not use it. */ | 1159 what that value is, because builtin_setjmp does not use it. */ |
1134 emit_insn (targetm.gen_nonlocal_goto (value, lab, stack, fp)); | 1160 emit_insn (targetm.gen_nonlocal_goto (value, lab, stack, fp)); |
1135 else | 1161 else |
1136 { | 1162 { |
1137 lab = copy_to_reg (lab); | |
1138 | |
1139 emit_clobber (gen_rtx_MEM (BLKmode, gen_rtx_SCRATCH (VOIDmode))); | 1163 emit_clobber (gen_rtx_MEM (BLKmode, gen_rtx_SCRATCH (VOIDmode))); |
1140 emit_clobber (gen_rtx_MEM (BLKmode, hard_frame_pointer_rtx)); | 1164 emit_clobber (gen_rtx_MEM (BLKmode, hard_frame_pointer_rtx)); |
1141 | 1165 |
1166 lab = copy_to_reg (lab); | |
1167 | |
1168 /* Restore the frame pointer and stack pointer. We must use a | |
1169 temporary since the setjmp buffer may be a local. */ | |
1170 fp = copy_to_reg (fp); | |
1171 emit_stack_restore (SAVE_NONLOCAL, stack); | |
1172 | |
1173 /* Ensure the frame pointer move is not optimized. */ | |
1174 emit_insn (gen_blockage ()); | |
1175 emit_clobber (hard_frame_pointer_rtx); | |
1176 emit_clobber (frame_pointer_rtx); | |
1142 emit_move_insn (hard_frame_pointer_rtx, fp); | 1177 emit_move_insn (hard_frame_pointer_rtx, fp); |
1143 emit_stack_restore (SAVE_NONLOCAL, stack); | |
1144 | 1178 |
1145 emit_use (hard_frame_pointer_rtx); | 1179 emit_use (hard_frame_pointer_rtx); |
1146 emit_use (stack_pointer_rtx); | 1180 emit_use (stack_pointer_rtx); |
1147 emit_indirect_jump (lab); | 1181 emit_indirect_jump (lab); |
1148 } | 1182 } |
1276 /* ??? We no longer need to pass the static chain value, afaik. */ | 1310 /* ??? We no longer need to pass the static chain value, afaik. */ |
1277 if (targetm.have_nonlocal_goto ()) | 1311 if (targetm.have_nonlocal_goto ()) |
1278 emit_insn (targetm.gen_nonlocal_goto (const0_rtx, r_label, r_sp, r_fp)); | 1312 emit_insn (targetm.gen_nonlocal_goto (const0_rtx, r_label, r_sp, r_fp)); |
1279 else | 1313 else |
1280 { | 1314 { |
1281 r_label = copy_to_reg (r_label); | |
1282 | |
1283 emit_clobber (gen_rtx_MEM (BLKmode, gen_rtx_SCRATCH (VOIDmode))); | 1315 emit_clobber (gen_rtx_MEM (BLKmode, gen_rtx_SCRATCH (VOIDmode))); |
1284 emit_clobber (gen_rtx_MEM (BLKmode, hard_frame_pointer_rtx)); | 1316 emit_clobber (gen_rtx_MEM (BLKmode, hard_frame_pointer_rtx)); |
1285 | 1317 |
1286 /* Restore frame pointer for containing function. */ | 1318 r_label = copy_to_reg (r_label); |
1319 | |
1320 /* Restore the frame pointer and stack pointer. We must use a | |
1321 temporary since the setjmp buffer may be a local. */ | |
1322 r_fp = copy_to_reg (r_fp); | |
1323 emit_stack_restore (SAVE_NONLOCAL, r_sp); | |
1324 | |
1325 /* Ensure the frame pointer move is not optimized. */ | |
1326 emit_insn (gen_blockage ()); | |
1327 emit_clobber (hard_frame_pointer_rtx); | |
1328 emit_clobber (frame_pointer_rtx); | |
1287 emit_move_insn (hard_frame_pointer_rtx, r_fp); | 1329 emit_move_insn (hard_frame_pointer_rtx, r_fp); |
1288 emit_stack_restore (SAVE_NONLOCAL, r_sp); | |
1289 | 1330 |
1290 /* USE of hard_frame_pointer_rtx added for consistency; | 1331 /* USE of hard_frame_pointer_rtx added for consistency; |
1291 not clear if really needed. */ | 1332 not clear if really needed. */ |
1292 emit_use (hard_frame_pointer_rtx); | 1333 emit_use (hard_frame_pointer_rtx); |
1293 emit_use (stack_pointer_rtx); | 1334 emit_use (stack_pointer_rtx); |
1405 op2 = const0_rtx; | 1446 op2 = const0_rtx; |
1406 } | 1447 } |
1407 | 1448 |
1408 if (targetm.have_prefetch ()) | 1449 if (targetm.have_prefetch ()) |
1409 { | 1450 { |
1410 struct expand_operand ops[3]; | 1451 class expand_operand ops[3]; |
1411 | 1452 |
1412 create_address_operand (&ops[0], op0); | 1453 create_address_operand (&ops[0], op0); |
1413 create_integer_operand (&ops[1], INTVAL (op1)); | 1454 create_integer_operand (&ops[1], INTVAL (op1)); |
1414 create_integer_operand (&ops[2], INTVAL (op2)); | 1455 create_integer_operand (&ops[2], INTVAL (op2)); |
1415 if (maybe_expand_insn (targetm.code_for_prefetch, 3, ops)) | 1456 if (maybe_expand_insn (targetm.code_for_prefetch, 3, ops)) |
1421 if (!MEM_P (op0) && side_effects_p (op0)) | 1462 if (!MEM_P (op0) && side_effects_p (op0)) |
1422 emit_insn (op0); | 1463 emit_insn (op0); |
1423 } | 1464 } |
1424 | 1465 |
1425 /* Get a MEM rtx for expression EXP which is the address of an operand | 1466 /* Get a MEM rtx for expression EXP which is the address of an operand |
1426 to be used in a string instruction (cmpstrsi, movmemsi, ..). LEN is | 1467 to be used in a string instruction (cmpstrsi, cpymemsi, ..). LEN is |
1427 the maximum length of the block of memory that might be accessed or | 1468 the maximum length of the block of memory that might be accessed or |
1428 NULL if unknown. */ | 1469 NULL if unknown. */ |
1429 | 1470 |
1430 static rtx | 1471 static rtx |
1431 get_memory_rtx (tree exp, tree len) | 1472 get_memory_rtx (tree exp, tree len) |
1643 size = GET_MODE_SIZE (Pmode); | 1684 size = GET_MODE_SIZE (Pmode); |
1644 | 1685 |
1645 /* Save the structure value address unless this is passed as an | 1686 /* Save the structure value address unless this is passed as an |
1646 "invisible" first argument. */ | 1687 "invisible" first argument. */ |
1647 if (struct_incoming_value) | 1688 if (struct_incoming_value) |
1648 { | 1689 emit_move_insn (adjust_address (registers, Pmode, size), |
1649 emit_move_insn (adjust_address (registers, Pmode, size), | 1690 copy_to_reg (struct_incoming_value)); |
1650 copy_to_reg (struct_incoming_value)); | |
1651 size += GET_MODE_SIZE (Pmode); | |
1652 } | |
1653 | 1691 |
1654 /* Return the address of the block. */ | 1692 /* Return the address of the block. */ |
1655 return copy_addr_to_reg (XEXP (registers, 0)); | 1693 return copy_addr_to_reg (XEXP (registers, 0)); |
1656 } | 1694 } |
1657 | 1695 |
1796 rtx value = gen_reg_rtx (Pmode); | 1834 rtx value = gen_reg_rtx (Pmode); |
1797 emit_move_insn (value, adjust_address (arguments, Pmode, size)); | 1835 emit_move_insn (value, adjust_address (arguments, Pmode, size)); |
1798 emit_move_insn (struct_value, value); | 1836 emit_move_insn (struct_value, value); |
1799 if (REG_P (struct_value)) | 1837 if (REG_P (struct_value)) |
1800 use_reg (&call_fusage, struct_value); | 1838 use_reg (&call_fusage, struct_value); |
1801 size += GET_MODE_SIZE (Pmode); | |
1802 } | 1839 } |
1803 | 1840 |
1804 /* All arguments and registers used for the call are set up by now! */ | 1841 /* All arguments and registers used for the call are set up by now! */ |
1805 function = prepare_call_address (NULL, function, NULL, &call_fusage, 0, 0); | 1842 function = prepare_call_address (NULL, function, NULL, &call_fusage, 0, 0); |
1806 | 1843 |
2065 CASE_MATHFN (POW10) | 2102 CASE_MATHFN (POW10) |
2066 CASE_MATHFN (REMAINDER) | 2103 CASE_MATHFN (REMAINDER) |
2067 CASE_MATHFN (REMQUO) | 2104 CASE_MATHFN (REMQUO) |
2068 CASE_MATHFN_FLOATN (RINT) | 2105 CASE_MATHFN_FLOATN (RINT) |
2069 CASE_MATHFN_FLOATN (ROUND) | 2106 CASE_MATHFN_FLOATN (ROUND) |
2107 CASE_MATHFN_FLOATN (ROUNDEVEN) | |
2070 CASE_MATHFN (SCALB) | 2108 CASE_MATHFN (SCALB) |
2071 CASE_MATHFN (SCALBLN) | 2109 CASE_MATHFN (SCALBLN) |
2072 CASE_MATHFN (SCALBN) | 2110 CASE_MATHFN (SCALBN) |
2073 CASE_MATHFN (SIGNBIT) | 2111 CASE_MATHFN (SIGNBIT) |
2074 CASE_MATHFN (SIGNIFICAND) | 2112 CASE_MATHFN (SIGNIFICAND) |
2454 icode = interclass_mathfn_icode (arg, fndecl); | 2492 icode = interclass_mathfn_icode (arg, fndecl); |
2455 mode = TYPE_MODE (TREE_TYPE (arg)); | 2493 mode = TYPE_MODE (TREE_TYPE (arg)); |
2456 | 2494 |
2457 if (icode != CODE_FOR_nothing) | 2495 if (icode != CODE_FOR_nothing) |
2458 { | 2496 { |
2459 struct expand_operand ops[1]; | 2497 class expand_operand ops[1]; |
2460 rtx_insn *last = get_last_insn (); | 2498 rtx_insn *last = get_last_insn (); |
2461 tree orig_arg = arg; | 2499 tree orig_arg = arg; |
2462 | 2500 |
2463 /* Wrap the computation of the argument in a SAVE_EXPR, as we may | 2501 /* Wrap the computation of the argument in a SAVE_EXPR, as we may |
2464 need to expand the argument again. This way, we will not perform | 2502 need to expand the argument again. This way, we will not perform |
2682 tree fallback_fndecl; | 2720 tree fallback_fndecl; |
2683 machine_mode mode; | 2721 machine_mode mode; |
2684 tree arg; | 2722 tree arg; |
2685 | 2723 |
2686 if (!validate_arglist (exp, REAL_TYPE, VOID_TYPE)) | 2724 if (!validate_arglist (exp, REAL_TYPE, VOID_TYPE)) |
2687 gcc_unreachable (); | 2725 return NULL_RTX; |
2688 | 2726 |
2689 arg = CALL_EXPR_ARG (exp, 0); | 2727 arg = CALL_EXPR_ARG (exp, 0); |
2690 | 2728 |
2691 switch (DECL_FUNCTION_CODE (fndecl)) | 2729 switch (DECL_FUNCTION_CODE (fndecl)) |
2692 { | 2730 { |
2818 tree arg; | 2856 tree arg; |
2819 machine_mode mode; | 2857 machine_mode mode; |
2820 enum built_in_function fallback_fn = BUILT_IN_NONE; | 2858 enum built_in_function fallback_fn = BUILT_IN_NONE; |
2821 | 2859 |
2822 if (!validate_arglist (exp, REAL_TYPE, VOID_TYPE)) | 2860 if (!validate_arglist (exp, REAL_TYPE, VOID_TYPE)) |
2823 gcc_unreachable (); | 2861 return NULL_RTX; |
2824 | 2862 |
2825 arg = CALL_EXPR_ARG (exp, 0); | 2863 arg = CALL_EXPR_ARG (exp, 0); |
2826 | 2864 |
2827 switch (DECL_FUNCTION_CODE (fndecl)) | 2865 switch (DECL_FUNCTION_CODE (fndecl)) |
2828 { | 2866 { |
2955 machine_mode target_mode) | 2993 machine_mode target_mode) |
2956 { | 2994 { |
2957 if (!validate_arglist (exp, POINTER_TYPE, VOID_TYPE)) | 2995 if (!validate_arglist (exp, POINTER_TYPE, VOID_TYPE)) |
2958 return NULL_RTX; | 2996 return NULL_RTX; |
2959 | 2997 |
2960 struct expand_operand ops[4]; | 2998 class expand_operand ops[4]; |
2961 rtx pat; | 2999 rtx pat; |
2962 tree len; | 3000 tree len; |
2963 tree src = CALL_EXPR_ARG (exp, 0); | 3001 tree src = CALL_EXPR_ARG (exp, 0); |
2964 rtx src_reg; | 3002 rtx src_reg; |
2965 rtx_insn *before_strlen; | 3003 rtx_insn *before_strlen; |
3074 tree maxobjsize = max_object_size (); | 3112 tree maxobjsize = max_object_size (); |
3075 tree func = get_callee_fndecl (exp); | 3113 tree func = get_callee_fndecl (exp); |
3076 | 3114 |
3077 /* FIXME: Change c_strlen() to return sizetype instead of ssizetype | 3115 /* FIXME: Change c_strlen() to return sizetype instead of ssizetype |
3078 so these conversions aren't necessary. */ | 3116 so these conversions aren't necessary. */ |
3079 c_strlen_data data; | 3117 c_strlen_data lendata = { }; |
3080 memset (&data, 0, sizeof (c_strlen_data)); | 3118 tree len = c_strlen (src, 0, &lendata, 1); |
3081 tree len = c_strlen (src, 0, &data, 1); | |
3082 if (len) | 3119 if (len) |
3083 len = fold_convert_loc (loc, TREE_TYPE (bound), len); | 3120 len = fold_convert_loc (loc, TREE_TYPE (bound), len); |
3084 | 3121 |
3085 if (TREE_CODE (bound) == INTEGER_CST) | 3122 if (TREE_CODE (bound) == INTEGER_CST) |
3086 { | 3123 { |
3088 && tree_int_cst_lt (maxobjsize, bound) | 3125 && tree_int_cst_lt (maxobjsize, bound) |
3089 && warning_at (loc, OPT_Wstringop_overflow_, | 3126 && warning_at (loc, OPT_Wstringop_overflow_, |
3090 "%K%qD specified bound %E " | 3127 "%K%qD specified bound %E " |
3091 "exceeds maximum object size %E", | 3128 "exceeds maximum object size %E", |
3092 exp, func, bound, maxobjsize)) | 3129 exp, func, bound, maxobjsize)) |
3093 TREE_NO_WARNING (exp) = true; | 3130 TREE_NO_WARNING (exp) = true; |
3094 | 3131 |
3095 bool exact = true; | 3132 bool exact = true; |
3096 if (!len || TREE_CODE (len) != INTEGER_CST) | 3133 if (!len || TREE_CODE (len) != INTEGER_CST) |
3097 { | 3134 { |
3098 /* Clear EXACT if LEN may be less than SRC suggests, | 3135 /* Clear EXACT if LEN may be less than SRC suggests, |
3099 such as in | 3136 such as in |
3100 strnlen (&a[i], sizeof a) | 3137 strnlen (&a[i], sizeof a) |
3101 where the value of i is unknown. Unless i's value is | 3138 where the value of i is unknown. Unless i's value is |
3102 zero, the call is unsafe because the bound is greater. */ | 3139 zero, the call is unsafe because the bound is greater. */ |
3103 data.decl = unterminated_array (src, &len, &exact); | 3140 lendata.decl = unterminated_array (src, &len, &exact); |
3104 if (!data.decl) | 3141 if (!lendata.decl) |
3105 return NULL_RTX; | 3142 return NULL_RTX; |
3106 } | 3143 } |
3107 | 3144 |
3108 if (data.decl | 3145 if (lendata.decl |
3109 && !TREE_NO_WARNING (exp) | 3146 && !TREE_NO_WARNING (exp) |
3110 && ((tree_int_cst_lt (len, bound)) | 3147 && ((tree_int_cst_lt (len, bound)) |
3111 || !exact)) | 3148 || !exact)) |
3112 { | 3149 { |
3113 location_t warnloc | 3150 location_t warnloc |
3119 "of unterminated array") | 3156 "of unterminated array") |
3120 : G_("%K%qD specified bound %E may exceed the size " | 3157 : G_("%K%qD specified bound %E may exceed the size " |
3121 "of at most %E of unterminated array"), | 3158 "of at most %E of unterminated array"), |
3122 exp, func, bound, len)) | 3159 exp, func, bound, len)) |
3123 { | 3160 { |
3124 inform (DECL_SOURCE_LOCATION (data.decl), | 3161 inform (DECL_SOURCE_LOCATION (lendata.decl), |
3125 "referenced argument declared here"); | 3162 "referenced argument declared here"); |
3126 TREE_NO_WARNING (exp) = true; | 3163 TREE_NO_WARNING (exp) = true; |
3127 return NULL_RTX; | 3164 return NULL_RTX; |
3128 } | 3165 } |
3129 } | 3166 } |
3142 enum value_range_kind rng = get_range_info (bound, &min, &max); | 3179 enum value_range_kind rng = get_range_info (bound, &min, &max); |
3143 if (rng != VR_RANGE) | 3180 if (rng != VR_RANGE) |
3144 return NULL_RTX; | 3181 return NULL_RTX; |
3145 | 3182 |
3146 if (!TREE_NO_WARNING (exp) | 3183 if (!TREE_NO_WARNING (exp) |
3147 && wi::ltu_p (wi::to_wide (maxobjsize), min) | 3184 && wi::ltu_p (wi::to_wide (maxobjsize, min.get_precision ()), min) |
3148 && warning_at (loc, OPT_Wstringop_overflow_, | 3185 && warning_at (loc, OPT_Wstringop_overflow_, |
3149 "%K%qD specified bound [%wu, %wu] " | 3186 "%K%qD specified bound [%wu, %wu] " |
3150 "exceeds maximum object size %E", | 3187 "exceeds maximum object size %E", |
3151 exp, func, min.to_uhwi (), max.to_uhwi (), maxobjsize)) | 3188 exp, func, min.to_uhwi (), max.to_uhwi (), maxobjsize)) |
3152 TREE_NO_WARNING (exp) = true; | 3189 TREE_NO_WARNING (exp) = true; |
3153 | 3190 |
3154 bool exact = true; | 3191 bool exact = true; |
3155 if (!len || TREE_CODE (len) != INTEGER_CST) | 3192 if (!len || TREE_CODE (len) != INTEGER_CST) |
3156 { | 3193 { |
3157 data.decl = unterminated_array (src, &len, &exact); | 3194 lendata.decl = unterminated_array (src, &len, &exact); |
3158 if (!data.decl) | 3195 if (!lendata.decl) |
3159 return NULL_RTX; | 3196 return NULL_RTX; |
3160 } | 3197 } |
3161 | 3198 |
3162 if (data.decl | 3199 if (lendata.decl |
3163 && !TREE_NO_WARNING (exp) | 3200 && !TREE_NO_WARNING (exp) |
3164 && (wi::ltu_p (wi::to_wide (len), min) | 3201 && (wi::ltu_p (wi::to_wide (len), min) |
3165 || !exact)) | 3202 || !exact)) |
3166 { | 3203 { |
3167 location_t warnloc | 3204 location_t warnloc |
3173 "the size %E of unterminated array") | 3210 "the size %E of unterminated array") |
3174 : G_("%K%qD specified bound [%wu, %wu] may exceed " | 3211 : G_("%K%qD specified bound [%wu, %wu] may exceed " |
3175 "the size of at most %E of unterminated array"), | 3212 "the size of at most %E of unterminated array"), |
3176 exp, func, min.to_uhwi (), max.to_uhwi (), len)) | 3213 exp, func, min.to_uhwi (), max.to_uhwi (), len)) |
3177 { | 3214 { |
3178 inform (DECL_SOURCE_LOCATION (data.decl), | 3215 inform (DECL_SOURCE_LOCATION (lendata.decl), |
3179 "referenced argument declared here"); | 3216 "referenced argument declared here"); |
3180 TREE_NO_WARNING (exp) = true; | 3217 TREE_NO_WARNING (exp) = true; |
3181 } | 3218 } |
3182 } | 3219 } |
3183 | 3220 |
3184 if (data.decl) | 3221 if (lendata.decl) |
3185 return NULL_RTX; | 3222 return NULL_RTX; |
3186 | 3223 |
3187 if (wi::gtu_p (min, wi::to_wide (len))) | 3224 if (wi::gtu_p (min, wi::to_wide (len))) |
3188 return expand_expr (len, target, target_mode, EXPAND_NORMAL); | 3225 return expand_expr (len, target, target_mode, EXPAND_NORMAL); |
3189 | 3226 |
3302 SIZE_MAX. | 3339 SIZE_MAX. |
3303 | 3340 |
3304 If the call is successfully verified as safe return true, otherwise | 3341 If the call is successfully verified as safe return true, otherwise |
3305 return false. */ | 3342 return false. */ |
3306 | 3343 |
3307 static bool | 3344 bool |
3308 check_access (tree exp, tree, tree, tree dstwrite, | 3345 check_access (tree exp, tree, tree, tree dstwrite, |
3309 tree maxread, tree srcstr, tree dstsize) | 3346 tree maxread, tree srcstr, tree dstsize) |
3310 { | 3347 { |
3311 int opt = OPT_Wstringop_overflow_; | 3348 int opt = OPT_Wstringop_overflow_; |
3312 | 3349 |
3333 /* Try to determine the range of lengths the source string | 3370 /* Try to determine the range of lengths the source string |
3334 refers to. If it can be determined and is less than | 3371 refers to. If it can be determined and is less than |
3335 the upper bound given by MAXREAD add one to it for | 3372 the upper bound given by MAXREAD add one to it for |
3336 the terminating nul. Otherwise, set it to one for | 3373 the terminating nul. Otherwise, set it to one for |
3337 the same reason, or to MAXREAD as appropriate. */ | 3374 the same reason, or to MAXREAD as appropriate. */ |
3338 get_range_strlen (srcstr, range); | 3375 c_strlen_data lendata = { }; |
3376 get_range_strlen (srcstr, &lendata, /* eltsize = */ 1); | |
3377 range[0] = lendata.minlen; | |
3378 range[1] = lendata.maxbound ? lendata.maxbound : lendata.maxlen; | |
3339 if (range[0] && (!maxread || TREE_CODE (maxread) == INTEGER_CST)) | 3379 if (range[0] && (!maxread || TREE_CODE (maxread) == INTEGER_CST)) |
3340 { | 3380 { |
3341 if (maxread && tree_int_cst_le (maxread, range[0])) | 3381 if (maxread && tree_int_cst_le (maxread, range[0])) |
3342 range[0] = range[1] = maxread; | 3382 range[0] = range[1] = maxread; |
3343 else | 3383 else |
3395 location_t loc = tree_nonartificial_location (exp); | 3435 location_t loc = tree_nonartificial_location (exp); |
3396 loc = expansion_point_location_if_in_system_header (loc); | 3436 loc = expansion_point_location_if_in_system_header (loc); |
3397 | 3437 |
3398 bool warned; | 3438 bool warned; |
3399 if (range[0] == range[1]) | 3439 if (range[0] == range[1]) |
3400 warned = warning_at (loc, opt, | 3440 warned = (func |
3401 "%K%qD specified size %E " | 3441 ? warning_at (loc, opt, |
3402 "exceeds maximum object size %E", | 3442 "%K%qD specified size %E " |
3403 exp, func, range[0], maxobjsize); | 3443 "exceeds maximum object size %E", |
3444 exp, func, range[0], maxobjsize) | |
3445 : warning_at (loc, opt, | |
3446 "%Kspecified size %E " | |
3447 "exceeds maximum object size %E", | |
3448 exp, range[0], maxobjsize)); | |
3404 else | 3449 else |
3405 warned = warning_at (loc, opt, | 3450 warned = (func |
3406 "%K%qD specified size between %E and %E " | 3451 ? warning_at (loc, opt, |
3407 "exceeds maximum object size %E", | 3452 "%K%qD specified size between %E and %E " |
3408 exp, func, | 3453 "exceeds maximum object size %E", |
3409 range[0], range[1], maxobjsize); | 3454 exp, func, |
3455 range[0], range[1], maxobjsize) | |
3456 : warning_at (loc, opt, | |
3457 "%Kspecified size between %E and %E " | |
3458 "exceeds maximum object size %E", | |
3459 exp, range[0], range[1], maxobjsize)); | |
3410 if (warned) | 3460 if (warned) |
3411 TREE_NO_WARNING (exp) = true; | 3461 TREE_NO_WARNING (exp) = true; |
3412 | 3462 |
3413 return false; | 3463 return false; |
3414 } | 3464 } |
3433 return false; | 3483 return false; |
3434 | 3484 |
3435 location_t loc = tree_nonartificial_location (exp); | 3485 location_t loc = tree_nonartificial_location (exp); |
3436 loc = expansion_point_location_if_in_system_header (loc); | 3486 loc = expansion_point_location_if_in_system_header (loc); |
3437 | 3487 |
3488 bool warned = false; | |
3438 if (dstwrite == slen && at_least_one) | 3489 if (dstwrite == slen && at_least_one) |
3439 { | 3490 { |
3440 /* This is a call to strcpy with a destination of 0 size | 3491 /* This is a call to strcpy with a destination of 0 size |
3441 and a source of unknown length. The call will write | 3492 and a source of unknown length. The call will write |
3442 at least one byte past the end of the destination. */ | 3493 at least one byte past the end of the destination. */ |
3443 warning_at (loc, opt, | 3494 warned = (func |
3444 "%K%qD writing %E or more bytes into a region " | 3495 ? warning_at (loc, opt, |
3445 "of size %E overflows the destination", | 3496 "%K%qD writing %E or more bytes into " |
3446 exp, func, range[0], dstsize); | 3497 "a region of size %E overflows " |
3498 "the destination", | |
3499 exp, func, range[0], dstsize) | |
3500 : warning_at (loc, opt, | |
3501 "%Kwriting %E or more bytes into " | |
3502 "a region of size %E overflows " | |
3503 "the destination", | |
3504 exp, range[0], dstsize)); | |
3447 } | 3505 } |
3448 else if (tree_int_cst_equal (range[0], range[1])) | 3506 else if (tree_int_cst_equal (range[0], range[1])) |
3449 warning_n (loc, opt, tree_to_uhwi (range[0]), | 3507 warned = (func |
3450 "%K%qD writing %E byte into a region " | 3508 ? warning_n (loc, opt, tree_to_uhwi (range[0]), |
3451 "of size %E overflows the destination", | 3509 "%K%qD writing %E byte into a region " |
3452 "%K%qD writing %E bytes into a region " | 3510 "of size %E overflows the destination", |
3453 "of size %E overflows the destination", | 3511 "%K%qD writing %E bytes into a region " |
3454 exp, func, range[0], dstsize); | 3512 "of size %E overflows the destination", |
3513 exp, func, range[0], dstsize) | |
3514 : warning_n (loc, opt, tree_to_uhwi (range[0]), | |
3515 "%Kwriting %E byte into a region " | |
3516 "of size %E overflows the destination", | |
3517 "%Kwriting %E bytes into a region " | |
3518 "of size %E overflows the destination", | |
3519 exp, range[0], dstsize)); | |
3455 else if (tree_int_cst_sign_bit (range[1])) | 3520 else if (tree_int_cst_sign_bit (range[1])) |
3456 { | 3521 { |
3457 /* Avoid printing the upper bound if it's invalid. */ | 3522 /* Avoid printing the upper bound if it's invalid. */ |
3458 warning_at (loc, opt, | 3523 warned = (func |
3459 "%K%qD writing %E or more bytes into a region " | 3524 ? warning_at (loc, opt, |
3460 "of size %E overflows the destination", | 3525 "%K%qD writing %E or more bytes into " |
3461 exp, func, range[0], dstsize); | 3526 "a region of size %E overflows " |
3527 "the destination", | |
3528 exp, func, range[0], dstsize) | |
3529 : warning_at (loc, opt, | |
3530 "%Kwriting %E or more bytes into " | |
3531 "a region of size %E overflows " | |
3532 "the destination", | |
3533 exp, range[0], dstsize)); | |
3462 } | 3534 } |
3463 else | 3535 else |
3464 warning_at (loc, opt, | 3536 warned = (func |
3465 "%K%qD writing between %E and %E bytes into " | 3537 ? warning_at (loc, opt, |
3466 "a region of size %E overflows the destination", | 3538 "%K%qD writing between %E and %E bytes " |
3467 exp, func, range[0], range[1], | 3539 "into a region of size %E overflows " |
3468 dstsize); | 3540 "the destination", |
3541 exp, func, range[0], range[1], | |
3542 dstsize) | |
3543 : warning_at (loc, opt, | |
3544 "%Kwriting between %E and %E bytes " | |
3545 "into a region of size %E overflows " | |
3546 "the destination", | |
3547 exp, range[0], range[1], | |
3548 dstsize)); | |
3549 if (warned) | |
3550 TREE_NO_WARNING (exp) = true; | |
3469 | 3551 |
3470 /* Return error when an overflow has been detected. */ | 3552 /* Return error when an overflow has been detected. */ |
3471 return false; | 3553 return false; |
3472 } | 3554 } |
3473 } | 3555 } |
3476 of the destination object if known, or against the maximum size | 3558 of the destination object if known, or against the maximum size |
3477 of an object. */ | 3559 of an object. */ |
3478 if (maxread) | 3560 if (maxread) |
3479 { | 3561 { |
3480 get_size_range (maxread, range); | 3562 get_size_range (maxread, range); |
3481 | |
3482 /* Use the lower end for MAXREAD from now on. */ | |
3483 if (range[0]) | |
3484 maxread = range[0]; | |
3485 | |
3486 if (range[0] && dstsize && tree_fits_uhwi_p (dstsize)) | 3563 if (range[0] && dstsize && tree_fits_uhwi_p (dstsize)) |
3487 { | 3564 { |
3488 location_t loc = tree_nonartificial_location (exp); | 3565 location_t loc = tree_nonartificial_location (exp); |
3489 loc = expansion_point_location_if_in_system_header (loc); | 3566 loc = expansion_point_location_if_in_system_header (loc); |
3490 | 3567 |
3491 if (tree_int_cst_lt (maxobjsize, range[0])) | 3568 if (tree_int_cst_lt (maxobjsize, range[0])) |
3492 { | 3569 { |
3493 if (TREE_NO_WARNING (exp)) | 3570 if (TREE_NO_WARNING (exp)) |
3494 return false; | 3571 return false; |
3495 | 3572 |
3573 bool warned = false; | |
3574 | |
3496 /* Warn about crazy big sizes first since that's more | 3575 /* Warn about crazy big sizes first since that's more |
3497 likely to be meaningful than saying that the bound | 3576 likely to be meaningful than saying that the bound |
3498 is greater than the object size if both are big. */ | 3577 is greater than the object size if both are big. */ |
3499 if (range[0] == range[1]) | 3578 if (range[0] == range[1]) |
3500 warning_at (loc, opt, | 3579 warned = (func |
3501 "%K%qD specified bound %E " | 3580 ? warning_at (loc, opt, |
3502 "exceeds maximum object size %E", | 3581 "%K%qD specified bound %E " |
3503 exp, func, | 3582 "exceeds maximum object size %E", |
3504 range[0], maxobjsize); | 3583 exp, func, range[0], maxobjsize) |
3584 : warning_at (loc, opt, | |
3585 "%Kspecified bound %E " | |
3586 "exceeds maximum object size %E", | |
3587 exp, range[0], maxobjsize)); | |
3505 else | 3588 else |
3506 warning_at (loc, opt, | 3589 warned = (func |
3507 "%K%qD specified bound between %E and %E " | 3590 ? warning_at (loc, opt, |
3508 "exceeds maximum object size %E", | 3591 "%K%qD specified bound between " |
3509 exp, func, | 3592 "%E and %E exceeds maximum object " |
3510 range[0], range[1], maxobjsize); | 3593 "size %E", |
3594 exp, func, | |
3595 range[0], range[1], maxobjsize) | |
3596 : warning_at (loc, opt, | |
3597 "%Kspecified bound between " | |
3598 "%E and %E exceeds maximum object " | |
3599 "size %E", | |
3600 exp, range[0], range[1], maxobjsize)); | |
3601 if (warned) | |
3602 TREE_NO_WARNING (exp) = true; | |
3511 | 3603 |
3512 return false; | 3604 return false; |
3513 } | 3605 } |
3514 | 3606 |
3515 if (dstsize != maxobjsize && tree_int_cst_lt (dstsize, range[0])) | 3607 if (dstsize != maxobjsize && tree_int_cst_lt (dstsize, range[0])) |
3516 { | 3608 { |
3517 if (TREE_NO_WARNING (exp)) | 3609 if (TREE_NO_WARNING (exp)) |
3518 return false; | 3610 return false; |
3519 | 3611 |
3612 bool warned = false; | |
3613 | |
3520 if (tree_int_cst_equal (range[0], range[1])) | 3614 if (tree_int_cst_equal (range[0], range[1])) |
3521 warning_at (loc, opt, | 3615 warned = (func |
3522 "%K%qD specified bound %E " | 3616 ? warning_at (loc, opt, |
3523 "exceeds destination size %E", | 3617 "%K%qD specified bound %E " |
3524 exp, func, | 3618 "exceeds destination size %E", |
3525 range[0], dstsize); | 3619 exp, func, |
3620 range[0], dstsize) | |
3621 : warning_at (loc, opt, | |
3622 "%Kspecified bound %E " | |
3623 "exceeds destination size %E", | |
3624 exp, range[0], dstsize)); | |
3526 else | 3625 else |
3527 warning_at (loc, opt, | 3626 warned = (func |
3528 "%K%qD specified bound between %E and %E " | 3627 ? warning_at (loc, opt, |
3529 "exceeds destination size %E", | 3628 "%K%qD specified bound between %E " |
3530 exp, func, | 3629 "and %E exceeds destination size %E", |
3531 range[0], range[1], dstsize); | 3630 exp, func, |
3631 range[0], range[1], dstsize) | |
3632 : warning_at (loc, opt, | |
3633 "%Kspecified bound between %E " | |
3634 "and %E exceeds destination size %E", | |
3635 exp, | |
3636 range[0], range[1], dstsize)); | |
3637 if (warned) | |
3638 TREE_NO_WARNING (exp) = true; | |
3639 | |
3532 return false; | 3640 return false; |
3533 } | 3641 } |
3534 } | 3642 } |
3535 } | 3643 } |
3536 | 3644 |
3541 && tree_int_cst_lt (slen, range[0])) | 3649 && tree_int_cst_lt (slen, range[0])) |
3542 { | 3650 { |
3543 if (TREE_NO_WARNING (exp)) | 3651 if (TREE_NO_WARNING (exp)) |
3544 return false; | 3652 return false; |
3545 | 3653 |
3654 bool warned = false; | |
3546 location_t loc = tree_nonartificial_location (exp); | 3655 location_t loc = tree_nonartificial_location (exp); |
3656 loc = expansion_point_location_if_in_system_header (loc); | |
3547 | 3657 |
3548 if (tree_int_cst_equal (range[0], range[1])) | 3658 if (tree_int_cst_equal (range[0], range[1])) |
3549 warning_n (loc, opt, tree_to_uhwi (range[0]), | 3659 warned = (func |
3550 "%K%qD reading %E byte from a region of size %E", | 3660 ? warning_n (loc, opt, tree_to_uhwi (range[0]), |
3551 "%K%qD reading %E bytes from a region of size %E", | 3661 "%K%qD reading %E byte from a region of size %E", |
3552 exp, func, range[0], slen); | 3662 "%K%qD reading %E bytes from a region of size %E", |
3663 exp, func, range[0], slen) | |
3664 : warning_n (loc, opt, tree_to_uhwi (range[0]), | |
3665 "%Kreading %E byte from a region of size %E", | |
3666 "%Kreading %E bytes from a region of size %E", | |
3667 exp, range[0], slen)); | |
3553 else if (tree_int_cst_sign_bit (range[1])) | 3668 else if (tree_int_cst_sign_bit (range[1])) |
3554 { | 3669 { |
3555 /* Avoid printing the upper bound if it's invalid. */ | 3670 /* Avoid printing the upper bound if it's invalid. */ |
3556 warning_at (loc, opt, | 3671 warned = (func |
3557 "%K%qD reading %E or more bytes from a region " | 3672 ? warning_at (loc, opt, |
3558 "of size %E", | 3673 "%K%qD reading %E or more bytes from a region " |
3559 exp, func, range[0], slen); | 3674 "of size %E", |
3675 exp, func, range[0], slen) | |
3676 : warning_at (loc, opt, | |
3677 "%Kreading %E or more bytes from a region " | |
3678 "of size %E", | |
3679 exp, range[0], slen)); | |
3560 } | 3680 } |
3561 else | 3681 else |
3562 warning_at (loc, opt, | 3682 warned = (func |
3563 "%K%qD reading between %E and %E bytes from a region " | 3683 ? warning_at (loc, opt, |
3564 "of size %E", | 3684 "%K%qD reading between %E and %E bytes from " |
3565 exp, func, range[0], range[1], slen); | 3685 "a region of size %E", |
3686 exp, func, range[0], range[1], slen) | |
3687 : warning_at (loc, opt, | |
3688 "%Kreading between %E and %E bytes from " | |
3689 "a region of size %E", | |
3690 exp, range[0], range[1], slen)); | |
3691 if (warned) | |
3692 TREE_NO_WARNING (exp) = true; | |
3693 | |
3566 return false; | 3694 return false; |
3567 } | 3695 } |
3568 | 3696 |
3569 return true; | 3697 return true; |
3698 } | |
3699 | |
3700 /* If STMT is a call to an allocation function, returns the constant | |
3701 size of the object allocated by the call represented as sizetype. | |
3702 If nonnull, sets RNG1[] to the range of the size. */ | |
3703 | |
3704 tree | |
3705 gimple_call_alloc_size (gimple *stmt, wide_int rng1[2] /* = NULL */, | |
3706 const vr_values *rvals /* = NULL */) | |
3707 { | |
3708 if (!stmt) | |
3709 return NULL_TREE; | |
3710 | |
3711 tree allocfntype; | |
3712 if (tree fndecl = gimple_call_fndecl (stmt)) | |
3713 allocfntype = TREE_TYPE (fndecl); | |
3714 else | |
3715 allocfntype = gimple_call_fntype (stmt); | |
3716 | |
3717 if (!allocfntype) | |
3718 return NULL_TREE; | |
3719 | |
3720 unsigned argidx1 = UINT_MAX, argidx2 = UINT_MAX; | |
3721 tree at = lookup_attribute ("alloc_size", TYPE_ATTRIBUTES (allocfntype)); | |
3722 if (!at) | |
3723 { | |
3724 if (!gimple_call_builtin_p (stmt, BUILT_IN_ALLOCA_WITH_ALIGN)) | |
3725 return NULL_TREE; | |
3726 | |
3727 argidx1 = 0; | |
3728 } | |
3729 | |
3730 unsigned nargs = gimple_call_num_args (stmt); | |
3731 | |
3732 if (argidx1 == UINT_MAX) | |
3733 { | |
3734 tree atval = TREE_VALUE (at); | |
3735 if (!atval) | |
3736 return NULL_TREE; | |
3737 | |
3738 argidx1 = TREE_INT_CST_LOW (TREE_VALUE (atval)) - 1; | |
3739 if (nargs <= argidx1) | |
3740 return NULL_TREE; | |
3741 | |
3742 atval = TREE_CHAIN (atval); | |
3743 if (atval) | |
3744 { | |
3745 argidx2 = TREE_INT_CST_LOW (TREE_VALUE (atval)) - 1; | |
3746 if (nargs <= argidx2) | |
3747 return NULL_TREE; | |
3748 } | |
3749 } | |
3750 | |
3751 tree size = gimple_call_arg (stmt, argidx1); | |
3752 | |
3753 wide_int rng1_buf[2]; | |
3754 /* If RNG1 is not set, use the buffer. */ | |
3755 if (!rng1) | |
3756 rng1 = rng1_buf; | |
3757 | |
3758 if (!get_range (size, rng1, rvals)) | |
3759 return NULL_TREE; | |
3760 | |
3761 if (argidx2 > nargs && TREE_CODE (size) == INTEGER_CST) | |
3762 return fold_convert (sizetype, size); | |
3763 | |
3764 /* To handle ranges do the math in wide_int and return the product | |
3765 of the upper bounds as a constant. Ignore anti-ranges. */ | |
3766 tree n = argidx2 < nargs ? gimple_call_arg (stmt, argidx2) : integer_one_node; | |
3767 wide_int rng2[2]; | |
3768 if (!get_range (n, rng2, rvals)) | |
3769 return NULL_TREE; | |
3770 | |
3771 /* Extend to the maximum precision to avoid overflow. */ | |
3772 const int prec = ADDR_MAX_PRECISION; | |
3773 rng1[0] = wide_int::from (rng1[0], prec, UNSIGNED); | |
3774 rng1[1] = wide_int::from (rng1[1], prec, UNSIGNED); | |
3775 rng2[0] = wide_int::from (rng2[0], prec, UNSIGNED); | |
3776 rng2[1] = wide_int::from (rng2[1], prec, UNSIGNED); | |
3777 | |
3778 /* Compute products of both bounds for the caller but return the lesser | |
3779 of SIZE_MAX and the product of the upper bounds as a constant. */ | |
3780 rng1[0] = rng1[0] * rng2[0]; | |
3781 rng1[1] = rng1[1] * rng2[1]; | |
3782 tree size_max = TYPE_MAX_VALUE (sizetype); | |
3783 if (wi::gtu_p (rng1[1], wi::to_wide (size_max, prec))) | |
3784 { | |
3785 rng1[1] = wi::to_wide (size_max); | |
3786 return size_max; | |
3787 } | |
3788 | |
3789 return wide_int_to_tree (sizetype, rng1[1]); | |
3790 } | |
3791 | |
3792 /* Helper for compute_objsize. Returns the constant size of the DEST | |
3793 if it refers to a variable or field and sets *PDECL to the DECL and | |
3794 *POFF to zero. Otherwise returns null for other nodes. */ | |
3795 | |
3796 static tree | |
3797 addr_decl_size (tree dest, tree *pdecl, tree *poff) | |
3798 { | |
3799 if (TREE_CODE (dest) == ADDR_EXPR) | |
3800 dest = TREE_OPERAND (dest, 0); | |
3801 | |
3802 if (DECL_P (dest)) | |
3803 { | |
3804 *pdecl = dest; | |
3805 *poff = integer_zero_node; | |
3806 if (tree size = DECL_SIZE_UNIT (dest)) | |
3807 return TREE_CODE (size) == INTEGER_CST ? size : NULL_TREE; | |
3808 } | |
3809 | |
3810 if (TREE_CODE (dest) == COMPONENT_REF) | |
3811 { | |
3812 *pdecl = TREE_OPERAND (dest, 1); | |
3813 *poff = integer_zero_node; | |
3814 /* Only return constant sizes for now while callers depend on it. */ | |
3815 if (tree size = component_ref_size (dest)) | |
3816 return TREE_CODE (size) == INTEGER_CST ? size : NULL_TREE; | |
3817 } | |
3818 | |
3819 return NULL_TREE; | |
3570 } | 3820 } |
3571 | 3821 |
3572 /* Helper to compute the size of the object referenced by the DEST | 3822 /* Helper to compute the size of the object referenced by the DEST |
3573 expression which must have pointer type, using Object Size type | 3823 expression which must have pointer type, using Object Size type |
3574 OSTYPE (only the least significant 2 bits are used). Return | 3824 OSTYPE (only the least significant 2 bits are used). |
3575 an estimate of the size of the object if successful or NULL when | 3825 Returns an estimate of the size of the object represented as |
3576 the size cannot be determined. When the referenced object involves | 3826 a sizetype constant if successful or NULL when the size cannot |
3577 a non-constant offset in some range the returned value represents | 3827 be determined. |
3578 the largest size given the smallest non-negative offset in the | 3828 When the referenced object involves a non-constant offset in some |
3579 range. The function is intended for diagnostics and should not | 3829 range the returned value represents the largest size given the |
3580 be used to influence code generation or optimization. */ | 3830 smallest non-negative offset in the range. |
3831 If nonnull, sets *PDECL to the decl of the referenced subobject | |
3832 if it can be determined, or to null otherwise. Likewise, when | |
3833 POFF is nonnull *POFF is set to the offset into *PDECL. | |
3834 | |
3835 The function is intended for diagnostics and should not be used | |
3836 to influence code generation or optimization. */ | |
3581 | 3837 |
3582 tree | 3838 tree |
3583 compute_objsize (tree dest, int ostype) | 3839 compute_objsize (tree dest, int ostype, tree *pdecl /* = NULL */, |
3584 { | 3840 tree *poff /* = NULL */, const vr_values *rvals /* = NULL */) |
3585 unsigned HOST_WIDE_INT size; | 3841 { |
3842 tree dummy_decl = NULL_TREE; | |
3843 if (!pdecl) | |
3844 pdecl = &dummy_decl; | |
3845 | |
3846 tree dummy_off = NULL_TREE; | |
3847 if (!poff) | |
3848 poff = &dummy_off; | |
3586 | 3849 |
3587 /* Only the two least significant bits are meaningful. */ | 3850 /* Only the two least significant bits are meaningful. */ |
3588 ostype &= 3; | 3851 ostype &= 3; |
3589 | 3852 |
3590 if (compute_builtin_object_size (dest, ostype, &size)) | 3853 if (ostype) |
3854 /* Except for overly permissive calls to memcpy and other raw | |
3855 memory functions with zero OSTYPE, detect the size from simple | |
3856 DECLs first to more reliably than compute_builtin_object_size | |
3857 set *PDECL and *POFF. */ | |
3858 if (tree size = addr_decl_size (dest, pdecl, poff)) | |
3859 return size; | |
3860 | |
3861 unsigned HOST_WIDE_INT size; | |
3862 if (compute_builtin_object_size (dest, ostype, &size, pdecl, poff)) | |
3591 return build_int_cst (sizetype, size); | 3863 return build_int_cst (sizetype, size); |
3592 | 3864 |
3593 if (TREE_CODE (dest) == SSA_NAME) | 3865 if (TREE_CODE (dest) == SSA_NAME) |
3594 { | 3866 { |
3595 gimple *stmt = SSA_NAME_DEF_STMT (dest); | 3867 gimple *stmt = SSA_NAME_DEF_STMT (dest); |
3868 if (is_gimple_call (stmt)) | |
3869 { | |
3870 /* If STMT is a call to an allocation function get the size | |
3871 from its argument(s). If successful, also set *PDECL to | |
3872 DEST for the caller to include in diagnostics. */ | |
3873 if (tree size = gimple_call_alloc_size (stmt)) | |
3874 { | |
3875 *pdecl = dest; | |
3876 *poff = integer_zero_node; | |
3877 return size; | |
3878 } | |
3879 return NULL_TREE; | |
3880 } | |
3881 | |
3596 if (!is_gimple_assign (stmt)) | 3882 if (!is_gimple_assign (stmt)) |
3597 return NULL_TREE; | 3883 return NULL_TREE; |
3598 | 3884 |
3599 dest = gimple_assign_rhs1 (stmt); | 3885 dest = gimple_assign_rhs1 (stmt); |
3600 | 3886 |
3606 such an offset here and use it to adjust the constant | 3892 such an offset here and use it to adjust the constant |
3607 size. */ | 3893 size. */ |
3608 tree off = gimple_assign_rhs2 (stmt); | 3894 tree off = gimple_assign_rhs2 (stmt); |
3609 if (TREE_CODE (off) == INTEGER_CST) | 3895 if (TREE_CODE (off) == INTEGER_CST) |
3610 { | 3896 { |
3611 if (tree size = compute_objsize (dest, ostype)) | 3897 if (tree size = compute_objsize (dest, ostype, pdecl, poff)) |
3612 { | 3898 { |
3613 wide_int wioff = wi::to_wide (off); | 3899 wide_int wioff = wi::to_wide (off); |
3614 wide_int wisiz = wi::to_wide (size); | 3900 wide_int wisiz = wi::to_wide (size); |
3615 | 3901 |
3616 /* Ignore negative offsets for now. For others, | 3902 /* Ignore negative offsets for now. For others, |
3617 use the lower bound as the most optimistic | 3903 use the lower bound as the most optimistic |
3618 estimate of the (remaining) size. */ | 3904 estimate of the (remaining) size. */ |
3619 if (wi::sign_mask (wioff)) | 3905 if (wi::neg_p (wioff)) |
3620 ; | 3906 ; |
3621 else if (wi::ltu_p (wioff, wisiz)) | |
3622 return wide_int_to_tree (TREE_TYPE (size), | |
3623 wi::sub (wisiz, wioff)); | |
3624 else | 3907 else |
3625 return size_zero_node; | 3908 { |
3909 if (*poff) | |
3910 { | |
3911 *poff = fold_convert (ptrdiff_type_node, *poff); | |
3912 off = fold_convert (ptrdiff_type_node, *poff); | |
3913 *poff = size_binop (PLUS_EXPR, *poff, off); | |
3914 } | |
3915 else | |
3916 *poff = off; | |
3917 if (wi::ltu_p (wioff, wisiz)) | |
3918 return wide_int_to_tree (TREE_TYPE (size), | |
3919 wi::sub (wisiz, wioff)); | |
3920 return size_zero_node; | |
3921 } | |
3626 } | 3922 } |
3627 } | 3923 } |
3628 else if (TREE_CODE (off) == SSA_NAME | 3924 else if (TREE_CODE (off) == SSA_NAME |
3629 && INTEGRAL_TYPE_P (TREE_TYPE (off))) | 3925 && INTEGRAL_TYPE_P (TREE_TYPE (off))) |
3630 { | 3926 { |
3631 wide_int min, max; | 3927 wide_int min, max; |
3632 enum value_range_kind rng = get_range_info (off, &min, &max); | 3928 enum value_range_kind rng = get_range_info (off, &min, &max); |
3633 | 3929 |
3634 if (rng == VR_RANGE) | 3930 if (rng == VR_RANGE) |
3635 { | 3931 if (tree size = compute_objsize (dest, ostype, pdecl, poff)) |
3636 if (tree size = compute_objsize (dest, ostype)) | 3932 { |
3637 { | 3933 wide_int wisiz = wi::to_wide (size); |
3638 wide_int wisiz = wi::to_wide (size); | 3934 |
3639 | 3935 /* Ignore negative offsets for now. For others, |
3640 /* Ignore negative offsets for now. For others, | 3936 use the lower bound as the most optimistic |
3641 use the lower bound as the most optimistic | 3937 estimate of the (remaining)size. */ |
3642 estimate of the (remaining)size. */ | 3938 if (wi::neg_p (min) || wi::neg_p (max)) |
3643 if (wi::sign_mask (min)) | 3939 ; |
3644 ; | 3940 else |
3645 else if (wi::ltu_p (min, wisiz)) | 3941 { |
3646 return wide_int_to_tree (TREE_TYPE (size), | 3942 /* FIXME: For now, since the offset is non-constant, |
3647 wi::sub (wisiz, min)); | 3943 clear *POFF to keep it from being "misused." |
3648 else | 3944 Eventually *POFF will need to become a range that |
3945 can be properly added to the outer offset if it | |
3946 too is one. */ | |
3947 *poff = NULL_TREE; | |
3948 if (wi::ltu_p (min, wisiz)) | |
3949 return wide_int_to_tree (TREE_TYPE (size), | |
3950 wi::sub (wisiz, min)); | |
3649 return size_zero_node; | 3951 return size_zero_node; |
3650 } | 3952 } |
3651 } | 3953 } |
3652 } | 3954 } |
3653 } | 3955 } |
3654 else if (code != ADDR_EXPR) | 3956 else if (code != ADDR_EXPR) |
3655 return NULL_TREE; | 3957 return NULL_TREE; |
3656 } | 3958 } |
3658 /* Unless computing the largest size (for memcpy and other raw memory | 3960 /* Unless computing the largest size (for memcpy and other raw memory |
3659 functions), try to determine the size of the object from its type. */ | 3961 functions), try to determine the size of the object from its type. */ |
3660 if (!ostype) | 3962 if (!ostype) |
3661 return NULL_TREE; | 3963 return NULL_TREE; |
3662 | 3964 |
3663 if (TREE_CODE (dest) != ADDR_EXPR) | 3965 if (TREE_CODE (dest) == ARRAY_REF |
3664 return NULL_TREE; | 3966 || TREE_CODE (dest) == MEM_REF) |
3967 { | |
3968 tree ref = TREE_OPERAND (dest, 0); | |
3969 tree reftype = TREE_TYPE (ref); | |
3970 if (TREE_CODE (dest) == MEM_REF && TREE_CODE (reftype) == POINTER_TYPE) | |
3971 { | |
3972 /* Give up for MEM_REFs of vector types; those may be synthesized | |
3973 from multiple assignments to consecutive data members. See PR | |
3974 93200. | |
3975 FIXME: Deal with this more generally, e.g., by marking up such | |
3976 MEM_REFs at the time they're created. */ | |
3977 reftype = TREE_TYPE (reftype); | |
3978 if (TREE_CODE (reftype) == VECTOR_TYPE) | |
3979 return NULL_TREE; | |
3980 } | |
3981 tree off = TREE_OPERAND (dest, 1); | |
3982 if (tree size = compute_objsize (ref, ostype, pdecl, poff)) | |
3983 { | |
3984 /* If the declaration of the destination object is known | |
3985 to have zero size, return zero. */ | |
3986 if (integer_zerop (size) | |
3987 && *pdecl && DECL_P (*pdecl) | |
3988 && *poff && integer_zerop (*poff)) | |
3989 return size_zero_node; | |
3990 | |
3991 /* A valid offset into a declared object cannot be negative. | |
3992 A zero size with a zero "inner" offset is still zero size | |
3993 regardless of the "other" offset OFF. */ | |
3994 if (*poff | |
3995 && ((integer_zerop (*poff) && integer_zerop (size)) | |
3996 || (TREE_CODE (*poff) == INTEGER_CST | |
3997 && tree_int_cst_sgn (*poff) < 0))) | |
3998 return size_zero_node; | |
3999 | |
4000 wide_int offrng[2]; | |
4001 if (!get_range (off, offrng, rvals)) | |
4002 return NULL_TREE; | |
4003 | |
4004 /* Convert to the same precision to keep wide_int from "helpfully" | |
4005 crashing whenever it sees other arguments. */ | |
4006 const unsigned sizprec = TYPE_PRECISION (sizetype); | |
4007 offrng[0] = wide_int::from (offrng[0], sizprec, SIGNED); | |
4008 offrng[1] = wide_int::from (offrng[1], sizprec, SIGNED); | |
4009 | |
4010 /* Adjust SIZE either up or down by the sum of *POFF and OFF | |
4011 above. */ | |
4012 if (TREE_CODE (dest) == ARRAY_REF) | |
4013 { | |
4014 tree lowbnd = array_ref_low_bound (dest); | |
4015 if (!integer_zerop (lowbnd) && tree_fits_uhwi_p (lowbnd)) | |
4016 { | |
4017 /* Adjust the offset by the low bound of the array | |
4018 domain (normally zero but 1 in Fortran). */ | |
4019 unsigned HOST_WIDE_INT lb = tree_to_uhwi (lowbnd); | |
4020 offrng[0] -= lb; | |
4021 offrng[1] -= lb; | |
4022 } | |
4023 | |
4024 /* Convert the array index into a byte offset. */ | |
4025 tree eltype = TREE_TYPE (dest); | |
4026 tree tpsize = TYPE_SIZE_UNIT (eltype); | |
4027 if (tpsize && TREE_CODE (tpsize) == INTEGER_CST) | |
4028 { | |
4029 wide_int wsz = wi::to_wide (tpsize, offrng->get_precision ()); | |
4030 offrng[0] *= wsz; | |
4031 offrng[1] *= wsz; | |
4032 } | |
4033 else | |
4034 return NULL_TREE; | |
4035 } | |
4036 | |
4037 wide_int wisize = wi::to_wide (size); | |
4038 | |
4039 if (!*poff) | |
4040 { | |
4041 /* If the "inner" offset is unknown and the "outer" offset | |
4042 is either negative or less than SIZE, return the size | |
4043 minus the offset. This may be overly optimistic in | |
4044 the first case if the inner offset happens to be less | |
4045 than the absolute value of the outer offset. */ | |
4046 if (wi::neg_p (offrng[0])) | |
4047 return size; | |
4048 if (wi::ltu_p (offrng[0], wisize)) | |
4049 return build_int_cst (sizetype, (wisize - offrng[0]).to_uhwi ()); | |
4050 return size_zero_node; | |
4051 } | |
4052 | |
4053 /* Convert to the same precision to keep wide_int from "helpfuly" | |
4054 crashing whenever it sees other argumments. */ | |
4055 offrng[0] = wide_int::from (offrng[0], sizprec, SIGNED); | |
4056 offrng[1] = wide_int::from (offrng[1], sizprec, SIGNED); | |
4057 | |
4058 tree dstoff = *poff; | |
4059 if (integer_zerop (*poff)) | |
4060 *poff = off; | |
4061 else if (!integer_zerop (off)) | |
4062 { | |
4063 *poff = fold_convert (ptrdiff_type_node, *poff); | |
4064 off = fold_convert (ptrdiff_type_node, off); | |
4065 *poff = size_binop (PLUS_EXPR, *poff, off); | |
4066 } | |
4067 | |
4068 if (!wi::neg_p (offrng[0])) | |
4069 { | |
4070 if (TREE_CODE (size) != INTEGER_CST) | |
4071 return NULL_TREE; | |
4072 | |
4073 /* Return the difference between the size and the offset | |
4074 or zero if the offset is greater. */ | |
4075 wide_int wisize = wi::to_wide (size, sizprec); | |
4076 if (wi::ltu_p (wisize, offrng[0])) | |
4077 return size_zero_node; | |
4078 | |
4079 return wide_int_to_tree (sizetype, wisize - offrng[0]); | |
4080 } | |
4081 | |
4082 wide_int dstoffrng[2]; | |
4083 if (TREE_CODE (dstoff) == INTEGER_CST) | |
4084 dstoffrng[0] = dstoffrng[1] = wi::to_wide (dstoff); | |
4085 else if (TREE_CODE (dstoff) == SSA_NAME) | |
4086 { | |
4087 enum value_range_kind rng | |
4088 = get_range_info (dstoff, dstoffrng, dstoffrng + 1); | |
4089 if (rng != VR_RANGE) | |
4090 return NULL_TREE; | |
4091 } | |
4092 else | |
4093 return NULL_TREE; | |
4094 | |
4095 dstoffrng[0] = wide_int::from (dstoffrng[0], sizprec, SIGNED); | |
4096 dstoffrng[1] = wide_int::from (dstoffrng[1], sizprec, SIGNED); | |
4097 | |
4098 if (!wi::neg_p (dstoffrng[0])) | |
4099 wisize += dstoffrng[0]; | |
4100 | |
4101 offrng[1] += dstoffrng[1]; | |
4102 if (wi::neg_p (offrng[1])) | |
4103 return size_zero_node; | |
4104 | |
4105 return wide_int_to_tree (sizetype, wisize); | |
4106 } | |
4107 | |
4108 return NULL_TREE; | |
4109 } | |
4110 | |
4111 /* Try simple DECLs not handled above. */ | |
4112 if (tree size = addr_decl_size (dest, pdecl, poff)) | |
4113 return size; | |
3665 | 4114 |
3666 tree type = TREE_TYPE (dest); | 4115 tree type = TREE_TYPE (dest); |
3667 if (TREE_CODE (type) == POINTER_TYPE) | 4116 if (TREE_CODE (type) == POINTER_TYPE) |
3668 type = TREE_TYPE (type); | 4117 type = TREE_TYPE (type); |
3669 | 4118 |
3670 type = TYPE_MAIN_VARIANT (type); | 4119 type = TYPE_MAIN_VARIANT (type); |
4120 if (TREE_CODE (dest) == ADDR_EXPR) | |
4121 dest = TREE_OPERAND (dest, 0); | |
3671 | 4122 |
3672 if (TREE_CODE (type) == ARRAY_TYPE | 4123 if (TREE_CODE (type) == ARRAY_TYPE |
3673 && !array_at_struct_end_p (TREE_OPERAND (dest, 0))) | 4124 && !array_at_struct_end_p (dest)) |
3674 { | 4125 { |
3675 /* Return the constant size unless it's zero (that's a zero-length | 4126 if (tree size = TYPE_SIZE_UNIT (type)) |
3676 array likely at the end of a struct). */ | 4127 return TREE_CODE (size) == INTEGER_CST ? size : NULL_TREE; |
3677 tree size = TYPE_SIZE_UNIT (type); | |
3678 if (size && TREE_CODE (size) == INTEGER_CST | |
3679 && !integer_zerop (size)) | |
3680 return size; | |
3681 } | 4128 } |
3682 | 4129 |
3683 return NULL_TREE; | 4130 return NULL_TREE; |
3684 } | 4131 } |
3685 | 4132 |
3746 tree len = CALL_EXPR_ARG (exp, 2); | 4193 tree len = CALL_EXPR_ARG (exp, 2); |
3747 | 4194 |
3748 check_memop_access (exp, dest, src, len); | 4195 check_memop_access (exp, dest, src, len); |
3749 | 4196 |
3750 return expand_builtin_memory_copy_args (dest, src, len, target, exp, | 4197 return expand_builtin_memory_copy_args (dest, src, len, target, exp, |
3751 /*endp=*/ 0); | 4198 /*retmode=*/ RETURN_BEGIN, false); |
3752 } | 4199 } |
3753 | 4200 |
3754 /* Check a call EXP to the memmove built-in for validity. | 4201 /* Check a call EXP to the memmove built-in for validity. |
3755 Return NULL_RTX on both success and failure. */ | 4202 Return NULL_RTX on both success and failure. */ |
3756 | 4203 |
3757 static rtx | 4204 static rtx |
3758 expand_builtin_memmove (tree exp, rtx) | 4205 expand_builtin_memmove (tree exp, rtx target) |
3759 { | 4206 { |
3760 if (!validate_arglist (exp, | 4207 if (!validate_arglist (exp, |
3761 POINTER_TYPE, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE)) | 4208 POINTER_TYPE, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE)) |
3762 return NULL_RTX; | 4209 return NULL_RTX; |
3763 | 4210 |
3765 tree src = CALL_EXPR_ARG (exp, 1); | 4212 tree src = CALL_EXPR_ARG (exp, 1); |
3766 tree len = CALL_EXPR_ARG (exp, 2); | 4213 tree len = CALL_EXPR_ARG (exp, 2); |
3767 | 4214 |
3768 check_memop_access (exp, dest, src, len); | 4215 check_memop_access (exp, dest, src, len); |
3769 | 4216 |
3770 return NULL_RTX; | 4217 return expand_builtin_memory_copy_args (dest, src, len, target, exp, |
4218 /*retmode=*/ RETURN_BEGIN, true); | |
3771 } | 4219 } |
3772 | 4220 |
3773 /* Expand a call EXP to the mempcpy builtin. | 4221 /* Expand a call EXP to the mempcpy builtin. |
3774 Return NULL_RTX if we failed; the caller should emit a normal call, | 4222 Return NULL_RTX if we failed; the caller should emit a normal call, |
3775 otherwise try to get the result in TARGET, if convenient (and in | 4223 otherwise try to get the result in TARGET, if convenient (and in |
3776 mode MODE if that's convenient). If ENDP is 0 return the | 4224 mode MODE if that's convenient). */ |
3777 destination pointer, if ENDP is 1 return the end pointer ala | |
3778 mempcpy, and if ENDP is 2 return the end pointer minus one ala | |
3779 stpcpy. */ | |
3780 | 4225 |
3781 static rtx | 4226 static rtx |
3782 expand_builtin_mempcpy (tree exp, rtx target) | 4227 expand_builtin_mempcpy (tree exp, rtx target) |
3783 { | 4228 { |
3784 if (!validate_arglist (exp, | 4229 if (!validate_arglist (exp, |
3807 from being diagnosed again when expanding memcpy. */ | 4252 from being diagnosed again when expanding memcpy. */ |
3808 if (!check_memop_access (exp, dest, src, len)) | 4253 if (!check_memop_access (exp, dest, src, len)) |
3809 return NULL_RTX; | 4254 return NULL_RTX; |
3810 | 4255 |
3811 return expand_builtin_mempcpy_args (dest, src, len, | 4256 return expand_builtin_mempcpy_args (dest, src, len, |
3812 target, exp, /*endp=*/ 1); | 4257 target, exp, /*retmode=*/ RETURN_END); |
3813 } | 4258 } |
3814 | 4259 |
3815 /* Helper function to do the actual work for expand of memory copy family | 4260 /* Helper function to do the actual work for expand of memory copy family |
3816 functions (memcpy, mempcpy, stpcpy). Expansing should assign LEN bytes | 4261 functions (memcpy, mempcpy, stpcpy). Expansing should assign LEN bytes |
3817 of memory from SRC to DEST and assign to TARGET if convenient. | 4262 of memory from SRC to DEST and assign to TARGET if convenient. Return |
3818 If ENDP is 0 return the | 4263 value is based on RETMODE argument. */ |
3819 destination pointer, if ENDP is 1 return the end pointer ala | |
3820 mempcpy, and if ENDP is 2 return the end pointer minus one ala | |
3821 stpcpy. */ | |
3822 | 4264 |
3823 static rtx | 4265 static rtx |
3824 expand_builtin_memory_copy_args (tree dest, tree src, tree len, | 4266 expand_builtin_memory_copy_args (tree dest, tree src, tree len, |
3825 rtx target, tree exp, int endp) | 4267 rtx target, tree exp, memop_ret retmode, |
4268 bool might_overlap) | |
3826 { | 4269 { |
3827 const char *src_str; | 4270 const char *src_str; |
3828 unsigned int src_align = get_pointer_alignment (src); | 4271 unsigned int src_align = get_pointer_alignment (src); |
3829 unsigned int dest_align = get_pointer_alignment (dest); | 4272 unsigned int dest_align = get_pointer_alignment (dest); |
3830 rtx dest_mem, src_mem, dest_addr, len_rtx; | 4273 rtx dest_mem, src_mem, dest_addr, len_rtx; |
3832 unsigned int expected_align = 0; | 4275 unsigned int expected_align = 0; |
3833 unsigned HOST_WIDE_INT min_size; | 4276 unsigned HOST_WIDE_INT min_size; |
3834 unsigned HOST_WIDE_INT max_size; | 4277 unsigned HOST_WIDE_INT max_size; |
3835 unsigned HOST_WIDE_INT probable_max_size; | 4278 unsigned HOST_WIDE_INT probable_max_size; |
3836 | 4279 |
4280 bool is_move_done; | |
4281 | |
3837 /* If DEST is not a pointer type, call the normal function. */ | 4282 /* If DEST is not a pointer type, call the normal function. */ |
3838 if (dest_align == 0) | 4283 if (dest_align == 0) |
3839 return NULL_RTX; | 4284 return NULL_RTX; |
3840 | 4285 |
3841 /* If either SRC is not a pointer type, don't do this | 4286 /* If either SRC is not a pointer type, don't do this |
3854 len_rtx = expand_normal (len); | 4299 len_rtx = expand_normal (len); |
3855 determine_block_size (len, len_rtx, &min_size, &max_size, | 4300 determine_block_size (len, len_rtx, &min_size, &max_size, |
3856 &probable_max_size); | 4301 &probable_max_size); |
3857 src_str = c_getstr (src); | 4302 src_str = c_getstr (src); |
3858 | 4303 |
3859 /* If SRC is a string constant and block move would be done | 4304 /* If SRC is a string constant and block move would be done by |
3860 by pieces, we can avoid loading the string from memory | 4305 pieces, we can avoid loading the string from memory and only |
3861 and only stored the computed constants. */ | 4306 stored the computed constants. This works in the overlap |
4307 (memmove) case as well because store_by_pieces just generates a | |
4308 series of stores of constants from the string constant returned | |
4309 by c_getstr(). */ | |
3862 if (src_str | 4310 if (src_str |
3863 && CONST_INT_P (len_rtx) | 4311 && CONST_INT_P (len_rtx) |
3864 && (unsigned HOST_WIDE_INT) INTVAL (len_rtx) <= strlen (src_str) + 1 | 4312 && (unsigned HOST_WIDE_INT) INTVAL (len_rtx) <= strlen (src_str) + 1 |
3865 && can_store_by_pieces (INTVAL (len_rtx), builtin_memcpy_read_str, | 4313 && can_store_by_pieces (INTVAL (len_rtx), builtin_memcpy_read_str, |
3866 CONST_CAST (char *, src_str), | 4314 CONST_CAST (char *, src_str), |
3867 dest_align, false)) | 4315 dest_align, false)) |
3868 { | 4316 { |
3869 dest_mem = store_by_pieces (dest_mem, INTVAL (len_rtx), | 4317 dest_mem = store_by_pieces (dest_mem, INTVAL (len_rtx), |
3870 builtin_memcpy_read_str, | 4318 builtin_memcpy_read_str, |
3871 CONST_CAST (char *, src_str), | 4319 CONST_CAST (char *, src_str), |
3872 dest_align, false, endp); | 4320 dest_align, false, retmode); |
3873 dest_mem = force_operand (XEXP (dest_mem, 0), target); | 4321 dest_mem = force_operand (XEXP (dest_mem, 0), target); |
3874 dest_mem = convert_memory_address (ptr_mode, dest_mem); | 4322 dest_mem = convert_memory_address (ptr_mode, dest_mem); |
3875 return dest_mem; | 4323 return dest_mem; |
3876 } | 4324 } |
3877 | 4325 |
3878 src_mem = get_memory_rtx (src, len); | 4326 src_mem = get_memory_rtx (src, len); |
3879 set_mem_align (src_mem, src_align); | 4327 set_mem_align (src_mem, src_align); |
3880 | 4328 |
3881 /* Copy word part most expediently. */ | 4329 /* Copy word part most expediently. */ |
3882 enum block_op_methods method = BLOCK_OP_NORMAL; | 4330 enum block_op_methods method = BLOCK_OP_NORMAL; |
3883 if (CALL_EXPR_TAILCALL (exp) && (endp == 0 || target == const0_rtx)) | 4331 if (CALL_EXPR_TAILCALL (exp) |
4332 && (retmode == RETURN_BEGIN || target == const0_rtx)) | |
3884 method = BLOCK_OP_TAILCALL; | 4333 method = BLOCK_OP_TAILCALL; |
3885 if (endp == 1 && target != const0_rtx) | 4334 bool use_mempcpy_call = (targetm.libc_has_fast_function (BUILT_IN_MEMPCPY) |
4335 && retmode == RETURN_END | |
4336 && !might_overlap | |
4337 && target != const0_rtx); | |
4338 if (use_mempcpy_call) | |
3886 method = BLOCK_OP_NO_LIBCALL_RET; | 4339 method = BLOCK_OP_NO_LIBCALL_RET; |
3887 dest_addr = emit_block_move_hints (dest_mem, src_mem, len_rtx, method, | 4340 dest_addr = emit_block_move_hints (dest_mem, src_mem, len_rtx, method, |
3888 expected_align, expected_size, | 4341 expected_align, expected_size, |
3889 min_size, max_size, probable_max_size); | 4342 min_size, max_size, probable_max_size, |
4343 use_mempcpy_call, &is_move_done, might_overlap); | |
4344 | |
4345 /* Bail out when a mempcpy call would be expanded as libcall and when | |
4346 we have a target that provides a fast implementation | |
4347 of mempcpy routine. */ | |
4348 if (!is_move_done) | |
4349 return NULL_RTX; | |
4350 | |
3890 if (dest_addr == pc_rtx) | 4351 if (dest_addr == pc_rtx) |
3891 return NULL_RTX; | 4352 return NULL_RTX; |
3892 | 4353 |
3893 if (dest_addr == 0) | 4354 if (dest_addr == 0) |
3894 { | 4355 { |
3895 dest_addr = force_operand (XEXP (dest_mem, 0), target); | 4356 dest_addr = force_operand (XEXP (dest_mem, 0), target); |
3896 dest_addr = convert_memory_address (ptr_mode, dest_addr); | 4357 dest_addr = convert_memory_address (ptr_mode, dest_addr); |
3897 } | 4358 } |
3898 | 4359 |
3899 if (endp && target != const0_rtx) | 4360 if (retmode != RETURN_BEGIN && target != const0_rtx) |
3900 { | 4361 { |
3901 dest_addr = gen_rtx_PLUS (ptr_mode, dest_addr, len_rtx); | 4362 dest_addr = gen_rtx_PLUS (ptr_mode, dest_addr, len_rtx); |
3902 /* stpcpy pointer to last byte. */ | 4363 /* stpcpy pointer to last byte. */ |
3903 if (endp == 2) | 4364 if (retmode == RETURN_END_MINUS_ONE) |
3904 dest_addr = gen_rtx_MINUS (ptr_mode, dest_addr, const1_rtx); | 4365 dest_addr = gen_rtx_MINUS (ptr_mode, dest_addr, const1_rtx); |
3905 } | 4366 } |
3906 | 4367 |
3907 return dest_addr; | 4368 return dest_addr; |
3908 } | 4369 } |
3909 | 4370 |
3910 static rtx | 4371 static rtx |
3911 expand_builtin_mempcpy_args (tree dest, tree src, tree len, | 4372 expand_builtin_mempcpy_args (tree dest, tree src, tree len, |
3912 rtx target, tree orig_exp, int endp) | 4373 rtx target, tree orig_exp, memop_ret retmode) |
3913 { | 4374 { |
3914 return expand_builtin_memory_copy_args (dest, src, len, target, orig_exp, | 4375 return expand_builtin_memory_copy_args (dest, src, len, target, orig_exp, |
3915 endp); | 4376 retmode, false); |
3916 } | 4377 } |
3917 | 4378 |
3918 /* Expand into a movstr instruction, if one is available. Return NULL_RTX if | 4379 /* Expand into a movstr instruction, if one is available. Return NULL_RTX if |
3919 we failed, the caller should emit a normal call, otherwise try to | 4380 we failed, the caller should emit a normal call, otherwise try to |
3920 get the result in TARGET, if convenient. If ENDP is 0 return the | 4381 get the result in TARGET, if convenient. |
3921 destination pointer, if ENDP is 1 return the end pointer ala | 4382 Return value is based on RETMODE argument. */ |
3922 mempcpy, and if ENDP is 2 return the end pointer minus one ala | |
3923 stpcpy. */ | |
3924 | 4383 |
3925 static rtx | 4384 static rtx |
3926 expand_movstr (tree dest, tree src, rtx target, int endp) | 4385 expand_movstr (tree dest, tree src, rtx target, memop_ret retmode) |
3927 { | 4386 { |
3928 struct expand_operand ops[3]; | 4387 class expand_operand ops[3]; |
3929 rtx dest_mem; | 4388 rtx dest_mem; |
3930 rtx src_mem; | 4389 rtx src_mem; |
3931 | 4390 |
3932 if (!targetm.have_movstr ()) | 4391 if (!targetm.have_movstr ()) |
3933 return NULL_RTX; | 4392 return NULL_RTX; |
3934 | 4393 |
3935 dest_mem = get_memory_rtx (dest, NULL); | 4394 dest_mem = get_memory_rtx (dest, NULL); |
3936 src_mem = get_memory_rtx (src, NULL); | 4395 src_mem = get_memory_rtx (src, NULL); |
3937 if (!endp) | 4396 if (retmode == RETURN_BEGIN) |
3938 { | 4397 { |
3939 target = force_reg (Pmode, XEXP (dest_mem, 0)); | 4398 target = force_reg (Pmode, XEXP (dest_mem, 0)); |
3940 dest_mem = replace_equiv_address (dest_mem, target); | 4399 dest_mem = replace_equiv_address (dest_mem, target); |
3941 } | 4400 } |
3942 | 4401 |
3943 create_output_operand (&ops[0], endp ? target : NULL_RTX, Pmode); | 4402 create_output_operand (&ops[0], |
4403 retmode != RETURN_BEGIN ? target : NULL_RTX, Pmode); | |
3944 create_fixed_operand (&ops[1], dest_mem); | 4404 create_fixed_operand (&ops[1], dest_mem); |
3945 create_fixed_operand (&ops[2], src_mem); | 4405 create_fixed_operand (&ops[2], src_mem); |
3946 if (!maybe_expand_insn (targetm.code_for_movstr, 3, ops)) | 4406 if (!maybe_expand_insn (targetm.code_for_movstr, 3, ops)) |
3947 return NULL_RTX; | 4407 return NULL_RTX; |
3948 | 4408 |
3949 if (endp && target != const0_rtx) | 4409 if (retmode != RETURN_BEGIN && target != const0_rtx) |
3950 { | 4410 { |
3951 target = ops[0].value; | 4411 target = ops[0].value; |
3952 /* movstr is supposed to set end to the address of the NUL | 4412 /* movstr is supposed to set end to the address of the NUL |
3953 terminator. If the caller requested a mempcpy-like return value, | 4413 terminator. If the caller requested a mempcpy-like return value, |
3954 adjust it. */ | 4414 adjust it. */ |
3955 if (endp == 1) | 4415 if (retmode == RETURN_END) |
3956 { | 4416 { |
3957 rtx tem = plus_constant (GET_MODE (target), | 4417 rtx tem = plus_constant (GET_MODE (target), |
3958 gen_lowpart (GET_MODE (target), target), 1); | 4418 gen_lowpart (GET_MODE (target), target), 1); |
3959 emit_move_insn (target, force_operand (tem, NULL_RTX)); | 4419 emit_move_insn (target, force_operand (tem, NULL_RTX)); |
3960 } | 4420 } |
3965 /* Do some very basic size validation of a call to the strcpy builtin | 4425 /* Do some very basic size validation of a call to the strcpy builtin |
3966 given by EXP. Return NULL_RTX to have the built-in expand to a call | 4426 given by EXP. Return NULL_RTX to have the built-in expand to a call |
3967 to the library function. */ | 4427 to the library function. */ |
3968 | 4428 |
3969 static rtx | 4429 static rtx |
3970 expand_builtin_strcat (tree exp, rtx) | 4430 expand_builtin_strcat (tree exp) |
3971 { | 4431 { |
3972 if (!validate_arglist (exp, POINTER_TYPE, POINTER_TYPE, VOID_TYPE) | 4432 if (!validate_arglist (exp, POINTER_TYPE, POINTER_TYPE, VOID_TYPE) |
3973 || !warn_stringop_overflow) | 4433 || !warn_stringop_overflow) |
3974 return NULL_RTX; | 4434 return NULL_RTX; |
3975 | 4435 |
3976 tree dest = CALL_EXPR_ARG (exp, 0); | 4436 tree dest = CALL_EXPR_ARG (exp, 0); |
3977 tree src = CALL_EXPR_ARG (exp, 1); | 4437 tree src = CALL_EXPR_ARG (exp, 1); |
4438 | |
4439 /* Detect unterminated source (only). */ | |
4440 if (!check_nul_terminated_array (exp, src)) | |
4441 return NULL_RTX; | |
3978 | 4442 |
3979 /* There is no way here to determine the length of the string in | 4443 /* There is no way here to determine the length of the string in |
3980 the destination to which the SRC string is being appended so | 4444 the destination to which the SRC string is being appended so |
3981 just diagnose cases when the souce string is longer than | 4445 just diagnose cases when the souce string is longer than |
3982 the destination object. */ | 4446 the destination object. */ |
4039 if (!TREE_NO_WARNING (exp)) | 4503 if (!TREE_NO_WARNING (exp)) |
4040 warn_string_no_nul (EXPR_LOCATION (exp), "strcpy", src, nonstr); | 4504 warn_string_no_nul (EXPR_LOCATION (exp), "strcpy", src, nonstr); |
4041 return NULL_RTX; | 4505 return NULL_RTX; |
4042 } | 4506 } |
4043 | 4507 |
4044 return expand_movstr (dest, src, target, /*endp=*/0); | 4508 return expand_movstr (dest, src, target, /*retmode=*/ RETURN_BEGIN); |
4045 } | 4509 } |
4046 | 4510 |
4047 /* Expand a call EXP to the stpcpy builtin. | 4511 /* Expand a call EXP to the stpcpy builtin. |
4048 Return NULL_RTX if we failed the caller should emit a normal call, | 4512 Return NULL_RTX if we failed the caller should emit a normal call, |
4049 otherwise try to get the result in TARGET, if convenient (and in | 4513 otherwise try to get the result in TARGET, if convenient (and in |
4082 | 4546 |
4083 /* Ensure we get an actual string whose length can be evaluated at | 4547 /* Ensure we get an actual string whose length can be evaluated at |
4084 compile-time, not an expression containing a string. This is | 4548 compile-time, not an expression containing a string. This is |
4085 because the latter will potentially produce pessimized code | 4549 because the latter will potentially produce pessimized code |
4086 when used to produce the return value. */ | 4550 when used to produce the return value. */ |
4087 c_strlen_data data; | 4551 c_strlen_data lendata = { }; |
4088 memset (&data, 0, sizeof (c_strlen_data)); | |
4089 if (!c_getstr (src, NULL) | 4552 if (!c_getstr (src, NULL) |
4090 || !(len = c_strlen (src, 0, &data, 1))) | 4553 || !(len = c_strlen (src, 0, &lendata, 1))) |
4091 return expand_movstr (dst, src, target, /*endp=*/2); | 4554 return expand_movstr (dst, src, target, |
4092 | 4555 /*retmode=*/ RETURN_END_MINUS_ONE); |
4093 if (data.decl && !TREE_NO_WARNING (exp)) | 4556 |
4094 warn_string_no_nul (EXPR_LOCATION (exp), "stpcpy", src, data.decl); | 4557 if (lendata.decl && !TREE_NO_WARNING (exp)) |
4558 warn_string_no_nul (EXPR_LOCATION (exp), "stpcpy", src, lendata.decl); | |
4095 | 4559 |
4096 lenp1 = size_binop_loc (loc, PLUS_EXPR, len, ssize_int (1)); | 4560 lenp1 = size_binop_loc (loc, PLUS_EXPR, len, ssize_int (1)); |
4097 ret = expand_builtin_mempcpy_args (dst, src, lenp1, | 4561 ret = expand_builtin_mempcpy_args (dst, src, lenp1, |
4098 target, exp, /*endp=*/2); | 4562 target, exp, |
4563 /*retmode=*/ RETURN_END_MINUS_ONE); | |
4099 | 4564 |
4100 if (ret) | 4565 if (ret) |
4101 return ret; | 4566 return ret; |
4102 | 4567 |
4103 if (TREE_CODE (len) == INTEGER_CST) | 4568 if (TREE_CODE (len) == INTEGER_CST) |
4127 return target; | 4592 return target; |
4128 } | 4593 } |
4129 } | 4594 } |
4130 } | 4595 } |
4131 | 4596 |
4132 return expand_movstr (dst, src, target, /*endp=*/2); | 4597 return expand_movstr (dst, src, target, |
4598 /*retmode=*/ RETURN_END_MINUS_ONE); | |
4133 } | 4599 } |
4134 } | 4600 } |
4135 | 4601 |
4136 /* Expand a call EXP to the stpcpy builtin and diagnose uses of nonstring | 4602 /* Expand a call EXP to the stpcpy builtin and diagnose uses of nonstring |
4137 arguments while being careful to avoid duplicate warnings (which could | 4603 arguments while being careful to avoid duplicate warnings (which could |
4167 tree dest = CALL_EXPR_ARG (exp, 0); | 4633 tree dest = CALL_EXPR_ARG (exp, 0); |
4168 tree src = CALL_EXPR_ARG (exp, 1); | 4634 tree src = CALL_EXPR_ARG (exp, 1); |
4169 | 4635 |
4170 /* The exact number of bytes to write (not the maximum). */ | 4636 /* The exact number of bytes to write (not the maximum). */ |
4171 tree len = CALL_EXPR_ARG (exp, 2); | 4637 tree len = CALL_EXPR_ARG (exp, 2); |
4638 if (!check_nul_terminated_array (exp, src, len)) | |
4639 return NULL_RTX; | |
4172 | 4640 |
4173 /* The size of the destination object. */ | 4641 /* The size of the destination object. */ |
4174 tree destsize = compute_objsize (dest, warn_stringop_overflow - 1); | 4642 tree destsize = compute_objsize (dest, warn_stringop_overflow - 1); |
4175 | 4643 |
4176 check_access (exp, dest, src, len, /*maxread=*/NULL_TREE, src, destsize); | 4644 check_access (exp, dest, src, len, /*maxread=*/NULL_TREE, src, destsize); |
4205 tree src = CALL_EXPR_ARG (exp, 1); | 4673 tree src = CALL_EXPR_ARG (exp, 1); |
4206 tree maxread = CALL_EXPR_ARG (exp, 2); | 4674 tree maxread = CALL_EXPR_ARG (exp, 2); |
4207 | 4675 |
4208 /* Try to determine the range of lengths that the source expression | 4676 /* Try to determine the range of lengths that the source expression |
4209 refers to. */ | 4677 refers to. */ |
4210 tree lenrange[2]; | 4678 c_strlen_data lendata = { }; |
4211 get_range_strlen (src, lenrange); | 4679 get_range_strlen (src, &lendata, /* eltsize = */ 1); |
4212 | 4680 |
4213 /* Try to verify that the destination is big enough for the shortest | 4681 /* Try to verify that the destination is big enough for the shortest |
4214 string. */ | 4682 string. */ |
4215 | 4683 |
4216 if (!objsize && warn_stringop_overflow) | 4684 if (!objsize && warn_stringop_overflow) |
4220 being copied. */ | 4688 being copied. */ |
4221 objsize = compute_objsize (dest, warn_stringop_overflow - 1); | 4689 objsize = compute_objsize (dest, warn_stringop_overflow - 1); |
4222 } | 4690 } |
4223 | 4691 |
4224 /* Add one for the terminating nul. */ | 4692 /* Add one for the terminating nul. */ |
4225 tree srclen = (lenrange[0] | 4693 tree srclen = (lendata.minlen |
4226 ? fold_build2 (PLUS_EXPR, size_type_node, lenrange[0], | 4694 ? fold_build2 (PLUS_EXPR, size_type_node, lendata.minlen, |
4227 size_one_node) | 4695 size_one_node) |
4228 : NULL_TREE); | 4696 : NULL_TREE); |
4229 | 4697 |
4230 /* The strncat function copies at most MAXREAD bytes and always appends | 4698 /* The strncat function copies at most MAXREAD bytes and always appends |
4231 the terminating nul so the specified upper bound should never be equal | 4699 the terminating nul so the specified upper bound should never be equal |
4269 | 4737 |
4270 tree dest = CALL_EXPR_ARG (exp, 0); | 4738 tree dest = CALL_EXPR_ARG (exp, 0); |
4271 tree src = CALL_EXPR_ARG (exp, 1); | 4739 tree src = CALL_EXPR_ARG (exp, 1); |
4272 /* The upper bound on the number of bytes to write. */ | 4740 /* The upper bound on the number of bytes to write. */ |
4273 tree maxread = CALL_EXPR_ARG (exp, 2); | 4741 tree maxread = CALL_EXPR_ARG (exp, 2); |
4742 | |
4743 /* Detect unterminated source (only). */ | |
4744 if (!check_nul_terminated_array (exp, src, maxread)) | |
4745 return NULL_RTX; | |
4746 | |
4274 /* The length of the source sequence. */ | 4747 /* The length of the source sequence. */ |
4275 tree slen = c_strlen (src, 1); | 4748 tree slen = c_strlen (src, 1); |
4276 | 4749 |
4277 /* Try to determine the range of lengths that the source expression | 4750 /* Try to determine the range of lengths that the source expression |
4278 refers to. */ | 4751 refers to. Since the lengths are only used for warning and not |
4279 tree lenrange[2]; | 4752 for code generation disable strict mode below. */ |
4280 if (slen) | 4753 tree maxlen = slen; |
4281 lenrange[0] = lenrange[1] = slen; | 4754 if (!maxlen) |
4282 else | 4755 { |
4283 get_range_strlen (src, lenrange); | 4756 c_strlen_data lendata = { }; |
4757 get_range_strlen (src, &lendata, /* eltsize = */ 1); | |
4758 maxlen = lendata.maxbound; | |
4759 } | |
4284 | 4760 |
4285 /* Try to verify that the destination is big enough for the shortest | 4761 /* Try to verify that the destination is big enough for the shortest |
4286 string. First try to determine the size of the destination object | 4762 string. First try to determine the size of the destination object |
4287 into which the source is being copied. */ | 4763 into which the source is being copied. */ |
4288 tree destsize = compute_objsize (dest, warn_stringop_overflow - 1); | 4764 tree destsize = compute_objsize (dest, warn_stringop_overflow - 1); |
4289 | 4765 |
4290 /* Add one for the terminating nul. */ | 4766 /* Add one for the terminating nul. */ |
4291 tree srclen = (lenrange[0] | 4767 tree srclen = (maxlen |
4292 ? fold_build2 (PLUS_EXPR, size_type_node, lenrange[0], | 4768 ? fold_build2 (PLUS_EXPR, size_type_node, maxlen, |
4293 size_one_node) | 4769 size_one_node) |
4294 : NULL_TREE); | 4770 : NULL_TREE); |
4295 | 4771 |
4296 /* The strncat function copies at most MAXREAD bytes and always appends | 4772 /* The strncat function copies at most MAXREAD bytes and always appends |
4297 the terminating nul so the specified upper bound should never be equal | 4773 the terminating nul so the specified upper bound should never be equal |
4327 static rtx | 4803 static rtx |
4328 expand_builtin_strncpy (tree exp, rtx target) | 4804 expand_builtin_strncpy (tree exp, rtx target) |
4329 { | 4805 { |
4330 location_t loc = EXPR_LOCATION (exp); | 4806 location_t loc = EXPR_LOCATION (exp); |
4331 | 4807 |
4332 if (validate_arglist (exp, | 4808 if (!validate_arglist (exp, |
4333 POINTER_TYPE, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE)) | 4809 POINTER_TYPE, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE)) |
4334 { | 4810 return NULL_RTX; |
4335 tree dest = CALL_EXPR_ARG (exp, 0); | 4811 tree dest = CALL_EXPR_ARG (exp, 0); |
4336 tree src = CALL_EXPR_ARG (exp, 1); | 4812 tree src = CALL_EXPR_ARG (exp, 1); |
4337 /* The number of bytes to write (not the maximum). */ | 4813 /* The number of bytes to write (not the maximum). */ |
4338 tree len = CALL_EXPR_ARG (exp, 2); | 4814 tree len = CALL_EXPR_ARG (exp, 2); |
4339 /* The length of the source sequence. */ | 4815 |
4340 tree slen = c_strlen (src, 1); | 4816 if (!check_nul_terminated_array (exp, src, len)) |
4341 | 4817 return NULL_RTX; |
4342 if (warn_stringop_overflow) | 4818 |
4343 { | 4819 /* The length of the source sequence. */ |
4344 tree destsize = compute_objsize (dest, | 4820 tree slen = c_strlen (src, 1); |
4345 warn_stringop_overflow - 1); | 4821 |
4346 | 4822 if (warn_stringop_overflow) |
4347 /* The number of bytes to write is LEN but check_access will also | 4823 { |
4348 check SLEN if LEN's value isn't known. */ | 4824 tree destsize = compute_objsize (dest, |
4349 check_access (exp, dest, src, len, /*maxread=*/NULL_TREE, src, | 4825 warn_stringop_overflow - 1); |
4350 destsize); | 4826 |
4351 } | 4827 /* The number of bytes to write is LEN but check_access will also |
4352 | 4828 check SLEN if LEN's value isn't known. */ |
4353 /* We must be passed a constant len and src parameter. */ | 4829 check_access (exp, dest, src, len, /*maxread=*/NULL_TREE, src, |
4354 if (!tree_fits_uhwi_p (len) || !slen || !tree_fits_uhwi_p (slen)) | 4830 destsize); |
4831 } | |
4832 | |
4833 /* We must be passed a constant len and src parameter. */ | |
4834 if (!tree_fits_uhwi_p (len) || !slen || !tree_fits_uhwi_p (slen)) | |
4835 return NULL_RTX; | |
4836 | |
4837 slen = size_binop_loc (loc, PLUS_EXPR, slen, ssize_int (1)); | |
4838 | |
4839 /* We're required to pad with trailing zeros if the requested | |
4840 len is greater than strlen(s2)+1. In that case try to | |
4841 use store_by_pieces, if it fails, punt. */ | |
4842 if (tree_int_cst_lt (slen, len)) | |
4843 { | |
4844 unsigned int dest_align = get_pointer_alignment (dest); | |
4845 const char *p = c_getstr (src); | |
4846 rtx dest_mem; | |
4847 | |
4848 if (!p || dest_align == 0 || !tree_fits_uhwi_p (len) | |
4849 || !can_store_by_pieces (tree_to_uhwi (len), | |
4850 builtin_strncpy_read_str, | |
4851 CONST_CAST (char *, p), | |
4852 dest_align, false)) | |
4355 return NULL_RTX; | 4853 return NULL_RTX; |
4356 | 4854 |
4357 slen = size_binop_loc (loc, PLUS_EXPR, slen, ssize_int (1)); | 4855 dest_mem = get_memory_rtx (dest, len); |
4358 | 4856 store_by_pieces (dest_mem, tree_to_uhwi (len), |
4359 /* We're required to pad with trailing zeros if the requested | 4857 builtin_strncpy_read_str, |
4360 len is greater than strlen(s2)+1. In that case try to | 4858 CONST_CAST (char *, p), dest_align, false, |
4361 use store_by_pieces, if it fails, punt. */ | 4859 RETURN_BEGIN); |
4362 if (tree_int_cst_lt (slen, len)) | 4860 dest_mem = force_operand (XEXP (dest_mem, 0), target); |
4363 { | 4861 dest_mem = convert_memory_address (ptr_mode, dest_mem); |
4364 unsigned int dest_align = get_pointer_alignment (dest); | 4862 return dest_mem; |
4365 const char *p = c_getstr (src); | 4863 } |
4366 rtx dest_mem; | 4864 |
4367 | |
4368 if (!p || dest_align == 0 || !tree_fits_uhwi_p (len) | |
4369 || !can_store_by_pieces (tree_to_uhwi (len), | |
4370 builtin_strncpy_read_str, | |
4371 CONST_CAST (char *, p), | |
4372 dest_align, false)) | |
4373 return NULL_RTX; | |
4374 | |
4375 dest_mem = get_memory_rtx (dest, len); | |
4376 store_by_pieces (dest_mem, tree_to_uhwi (len), | |
4377 builtin_strncpy_read_str, | |
4378 CONST_CAST (char *, p), dest_align, false, 0); | |
4379 dest_mem = force_operand (XEXP (dest_mem, 0), target); | |
4380 dest_mem = convert_memory_address (ptr_mode, dest_mem); | |
4381 return dest_mem; | |
4382 } | |
4383 } | |
4384 return NULL_RTX; | 4865 return NULL_RTX; |
4385 } | 4866 } |
4386 | 4867 |
4387 /* Callback routine for store_by_pieces. Read GET_MODE_BITSIZE (MODE) | 4868 /* Callback routine for store_by_pieces. Read GET_MODE_BITSIZE (MODE) |
4388 bytes from constant string DATA + OFFSET and return it as target | 4869 bytes from constant string DATA + OFFSET and return it as target |
4518 true)) | 4999 true)) |
4519 { | 5000 { |
4520 val_rtx = force_reg (val_mode, val_rtx); | 5001 val_rtx = force_reg (val_mode, val_rtx); |
4521 store_by_pieces (dest_mem, tree_to_uhwi (len), | 5002 store_by_pieces (dest_mem, tree_to_uhwi (len), |
4522 builtin_memset_gen_str, val_rtx, dest_align, | 5003 builtin_memset_gen_str, val_rtx, dest_align, |
4523 true, 0); | 5004 true, RETURN_BEGIN); |
4524 } | 5005 } |
4525 else if (!set_storage_via_setmem (dest_mem, len_rtx, val_rtx, | 5006 else if (!set_storage_via_setmem (dest_mem, len_rtx, val_rtx, |
4526 dest_align, expected_align, | 5007 dest_align, expected_align, |
4527 expected_size, min_size, max_size, | 5008 expected_size, min_size, max_size, |
4528 probable_max_size)) | 5009 probable_max_size)) |
4541 if (tree_fits_uhwi_p (len) | 5022 if (tree_fits_uhwi_p (len) |
4542 && can_store_by_pieces (tree_to_uhwi (len), | 5023 && can_store_by_pieces (tree_to_uhwi (len), |
4543 builtin_memset_read_str, &c, dest_align, | 5024 builtin_memset_read_str, &c, dest_align, |
4544 true)) | 5025 true)) |
4545 store_by_pieces (dest_mem, tree_to_uhwi (len), | 5026 store_by_pieces (dest_mem, tree_to_uhwi (len), |
4546 builtin_memset_read_str, &c, dest_align, true, 0); | 5027 builtin_memset_read_str, &c, dest_align, true, |
5028 RETURN_BEGIN); | |
4547 else if (!set_storage_via_setmem (dest_mem, len_rtx, | 5029 else if (!set_storage_via_setmem (dest_mem, len_rtx, |
4548 gen_int_mode (c, val_mode), | 5030 gen_int_mode (c, val_mode), |
4549 dest_align, expected_align, | 5031 dest_align, expected_align, |
4550 expected_size, min_size, max_size, | 5032 expected_size, min_size, max_size, |
4551 probable_max_size)) | 5033 probable_max_size)) |
4625 machine_mode insn_mode = insn_data[icode].operand[0].mode; | 5107 machine_mode insn_mode = insn_data[icode].operand[0].mode; |
4626 | 5108 |
4627 if (target && (!REG_P (target) || HARD_REGISTER_P (target))) | 5109 if (target && (!REG_P (target) || HARD_REGISTER_P (target))) |
4628 target = NULL_RTX; | 5110 target = NULL_RTX; |
4629 | 5111 |
4630 struct expand_operand ops[4]; | 5112 class expand_operand ops[4]; |
4631 create_output_operand (&ops[0], target, insn_mode); | 5113 create_output_operand (&ops[0], target, insn_mode); |
4632 create_fixed_operand (&ops[1], arg1_rtx); | 5114 create_fixed_operand (&ops[1], arg1_rtx); |
4633 create_fixed_operand (&ops[2], arg2_rtx); | 5115 create_fixed_operand (&ops[2], arg2_rtx); |
4634 create_integer_operand (&ops[3], align); | 5116 create_integer_operand (&ops[3], align); |
4635 if (maybe_expand_insn (icode, 4, ops)) | 5117 if (maybe_expand_insn (icode, 4, ops)) |
4756 expand_builtin_strcmp (tree exp, ATTRIBUTE_UNUSED rtx target) | 5238 expand_builtin_strcmp (tree exp, ATTRIBUTE_UNUSED rtx target) |
4757 { | 5239 { |
4758 if (!validate_arglist (exp, POINTER_TYPE, POINTER_TYPE, VOID_TYPE)) | 5240 if (!validate_arglist (exp, POINTER_TYPE, POINTER_TYPE, VOID_TYPE)) |
4759 return NULL_RTX; | 5241 return NULL_RTX; |
4760 | 5242 |
5243 tree arg1 = CALL_EXPR_ARG (exp, 0); | |
5244 tree arg2 = CALL_EXPR_ARG (exp, 1); | |
5245 | |
5246 if (!check_nul_terminated_array (exp, arg1) | |
5247 || !check_nul_terminated_array (exp, arg2)) | |
5248 return NULL_RTX; | |
5249 | |
4761 /* Due to the performance benefit, always inline the calls first. */ | 5250 /* Due to the performance benefit, always inline the calls first. */ |
4762 rtx result = NULL_RTX; | 5251 rtx result = NULL_RTX; |
4763 result = inline_expand_builtin_string_cmp (exp, target); | 5252 result = inline_expand_builtin_string_cmp (exp, target); |
4764 if (result) | 5253 if (result) |
4765 return result; | 5254 return result; |
4766 | 5255 |
4767 insn_code cmpstr_icode = direct_optab_handler (cmpstr_optab, SImode); | 5256 insn_code cmpstr_icode = direct_optab_handler (cmpstr_optab, SImode); |
4768 insn_code cmpstrn_icode = direct_optab_handler (cmpstrn_optab, SImode); | 5257 insn_code cmpstrn_icode = direct_optab_handler (cmpstrn_optab, SImode); |
4769 if (cmpstr_icode == CODE_FOR_nothing && cmpstrn_icode == CODE_FOR_nothing) | 5258 if (cmpstr_icode == CODE_FOR_nothing && cmpstrn_icode == CODE_FOR_nothing) |
4770 return NULL_RTX; | 5259 return NULL_RTX; |
4771 | |
4772 tree arg1 = CALL_EXPR_ARG (exp, 0); | |
4773 tree arg2 = CALL_EXPR_ARG (exp, 1); | |
4774 | 5260 |
4775 unsigned int arg1_align = get_pointer_alignment (arg1) / BITS_PER_UNIT; | 5261 unsigned int arg1_align = get_pointer_alignment (arg1) / BITS_PER_UNIT; |
4776 unsigned int arg2_align = get_pointer_alignment (arg2) / BITS_PER_UNIT; | 5262 unsigned int arg2_align = get_pointer_alignment (arg2) / BITS_PER_UNIT; |
4777 | 5263 |
4778 /* If we don't have POINTER_TYPE, call the function. */ | 5264 /* If we don't have POINTER_TYPE, call the function. */ |
4875 { | 5361 { |
4876 if (!validate_arglist (exp, | 5362 if (!validate_arglist (exp, |
4877 POINTER_TYPE, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE)) | 5363 POINTER_TYPE, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE)) |
4878 return NULL_RTX; | 5364 return NULL_RTX; |
4879 | 5365 |
5366 tree arg1 = CALL_EXPR_ARG (exp, 0); | |
5367 tree arg2 = CALL_EXPR_ARG (exp, 1); | |
5368 tree arg3 = CALL_EXPR_ARG (exp, 2); | |
5369 | |
5370 if (!check_nul_terminated_array (exp, arg1, arg3) | |
5371 || !check_nul_terminated_array (exp, arg2, arg3)) | |
5372 return NULL_RTX; | |
5373 | |
4880 /* Due to the performance benefit, always inline the calls first. */ | 5374 /* Due to the performance benefit, always inline the calls first. */ |
4881 rtx result = NULL_RTX; | 5375 rtx result = NULL_RTX; |
4882 result = inline_expand_builtin_string_cmp (exp, target); | 5376 result = inline_expand_builtin_string_cmp (exp, target); |
4883 if (result) | 5377 if (result) |
4884 return result; | 5378 return result; |
4889 insn_code cmpstrn_icode = direct_optab_handler (cmpstrn_optab, SImode); | 5383 insn_code cmpstrn_icode = direct_optab_handler (cmpstrn_optab, SImode); |
4890 if (cmpstrn_icode == CODE_FOR_nothing) | 5384 if (cmpstrn_icode == CODE_FOR_nothing) |
4891 return NULL_RTX; | 5385 return NULL_RTX; |
4892 | 5386 |
4893 tree len; | 5387 tree len; |
4894 | |
4895 tree arg1 = CALL_EXPR_ARG (exp, 0); | |
4896 tree arg2 = CALL_EXPR_ARG (exp, 1); | |
4897 tree arg3 = CALL_EXPR_ARG (exp, 2); | |
4898 | 5388 |
4899 unsigned int arg1_align = get_pointer_alignment (arg1) / BITS_PER_UNIT; | 5389 unsigned int arg1_align = get_pointer_alignment (arg1) / BITS_PER_UNIT; |
4900 unsigned int arg2_align = get_pointer_alignment (arg2) / BITS_PER_UNIT; | 5390 unsigned int arg2_align = get_pointer_alignment (arg2) / BITS_PER_UNIT; |
4901 | 5391 |
4902 tree len1 = c_strlen (arg1, 1); | 5392 tree len1 = c_strlen (arg1, 1); |
5341 of a variable-sized object, it cannot accumulate. */ | 5831 of a variable-sized object, it cannot accumulate. */ |
5342 result | 5832 result |
5343 = allocate_dynamic_stack_space (op0, 0, align, max_size, alloca_for_var); | 5833 = allocate_dynamic_stack_space (op0, 0, align, max_size, alloca_for_var); |
5344 result = convert_memory_address (ptr_mode, result); | 5834 result = convert_memory_address (ptr_mode, result); |
5345 | 5835 |
5836 /* Dynamic allocations for variables are recorded during gimplification. */ | |
5837 if (!alloca_for_var && (flag_callgraph_info & CALLGRAPH_INFO_DYNAMIC_ALLOC)) | |
5838 record_dynamic_alloc (exp); | |
5839 | |
5346 return result; | 5840 return result; |
5347 } | 5841 } |
5348 | 5842 |
5349 /* Emit a call to __asan_allocas_unpoison call in EXP. Add to second argument | 5843 /* Emit a call to __asan_allocas_unpoison call in EXP. Add to second argument |
5350 of the call virtual_stack_dynamic_rtx - stack_pointer_rtx, which is the | 5844 of the call virtual_stack_dynamic_rtx - stack_pointer_rtx, which is the |
5598 return const0_rtx; | 6092 return const0_rtx; |
5599 } | 6093 } |
5600 | 6094 |
5601 if (targetm.have_clear_cache ()) | 6095 if (targetm.have_clear_cache ()) |
5602 { | 6096 { |
5603 struct expand_operand ops[2]; | 6097 class expand_operand ops[2]; |
5604 | 6098 |
5605 begin = CALL_EXPR_ARG (exp, 0); | 6099 begin = CALL_EXPR_ARG (exp, 0); |
5606 begin_rtx = expand_expr (begin, NULL_RTX, Pmode, EXPAND_NORMAL); | 6100 begin_rtx = expand_expr (begin, NULL_RTX, Pmode, EXPAND_NORMAL); |
5607 | 6101 |
5608 end = CALL_EXPR_ARG (exp, 1); | 6102 end = CALL_EXPR_ARG (exp, 1); |
5734 t_chain = CALL_EXPR_ARG (exp, 2); | 6228 t_chain = CALL_EXPR_ARG (exp, 2); |
5735 | 6229 |
5736 r_descr = expand_normal (t_descr); | 6230 r_descr = expand_normal (t_descr); |
5737 m_descr = gen_rtx_MEM (BLKmode, r_descr); | 6231 m_descr = gen_rtx_MEM (BLKmode, r_descr); |
5738 MEM_NOTRAP_P (m_descr) = 1; | 6232 MEM_NOTRAP_P (m_descr) = 1; |
6233 set_mem_align (m_descr, GET_MODE_ALIGNMENT (ptr_mode)); | |
5739 | 6234 |
5740 r_func = expand_normal (t_func); | 6235 r_func = expand_normal (t_func); |
5741 r_chain = expand_normal (t_chain); | 6236 r_chain = expand_normal (t_chain); |
5742 | 6237 |
5743 /* Generate insns to initialize the descriptor. */ | 6238 /* Generate insns to initialize the descriptor. */ |
5882 static rtx | 6377 static rtx |
5883 expand_builtin_fork_or_exec (tree fn, tree exp, rtx target, int ignore) | 6378 expand_builtin_fork_or_exec (tree fn, tree exp, rtx target, int ignore) |
5884 { | 6379 { |
5885 tree id, decl; | 6380 tree id, decl; |
5886 tree call; | 6381 tree call; |
6382 | |
6383 if (DECL_FUNCTION_CODE (fn) != BUILT_IN_FORK) | |
6384 { | |
6385 /* Detect unterminated path. */ | |
6386 if (!check_nul_terminated_array (exp, CALL_EXPR_ARG (exp, 0))) | |
6387 return NULL_RTX; | |
6388 | |
6389 /* Also detect unterminated first argument. */ | |
6390 switch (DECL_FUNCTION_CODE (fn)) | |
6391 { | |
6392 case BUILT_IN_EXECL: | |
6393 case BUILT_IN_EXECLE: | |
6394 case BUILT_IN_EXECLP: | |
6395 if (!check_nul_terminated_array (exp, CALL_EXPR_ARG (exp, 0))) | |
6396 return NULL_RTX; | |
6397 default: | |
6398 break; | |
6399 } | |
6400 } | |
6401 | |
5887 | 6402 |
5888 /* If we are not profiling, just call the function. */ | 6403 /* If we are not profiling, just call the function. */ |
5889 if (!profile_arc_flag) | 6404 if (!profile_arc_flag) |
5890 return NULL_RTX; | 6405 return NULL_RTX; |
5891 | 6406 |
6146 static enum memmodel | 6661 static enum memmodel |
6147 get_memmodel (tree exp) | 6662 get_memmodel (tree exp) |
6148 { | 6663 { |
6149 rtx op; | 6664 rtx op; |
6150 unsigned HOST_WIDE_INT val; | 6665 unsigned HOST_WIDE_INT val; |
6151 source_location loc | 6666 location_t loc |
6152 = expansion_point_location_if_in_system_header (input_location); | 6667 = expansion_point_location_if_in_system_header (input_location); |
6153 | 6668 |
6154 /* If the parameter is not a constant, it's a run time value so we'll just | 6669 /* If the parameter is not a constant, it's a run time value so we'll just |
6155 convert it to MEMMODEL_SEQ_CST to avoid annoying runtime checking. */ | 6670 convert it to MEMMODEL_SEQ_CST to avoid annoying runtime checking. */ |
6156 if (TREE_CODE (exp) != INTEGER_CST) | 6671 if (TREE_CODE (exp) != INTEGER_CST) |
6222 rtx expect, desired, mem, oldval; | 6737 rtx expect, desired, mem, oldval; |
6223 rtx_code_label *label; | 6738 rtx_code_label *label; |
6224 enum memmodel success, failure; | 6739 enum memmodel success, failure; |
6225 tree weak; | 6740 tree weak; |
6226 bool is_weak; | 6741 bool is_weak; |
6227 source_location loc | 6742 location_t loc |
6228 = expansion_point_location_if_in_system_header (input_location); | 6743 = expansion_point_location_if_in_system_header (input_location); |
6229 | 6744 |
6230 success = get_memmodel (CALL_EXPR_ARG (exp, 4)); | 6745 success = get_memmodel (CALL_EXPR_ARG (exp, 4)); |
6231 failure = get_memmodel (CALL_EXPR_ARG (exp, 5)); | 6746 failure = get_memmodel (CALL_EXPR_ARG (exp, 5)); |
6232 | 6747 |
6349 machine_mode mode = int_mode_for_size (BITS_PER_UNIT * size, 0).require (); | 6864 machine_mode mode = int_mode_for_size (BITS_PER_UNIT * size, 0).require (); |
6350 rtx expect, desired, mem, oldval, boolret; | 6865 rtx expect, desired, mem, oldval, boolret; |
6351 enum memmodel success, failure; | 6866 enum memmodel success, failure; |
6352 tree lhs; | 6867 tree lhs; |
6353 bool is_weak; | 6868 bool is_weak; |
6354 source_location loc | 6869 location_t loc |
6355 = expansion_point_location_if_in_system_header (gimple_location (call)); | 6870 = expansion_point_location_if_in_system_header (gimple_location (call)); |
6356 | 6871 |
6357 success = get_memmodel (gimple_call_arg (call, 4)); | 6872 success = get_memmodel (gimple_call_arg (call, 4)); |
6358 failure = get_memmodel (gimple_call_arg (call, 5)); | 6873 failure = get_memmodel (gimple_call_arg (call, 5)); |
6359 | 6874 |
6421 enum memmodel model; | 6936 enum memmodel model; |
6422 | 6937 |
6423 model = get_memmodel (CALL_EXPR_ARG (exp, 1)); | 6938 model = get_memmodel (CALL_EXPR_ARG (exp, 1)); |
6424 if (is_mm_release (model) || is_mm_acq_rel (model)) | 6939 if (is_mm_release (model) || is_mm_acq_rel (model)) |
6425 { | 6940 { |
6426 source_location loc | 6941 location_t loc |
6427 = expansion_point_location_if_in_system_header (input_location); | 6942 = expansion_point_location_if_in_system_header (input_location); |
6428 warning_at (loc, OPT_Winvalid_memory_model, | 6943 warning_at (loc, OPT_Winvalid_memory_model, |
6429 "invalid memory model for %<__atomic_load%>"); | 6944 "invalid memory model for %<__atomic_load%>"); |
6430 model = MEMMODEL_SEQ_CST; | 6945 model = MEMMODEL_SEQ_CST; |
6431 } | 6946 } |
6453 | 6968 |
6454 model = get_memmodel (CALL_EXPR_ARG (exp, 2)); | 6969 model = get_memmodel (CALL_EXPR_ARG (exp, 2)); |
6455 if (!(is_mm_relaxed (model) || is_mm_seq_cst (model) | 6970 if (!(is_mm_relaxed (model) || is_mm_seq_cst (model) |
6456 || is_mm_release (model))) | 6971 || is_mm_release (model))) |
6457 { | 6972 { |
6458 source_location loc | 6973 location_t loc |
6459 = expansion_point_location_if_in_system_header (input_location); | 6974 = expansion_point_location_if_in_system_header (input_location); |
6460 warning_at (loc, OPT_Winvalid_memory_model, | 6975 warning_at (loc, OPT_Winvalid_memory_model, |
6461 "invalid memory model for %<__atomic_store%>"); | 6976 "invalid memory model for %<__atomic_store%>"); |
6462 model = MEMMODEL_SEQ_CST; | 6977 model = MEMMODEL_SEQ_CST; |
6463 } | 6978 } |
6517 STRIP_NOPS (addr); | 7032 STRIP_NOPS (addr); |
6518 | 7033 |
6519 gcc_assert (TREE_OPERAND (addr, 0) == fndecl); | 7034 gcc_assert (TREE_OPERAND (addr, 0) == fndecl); |
6520 TREE_OPERAND (addr, 0) = builtin_decl_explicit (ext_call); | 7035 TREE_OPERAND (addr, 0) = builtin_decl_explicit (ext_call); |
6521 | 7036 |
6522 /* If we will emit code after the call, the call can not be a tail call. | 7037 /* If we will emit code after the call, the call cannot be a tail call. |
6523 If it is emitted as a tail call, a barrier is emitted after it, and | 7038 If it is emitted as a tail call, a barrier is emitted after it, and |
6524 then all trailing code is removed. */ | 7039 then all trailing code is removed. */ |
6525 if (!ignore) | 7040 if (!ignore) |
6526 CALL_EXPR_TAILCALL (exp) = 0; | 7041 CALL_EXPR_TAILCALL (exp) = 0; |
6527 | 7042 |
6558 tree lhs = gimple_call_lhs (call); | 7073 tree lhs = gimple_call_lhs (call); |
6559 enum memmodel model = MEMMODEL_SYNC_SEQ_CST; | 7074 enum memmodel model = MEMMODEL_SYNC_SEQ_CST; |
6560 machine_mode mode = TYPE_MODE (TREE_TYPE (flag)); | 7075 machine_mode mode = TYPE_MODE (TREE_TYPE (flag)); |
6561 enum rtx_code code; | 7076 enum rtx_code code; |
6562 optab optab; | 7077 optab optab; |
6563 struct expand_operand ops[5]; | 7078 class expand_operand ops[5]; |
6564 | 7079 |
6565 gcc_assert (flag_inline_atomics); | 7080 gcc_assert (flag_inline_atomics); |
6566 | 7081 |
6567 if (gimple_call_num_args (call) == 4) | 7082 if (gimple_call_num_args (call) == 4) |
6568 model = get_memmodel (gimple_call_arg (call, 3)); | 7083 model = get_memmodel (gimple_call_arg (call, 3)); |
6646 mem = get_builtin_sync_mem (CALL_EXPR_ARG (exp, 0), mode); | 7161 mem = get_builtin_sync_mem (CALL_EXPR_ARG (exp, 0), mode); |
6647 model = get_memmodel (CALL_EXPR_ARG (exp, 1)); | 7162 model = get_memmodel (CALL_EXPR_ARG (exp, 1)); |
6648 | 7163 |
6649 if (is_mm_consume (model) || is_mm_acquire (model) || is_mm_acq_rel (model)) | 7164 if (is_mm_consume (model) || is_mm_acquire (model) || is_mm_acq_rel (model)) |
6650 { | 7165 { |
6651 source_location loc | 7166 location_t loc |
6652 = expansion_point_location_if_in_system_header (input_location); | 7167 = expansion_point_location_if_in_system_header (input_location); |
6653 warning_at (loc, OPT_Winvalid_memory_model, | 7168 warning_at (loc, OPT_Winvalid_memory_model, |
6654 "invalid memory model for %<__atomic_store%>"); | 7169 "invalid memory model for %<__atomic_store%>"); |
6655 model = MEMMODEL_SEQ_CST; | 7170 model = MEMMODEL_SEQ_CST; |
6656 } | 7171 } |
6770 tree arg0 = CALL_EXPR_ARG (exp, 0); | 7285 tree arg0 = CALL_EXPR_ARG (exp, 0); |
6771 tree arg1 = CALL_EXPR_ARG (exp, 1); | 7286 tree arg1 = CALL_EXPR_ARG (exp, 1); |
6772 | 7287 |
6773 if (TREE_CODE (arg0) != INTEGER_CST) | 7288 if (TREE_CODE (arg0) != INTEGER_CST) |
6774 { | 7289 { |
6775 error ("non-constant argument 1 to __atomic_always_lock_free"); | 7290 error ("non-constant argument 1 to %qs", "__atomic_always_lock_free"); |
6776 return const0_rtx; | 7291 return const0_rtx; |
6777 } | 7292 } |
6778 | 7293 |
6779 size = fold_builtin_atomic_always_lock_free (arg0, arg1); | 7294 size = fold_builtin_atomic_always_lock_free (arg0, arg1); |
6780 if (size == boolean_true_node) | 7295 if (size == boolean_true_node) |
6812 tree arg0 = CALL_EXPR_ARG (exp, 0); | 7327 tree arg0 = CALL_EXPR_ARG (exp, 0); |
6813 tree arg1 = CALL_EXPR_ARG (exp, 1); | 7328 tree arg1 = CALL_EXPR_ARG (exp, 1); |
6814 | 7329 |
6815 if (!INTEGRAL_TYPE_P (TREE_TYPE (arg0))) | 7330 if (!INTEGRAL_TYPE_P (TREE_TYPE (arg0))) |
6816 { | 7331 { |
6817 error ("non-integer argument 1 to __atomic_is_lock_free"); | 7332 error ("non-integer argument 1 to %qs", "__atomic_is_lock_free"); |
6818 return NULL_RTX; | 7333 return NULL_RTX; |
6819 } | 7334 } |
6820 | 7335 |
6821 if (!flag_inline_atomics) | 7336 if (!flag_inline_atomics) |
6822 return NULL_RTX; | 7337 return NULL_RTX; |
6866 if (!validate_arglist (exp, VOID_TYPE)) | 7381 if (!validate_arglist (exp, VOID_TYPE)) |
6867 return const0_rtx; | 7382 return const0_rtx; |
6868 icode = direct_optab_handler (get_thread_pointer_optab, Pmode); | 7383 icode = direct_optab_handler (get_thread_pointer_optab, Pmode); |
6869 if (icode != CODE_FOR_nothing) | 7384 if (icode != CODE_FOR_nothing) |
6870 { | 7385 { |
6871 struct expand_operand op; | 7386 class expand_operand op; |
6872 /* If the target is not sutitable then create a new target. */ | 7387 /* If the target is not sutitable then create a new target. */ |
6873 if (target == NULL_RTX | 7388 if (target == NULL_RTX |
6874 || !REG_P (target) | 7389 || !REG_P (target) |
6875 || GET_MODE (target) != Pmode) | 7390 || GET_MODE (target) != Pmode) |
6876 target = gen_reg_rtx (Pmode); | 7391 target = gen_reg_rtx (Pmode); |
6877 create_output_operand (&op, target, Pmode); | 7392 create_output_operand (&op, target, Pmode); |
6878 expand_insn (icode, 1, &op); | 7393 expand_insn (icode, 1, &op); |
6879 return target; | 7394 return target; |
6880 } | 7395 } |
6881 error ("__builtin_thread_pointer is not supported on this target"); | 7396 error ("%<__builtin_thread_pointer%> is not supported on this target"); |
6882 return const0_rtx; | 7397 return const0_rtx; |
6883 } | 7398 } |
6884 | 7399 |
6885 static void | 7400 static void |
6886 expand_builtin_set_thread_pointer (tree exp) | 7401 expand_builtin_set_thread_pointer (tree exp) |
6889 if (!validate_arglist (exp, POINTER_TYPE, VOID_TYPE)) | 7404 if (!validate_arglist (exp, POINTER_TYPE, VOID_TYPE)) |
6890 return; | 7405 return; |
6891 icode = direct_optab_handler (set_thread_pointer_optab, Pmode); | 7406 icode = direct_optab_handler (set_thread_pointer_optab, Pmode); |
6892 if (icode != CODE_FOR_nothing) | 7407 if (icode != CODE_FOR_nothing) |
6893 { | 7408 { |
6894 struct expand_operand op; | 7409 class expand_operand op; |
6895 rtx val = expand_expr (CALL_EXPR_ARG (exp, 0), NULL_RTX, | 7410 rtx val = expand_expr (CALL_EXPR_ARG (exp, 0), NULL_RTX, |
6896 Pmode, EXPAND_NORMAL); | 7411 Pmode, EXPAND_NORMAL); |
6897 create_input_operand (&op, val, Pmode); | 7412 create_input_operand (&op, val, Pmode); |
6898 expand_insn (icode, 1, &op); | 7413 expand_insn (icode, 1, &op); |
6899 return; | 7414 return; |
6900 } | 7415 } |
6901 error ("__builtin_set_thread_pointer is not supported on this target"); | 7416 error ("%<__builtin_set_thread_pointer%> is not supported on this target"); |
6902 } | 7417 } |
6903 | 7418 |
6904 | 7419 |
6905 /* Emit code to restore the current value of stack. */ | 7420 /* Emit code to restore the current value of stack. */ |
6906 | 7421 |
7110 /* If neither strings is constant string, the call is not qualify. */ | 7625 /* If neither strings is constant string, the call is not qualify. */ |
7111 if (!src_str1 && !src_str2) | 7626 if (!src_str1 && !src_str2) |
7112 return NULL_RTX; | 7627 return NULL_RTX; |
7113 | 7628 |
7114 /* For strncmp, if the length is not a const, not qualify. */ | 7629 /* For strncmp, if the length is not a const, not qualify. */ |
7115 if (is_ncmp && !tree_fits_uhwi_p (len3_tree)) | 7630 if (is_ncmp) |
7116 return NULL_RTX; | 7631 { |
7632 if (!tree_fits_uhwi_p (len3_tree)) | |
7633 return NULL_RTX; | |
7634 else | |
7635 len3 = tree_to_uhwi (len3_tree); | |
7636 } | |
7637 | |
7638 if (src_str1 != NULL) | |
7639 len1 = strnlen (src_str1, len1) + 1; | |
7640 | |
7641 if (src_str2 != NULL) | |
7642 len2 = strnlen (src_str2, len2) + 1; | |
7117 | 7643 |
7118 int const_str_n = 0; | 7644 int const_str_n = 0; |
7119 if (!len1) | 7645 if (!len1) |
7120 const_str_n = 2; | 7646 const_str_n = 2; |
7121 else if (!len2) | 7647 else if (!len2) |
7126 const_str_n = 2; | 7652 const_str_n = 2; |
7127 | 7653 |
7128 gcc_checking_assert (const_str_n > 0); | 7654 gcc_checking_assert (const_str_n > 0); |
7129 length = (const_str_n == 1) ? len1 : len2; | 7655 length = (const_str_n == 1) ? len1 : len2; |
7130 | 7656 |
7131 if (is_ncmp && (len3 = tree_to_uhwi (len3_tree)) < length) | 7657 if (is_ncmp && len3 < length) |
7132 length = len3; | 7658 length = len3; |
7133 | 7659 |
7134 /* If the length of the comparision is larger than the threshold, | 7660 /* If the length of the comparision is larger than the threshold, |
7135 do nothing. */ | 7661 do nothing. */ |
7136 if (length > (unsigned HOST_WIDE_INT) | 7662 if (length > (unsigned HOST_WIDE_INT) |
7137 PARAM_VALUE (BUILTIN_STRING_CMP_INLINE_LENGTH)) | 7663 param_builtin_string_cmp_inline_length) |
7138 return NULL_RTX; | 7664 return NULL_RTX; |
7139 | 7665 |
7140 machine_mode mode = TYPE_MODE (TREE_TYPE (exp)); | 7666 machine_mode mode = TYPE_MODE (TREE_TYPE (exp)); |
7141 | 7667 |
7142 /* Now, start inline expansion the call. */ | 7668 /* Now, start inline expansion the call. */ |
7203 rtx | 7729 rtx |
7204 expand_builtin (tree exp, rtx target, rtx subtarget, machine_mode mode, | 7730 expand_builtin (tree exp, rtx target, rtx subtarget, machine_mode mode, |
7205 int ignore) | 7731 int ignore) |
7206 { | 7732 { |
7207 tree fndecl = get_callee_fndecl (exp); | 7733 tree fndecl = get_callee_fndecl (exp); |
7208 enum built_in_function fcode = DECL_FUNCTION_CODE (fndecl); | |
7209 machine_mode target_mode = TYPE_MODE (TREE_TYPE (exp)); | 7734 machine_mode target_mode = TYPE_MODE (TREE_TYPE (exp)); |
7210 int flags; | 7735 int flags; |
7211 | 7736 |
7212 if (DECL_BUILT_IN_CLASS (fndecl) == BUILT_IN_MD) | 7737 if (DECL_BUILT_IN_CLASS (fndecl) == BUILT_IN_MD) |
7213 return targetm.expand_builtin (exp, target, subtarget, mode, ignore); | 7738 return targetm.expand_builtin (exp, target, subtarget, mode, ignore); |
7215 /* When ASan is enabled, we don't want to expand some memory/string | 7740 /* When ASan is enabled, we don't want to expand some memory/string |
7216 builtins and rely on libsanitizer's hooks. This allows us to avoid | 7741 builtins and rely on libsanitizer's hooks. This allows us to avoid |
7217 redundant checks and be sure, that possible overflow will be detected | 7742 redundant checks and be sure, that possible overflow will be detected |
7218 by ASan. */ | 7743 by ASan. */ |
7219 | 7744 |
7745 enum built_in_function fcode = DECL_FUNCTION_CODE (fndecl); | |
7220 if ((flag_sanitize & SANITIZE_ADDRESS) && asan_intercepted_p (fcode)) | 7746 if ((flag_sanitize & SANITIZE_ADDRESS) && asan_intercepted_p (fcode)) |
7221 return expand_call (exp, target, ignore); | 7747 return expand_call (exp, target, ignore); |
7222 | 7748 |
7223 /* When not optimizing, generate calls to library functions for a certain | 7749 /* When not optimizing, generate calls to library functions for a certain |
7224 set of builtins. */ | 7750 set of builtins. */ |
7522 if (target) | 8048 if (target) |
7523 return target; | 8049 return target; |
7524 break; | 8050 break; |
7525 | 8051 |
7526 case BUILT_IN_STRCAT: | 8052 case BUILT_IN_STRCAT: |
7527 target = expand_builtin_strcat (exp, target); | 8053 target = expand_builtin_strcat (exp); |
7528 if (target) | 8054 if (target) |
7529 return target; | 8055 return target; |
8056 break; | |
8057 | |
8058 case BUILT_IN_GETTEXT: | |
8059 case BUILT_IN_PUTS: | |
8060 case BUILT_IN_PUTS_UNLOCKED: | |
8061 case BUILT_IN_STRDUP: | |
8062 if (validate_arglist (exp, POINTER_TYPE, VOID_TYPE)) | |
8063 check_nul_terminated_array (exp, CALL_EXPR_ARG (exp, 0)); | |
8064 break; | |
8065 | |
8066 case BUILT_IN_INDEX: | |
8067 case BUILT_IN_RINDEX: | |
8068 case BUILT_IN_STRCHR: | |
8069 case BUILT_IN_STRRCHR: | |
8070 if (validate_arglist (exp, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE)) | |
8071 check_nul_terminated_array (exp, CALL_EXPR_ARG (exp, 0)); | |
8072 break; | |
8073 | |
8074 case BUILT_IN_FPUTS: | |
8075 case BUILT_IN_FPUTS_UNLOCKED: | |
8076 if (validate_arglist (exp, POINTER_TYPE, POINTER_TYPE, VOID_TYPE)) | |
8077 check_nul_terminated_array (exp, CALL_EXPR_ARG (exp, 0)); | |
8078 break; | |
8079 | |
8080 case BUILT_IN_STRNDUP: | |
8081 if (validate_arglist (exp, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE)) | |
8082 check_nul_terminated_array (exp, | |
8083 CALL_EXPR_ARG (exp, 0), | |
8084 CALL_EXPR_ARG (exp, 1)); | |
8085 break; | |
8086 | |
8087 case BUILT_IN_STRCASECMP: | |
8088 case BUILT_IN_STRSTR: | |
8089 if (validate_arglist (exp, POINTER_TYPE, POINTER_TYPE, VOID_TYPE)) | |
8090 { | |
8091 check_nul_terminated_array (exp, CALL_EXPR_ARG (exp, 0)); | |
8092 check_nul_terminated_array (exp, CALL_EXPR_ARG (exp, 1)); | |
8093 } | |
7530 break; | 8094 break; |
7531 | 8095 |
7532 case BUILT_IN_STRCPY: | 8096 case BUILT_IN_STRCPY: |
7533 target = expand_builtin_strcpy (exp, target); | 8097 target = expand_builtin_strcpy (exp, target); |
7534 if (target) | 8098 if (target) |
8562 { | 9126 { |
8563 if (!validate_arg (arg, POINTER_TYPE)) | 9127 if (!validate_arg (arg, POINTER_TYPE)) |
8564 return NULL_TREE; | 9128 return NULL_TREE; |
8565 else | 9129 else |
8566 { | 9130 { |
8567 c_strlen_data data; | 9131 c_strlen_data lendata = { }; |
8568 memset (&data, 0, sizeof (c_strlen_data)); | 9132 tree len = c_strlen (arg, 0, &lendata); |
8569 tree len = c_strlen (arg, 0, &data); | |
8570 | 9133 |
8571 if (len) | 9134 if (len) |
8572 return fold_convert_loc (loc, type, len); | 9135 return fold_convert_loc (loc, type, len); |
8573 | 9136 |
8574 if (!data.decl) | 9137 if (!lendata.decl) |
8575 c_strlen (arg, 1, &data); | 9138 c_strlen (arg, 1, &lendata); |
8576 | 9139 |
8577 if (data.decl) | 9140 if (lendata.decl) |
8578 { | 9141 { |
8579 if (EXPR_HAS_LOCATION (arg)) | 9142 if (EXPR_HAS_LOCATION (arg)) |
8580 loc = EXPR_LOCATION (arg); | 9143 loc = EXPR_LOCATION (arg); |
8581 else if (loc == UNKNOWN_LOCATION) | 9144 else if (loc == UNKNOWN_LOCATION) |
8582 loc = input_location; | 9145 loc = input_location; |
8583 warn_string_no_nul (loc, "strlen", arg, data.decl); | 9146 warn_string_no_nul (loc, "strlen", arg, lendata.decl); |
8584 } | 9147 } |
8585 | 9148 |
8586 return NULL_TREE; | 9149 return NULL_TREE; |
8587 } | 9150 } |
8588 } | 9151 } |
8958 only. The low-order value is not significant. */ | 9521 only. The low-order value is not significant. */ |
8959 type = double_type_node; | 9522 type = double_type_node; |
8960 mode = DFmode; | 9523 mode = DFmode; |
8961 arg = fold_build1_loc (loc, NOP_EXPR, type, arg); | 9524 arg = fold_build1_loc (loc, NOP_EXPR, type, arg); |
8962 } | 9525 } |
8963 get_max_float (REAL_MODE_FORMAT (mode), buf, sizeof (buf)); | 9526 get_max_float (REAL_MODE_FORMAT (mode), buf, sizeof (buf), false); |
8964 real_from_string (&r, buf); | 9527 real_from_string (&r, buf); |
8965 result = build_call_expr (isgr_fn, 2, | 9528 result = build_call_expr (isgr_fn, 2, |
8966 fold_build1_loc (loc, ABS_EXPR, type, arg), | 9529 fold_build1_loc (loc, ABS_EXPR, type, arg), |
8967 build_real (type, r)); | 9530 build_real (type, r)); |
8968 return result; | 9531 return result; |
8982 only. The low-order value is not significant. */ | 9545 only. The low-order value is not significant. */ |
8983 type = double_type_node; | 9546 type = double_type_node; |
8984 mode = DFmode; | 9547 mode = DFmode; |
8985 arg = fold_build1_loc (loc, NOP_EXPR, type, arg); | 9548 arg = fold_build1_loc (loc, NOP_EXPR, type, arg); |
8986 } | 9549 } |
8987 get_max_float (REAL_MODE_FORMAT (mode), buf, sizeof (buf)); | 9550 get_max_float (REAL_MODE_FORMAT (mode), buf, sizeof (buf), false); |
8988 real_from_string (&r, buf); | 9551 real_from_string (&r, buf); |
8989 result = build_call_expr (isle_fn, 2, | 9552 result = build_call_expr (isle_fn, 2, |
8990 fold_build1_loc (loc, ABS_EXPR, type, arg), | 9553 fold_build1_loc (loc, ABS_EXPR, type, arg), |
8991 build_real (type, r)); | 9554 build_real (type, r)); |
8992 /*result = fold_build2_loc (loc, UNGT_EXPR, | 9555 /*result = fold_build2_loc (loc, UNGT_EXPR, |
9021 mode = DFmode; | 9584 mode = DFmode; |
9022 arg = fold_build1_loc (loc, NOP_EXPR, type, arg); | 9585 arg = fold_build1_loc (loc, NOP_EXPR, type, arg); |
9023 } | 9586 } |
9024 arg = fold_build1_loc (loc, ABS_EXPR, type, arg); | 9587 arg = fold_build1_loc (loc, ABS_EXPR, type, arg); |
9025 | 9588 |
9026 get_max_float (REAL_MODE_FORMAT (mode), buf, sizeof (buf)); | 9589 get_max_float (REAL_MODE_FORMAT (mode), buf, sizeof (buf), false); |
9027 real_from_string (&rmax, buf); | 9590 real_from_string (&rmax, buf); |
9028 sprintf (buf, "0x1p%d", REAL_MODE_FORMAT (orig_mode)->emin - 1); | 9591 sprintf (buf, "0x1p%d", REAL_MODE_FORMAT (orig_mode)->emin - 1); |
9029 real_from_string (&rmin, buf); | 9592 real_from_string (&rmin, buf); |
9030 max_exp = build_real (type, rmax); | 9593 max_exp = build_real (type, rmax); |
9031 min_exp = build_real (type, rmin); | 9594 min_exp = build_real (type, rmin); |
9288 static tree | 9851 static tree |
9289 fold_builtin_arith_overflow (location_t loc, enum built_in_function fcode, | 9852 fold_builtin_arith_overflow (location_t loc, enum built_in_function fcode, |
9290 tree arg0, tree arg1, tree arg2) | 9853 tree arg0, tree arg1, tree arg2) |
9291 { | 9854 { |
9292 enum internal_fn ifn = IFN_LAST; | 9855 enum internal_fn ifn = IFN_LAST; |
9293 /* The code of the expression corresponding to the type-generic | 9856 /* The code of the expression corresponding to the built-in. */ |
9294 built-in, or ERROR_MARK for the type-specific ones. */ | |
9295 enum tree_code opcode = ERROR_MARK; | 9857 enum tree_code opcode = ERROR_MARK; |
9296 bool ovf_only = false; | 9858 bool ovf_only = false; |
9297 | 9859 |
9298 switch (fcode) | 9860 switch (fcode) |
9299 { | 9861 { |
9300 case BUILT_IN_ADD_OVERFLOW_P: | 9862 case BUILT_IN_ADD_OVERFLOW_P: |
9301 ovf_only = true; | 9863 ovf_only = true; |
9302 /* FALLTHRU */ | 9864 /* FALLTHRU */ |
9303 case BUILT_IN_ADD_OVERFLOW: | 9865 case BUILT_IN_ADD_OVERFLOW: |
9304 opcode = PLUS_EXPR; | |
9305 /* FALLTHRU */ | |
9306 case BUILT_IN_SADD_OVERFLOW: | 9866 case BUILT_IN_SADD_OVERFLOW: |
9307 case BUILT_IN_SADDL_OVERFLOW: | 9867 case BUILT_IN_SADDL_OVERFLOW: |
9308 case BUILT_IN_SADDLL_OVERFLOW: | 9868 case BUILT_IN_SADDLL_OVERFLOW: |
9309 case BUILT_IN_UADD_OVERFLOW: | 9869 case BUILT_IN_UADD_OVERFLOW: |
9310 case BUILT_IN_UADDL_OVERFLOW: | 9870 case BUILT_IN_UADDL_OVERFLOW: |
9311 case BUILT_IN_UADDLL_OVERFLOW: | 9871 case BUILT_IN_UADDLL_OVERFLOW: |
9872 opcode = PLUS_EXPR; | |
9312 ifn = IFN_ADD_OVERFLOW; | 9873 ifn = IFN_ADD_OVERFLOW; |
9313 break; | 9874 break; |
9314 case BUILT_IN_SUB_OVERFLOW_P: | 9875 case BUILT_IN_SUB_OVERFLOW_P: |
9315 ovf_only = true; | 9876 ovf_only = true; |
9316 /* FALLTHRU */ | 9877 /* FALLTHRU */ |
9317 case BUILT_IN_SUB_OVERFLOW: | 9878 case BUILT_IN_SUB_OVERFLOW: |
9318 opcode = MINUS_EXPR; | |
9319 /* FALLTHRU */ | |
9320 case BUILT_IN_SSUB_OVERFLOW: | 9879 case BUILT_IN_SSUB_OVERFLOW: |
9321 case BUILT_IN_SSUBL_OVERFLOW: | 9880 case BUILT_IN_SSUBL_OVERFLOW: |
9322 case BUILT_IN_SSUBLL_OVERFLOW: | 9881 case BUILT_IN_SSUBLL_OVERFLOW: |
9323 case BUILT_IN_USUB_OVERFLOW: | 9882 case BUILT_IN_USUB_OVERFLOW: |
9324 case BUILT_IN_USUBL_OVERFLOW: | 9883 case BUILT_IN_USUBL_OVERFLOW: |
9325 case BUILT_IN_USUBLL_OVERFLOW: | 9884 case BUILT_IN_USUBLL_OVERFLOW: |
9885 opcode = MINUS_EXPR; | |
9326 ifn = IFN_SUB_OVERFLOW; | 9886 ifn = IFN_SUB_OVERFLOW; |
9327 break; | 9887 break; |
9328 case BUILT_IN_MUL_OVERFLOW_P: | 9888 case BUILT_IN_MUL_OVERFLOW_P: |
9329 ovf_only = true; | 9889 ovf_only = true; |
9330 /* FALLTHRU */ | 9890 /* FALLTHRU */ |
9331 case BUILT_IN_MUL_OVERFLOW: | 9891 case BUILT_IN_MUL_OVERFLOW: |
9332 opcode = MULT_EXPR; | |
9333 /* FALLTHRU */ | |
9334 case BUILT_IN_SMUL_OVERFLOW: | 9892 case BUILT_IN_SMUL_OVERFLOW: |
9335 case BUILT_IN_SMULL_OVERFLOW: | 9893 case BUILT_IN_SMULL_OVERFLOW: |
9336 case BUILT_IN_SMULLL_OVERFLOW: | 9894 case BUILT_IN_SMULLL_OVERFLOW: |
9337 case BUILT_IN_UMUL_OVERFLOW: | 9895 case BUILT_IN_UMUL_OVERFLOW: |
9338 case BUILT_IN_UMULL_OVERFLOW: | 9896 case BUILT_IN_UMULL_OVERFLOW: |
9339 case BUILT_IN_UMULLL_OVERFLOW: | 9897 case BUILT_IN_UMULLL_OVERFLOW: |
9898 opcode = MULT_EXPR; | |
9340 ifn = IFN_MUL_OVERFLOW; | 9899 ifn = IFN_MUL_OVERFLOW; |
9341 break; | 9900 break; |
9342 default: | 9901 default: |
9343 gcc_unreachable (); | 9902 gcc_unreachable (); |
9344 } | 9903 } |
9359 return omit_one_operand_loc (loc, boolean_type_node, | 9918 return omit_one_operand_loc (loc, boolean_type_node, |
9360 arith_overflowed_p (opcode, type, arg0, arg1) | 9919 arith_overflowed_p (opcode, type, arg0, arg1) |
9361 ? boolean_true_node : boolean_false_node, | 9920 ? boolean_true_node : boolean_false_node, |
9362 arg2); | 9921 arg2); |
9363 | 9922 |
9364 tree ctype = build_complex_type (type); | 9923 tree intres, ovfres; |
9365 tree call = build_call_expr_internal_loc (loc, ifn, ctype, | 9924 if (TREE_CODE (arg0) == INTEGER_CST && TREE_CODE (arg1) == INTEGER_CST) |
9366 2, arg0, arg1); | 9925 { |
9367 tree tgt = save_expr (call); | 9926 intres = fold_binary_loc (loc, opcode, type, |
9368 tree intres = build1_loc (loc, REALPART_EXPR, type, tgt); | 9927 fold_convert_loc (loc, type, arg0), |
9369 tree ovfres = build1_loc (loc, IMAGPART_EXPR, type, tgt); | 9928 fold_convert_loc (loc, type, arg1)); |
9370 ovfres = fold_convert_loc (loc, boolean_type_node, ovfres); | 9929 if (TREE_OVERFLOW (intres)) |
9930 intres = drop_tree_overflow (intres); | |
9931 ovfres = (arith_overflowed_p (opcode, type, arg0, arg1) | |
9932 ? boolean_true_node : boolean_false_node); | |
9933 } | |
9934 else | |
9935 { | |
9936 tree ctype = build_complex_type (type); | |
9937 tree call = build_call_expr_internal_loc (loc, ifn, ctype, 2, | |
9938 arg0, arg1); | |
9939 tree tgt = save_expr (call); | |
9940 intres = build1_loc (loc, REALPART_EXPR, type, tgt); | |
9941 ovfres = build1_loc (loc, IMAGPART_EXPR, type, tgt); | |
9942 ovfres = fold_convert_loc (loc, boolean_type_node, ovfres); | |
9943 } | |
9371 | 9944 |
9372 if (ovf_only) | 9945 if (ovf_only) |
9373 return omit_one_operand_loc (loc, boolean_type_node, ovfres, arg2); | 9946 return omit_one_operand_loc (loc, boolean_type_node, ovfres, arg2); |
9374 | 9947 |
9375 tree mem_arg2 = build_fold_indirect_ref_loc (loc, arg2); | 9948 tree mem_arg2 = build_fold_indirect_ref_loc (loc, arg2); |
9580 | 10153 |
9581 return NULL_TREE; | 10154 return NULL_TREE; |
9582 | 10155 |
9583 } | 10156 } |
9584 | 10157 |
9585 /* Fold a call to built-in function FNDECL with 2 arguments, ARG0 and ARG1. | 10158 /* Folds a call EXPR (which may be null) to built-in function FNDECL |
9586 This function returns NULL_TREE if no simplification was possible. */ | 10159 with 2 arguments, ARG0 and ARG1. This function returns NULL_TREE |
10160 if no simplification was possible. */ | |
9587 | 10161 |
9588 static tree | 10162 static tree |
9589 fold_builtin_2 (location_t loc, tree fndecl, tree arg0, tree arg1) | 10163 fold_builtin_2 (location_t loc, tree expr, tree fndecl, tree arg0, tree arg1) |
9590 { | 10164 { |
9591 tree type = TREE_TYPE (TREE_TYPE (fndecl)); | 10165 tree type = TREE_TYPE (TREE_TYPE (fndecl)); |
9592 enum built_in_function fcode = DECL_FUNCTION_CODE (fndecl); | 10166 enum built_in_function fcode = DECL_FUNCTION_CODE (fndecl); |
9593 | 10167 |
9594 if (TREE_CODE (arg0) == ERROR_MARK | 10168 if (TREE_CODE (arg0) == ERROR_MARK |
9612 | 10186 |
9613 CASE_FLT_FN (BUILT_IN_MODF): | 10187 CASE_FLT_FN (BUILT_IN_MODF): |
9614 return fold_builtin_modf (loc, arg0, arg1, type); | 10188 return fold_builtin_modf (loc, arg0, arg1, type); |
9615 | 10189 |
9616 case BUILT_IN_STRSPN: | 10190 case BUILT_IN_STRSPN: |
9617 return fold_builtin_strspn (loc, arg0, arg1); | 10191 return fold_builtin_strspn (loc, expr, arg0, arg1); |
9618 | 10192 |
9619 case BUILT_IN_STRCSPN: | 10193 case BUILT_IN_STRCSPN: |
9620 return fold_builtin_strcspn (loc, arg0, arg1); | 10194 return fold_builtin_strcspn (loc, expr, arg0, arg1); |
9621 | 10195 |
9622 case BUILT_IN_STRPBRK: | 10196 case BUILT_IN_STRPBRK: |
9623 return fold_builtin_strpbrk (loc, arg0, arg1, type); | 10197 return fold_builtin_strpbrk (loc, expr, arg0, arg1, type); |
9624 | 10198 |
9625 case BUILT_IN_EXPECT: | 10199 case BUILT_IN_EXPECT: |
9626 return fold_builtin_expect (loc, arg0, arg1, NULL_TREE, NULL_TREE); | 10200 return fold_builtin_expect (loc, arg0, arg1, NULL_TREE, NULL_TREE); |
9627 | 10201 |
9628 case BUILT_IN_ISGREATER: | 10202 case BUILT_IN_ISGREATER: |
9736 break; | 10310 break; |
9737 } | 10311 } |
9738 return NULL_TREE; | 10312 return NULL_TREE; |
9739 } | 10313 } |
9740 | 10314 |
9741 /* Fold a call to built-in function FNDECL. ARGS is an array of NARGS | 10315 /* Folds a call EXPR (which may be null) to built-in function FNDECL. |
9742 arguments. IGNORE is true if the result of the | 10316 ARGS is an array of NARGS arguments. IGNORE is true if the result |
9743 function call is ignored. This function returns NULL_TREE if no | 10317 of the function call is ignored. This function returns NULL_TREE |
9744 simplification was possible. */ | 10318 if no simplification was possible. */ |
9745 | 10319 |
9746 tree | 10320 static tree |
9747 fold_builtin_n (location_t loc, tree fndecl, tree *args, int nargs, bool) | 10321 fold_builtin_n (location_t loc, tree expr, tree fndecl, tree *args, |
10322 int nargs, bool) | |
9748 { | 10323 { |
9749 tree ret = NULL_TREE; | 10324 tree ret = NULL_TREE; |
9750 | 10325 |
9751 switch (nargs) | 10326 switch (nargs) |
9752 { | 10327 { |
9755 break; | 10330 break; |
9756 case 1: | 10331 case 1: |
9757 ret = fold_builtin_1 (loc, fndecl, args[0]); | 10332 ret = fold_builtin_1 (loc, fndecl, args[0]); |
9758 break; | 10333 break; |
9759 case 2: | 10334 case 2: |
9760 ret = fold_builtin_2 (loc, fndecl, args[0], args[1]); | 10335 ret = fold_builtin_2 (loc, expr, fndecl, args[0], args[1]); |
9761 break; | 10336 break; |
9762 case 3: | 10337 case 3: |
9763 ret = fold_builtin_3 (loc, fndecl, args[0], args[1], args[2]); | 10338 ret = fold_builtin_3 (loc, fndecl, args[0], args[1], args[2]); |
9764 break; | 10339 break; |
9765 default: | 10340 default: |
9853 return targetm.fold_builtin (fndecl, call_expr_nargs (exp), | 10428 return targetm.fold_builtin (fndecl, call_expr_nargs (exp), |
9854 CALL_EXPR_ARGP (exp), ignore); | 10429 CALL_EXPR_ARGP (exp), ignore); |
9855 else | 10430 else |
9856 { | 10431 { |
9857 tree *args = CALL_EXPR_ARGP (exp); | 10432 tree *args = CALL_EXPR_ARGP (exp); |
9858 ret = fold_builtin_n (loc, fndecl, args, nargs, ignore); | 10433 ret = fold_builtin_n (loc, exp, fndecl, args, nargs, ignore); |
9859 if (ret) | 10434 if (ret) |
9860 return ret; | 10435 return ret; |
9861 } | 10436 } |
9862 } | 10437 } |
9863 return NULL_TREE; | 10438 return NULL_TREE; |
9891 if (avoid_folding_inline_builtin (fndecl)) | 10466 if (avoid_folding_inline_builtin (fndecl)) |
9892 return NULL_TREE; | 10467 return NULL_TREE; |
9893 if (DECL_BUILT_IN_CLASS (fndecl) == BUILT_IN_MD) | 10468 if (DECL_BUILT_IN_CLASS (fndecl) == BUILT_IN_MD) |
9894 return targetm.fold_builtin (fndecl, n, argarray, false); | 10469 return targetm.fold_builtin (fndecl, n, argarray, false); |
9895 else | 10470 else |
9896 return fold_builtin_n (loc, fndecl, argarray, n, false); | 10471 return fold_builtin_n (loc, NULL_TREE, fndecl, argarray, n, false); |
9897 } | 10472 } |
9898 | 10473 |
9899 return NULL_TREE; | 10474 return NULL_TREE; |
9900 } | 10475 } |
9901 | 10476 |
10043 COMPOUND_EXPRs are chained through their RHS. The RHS of the last | 10618 COMPOUND_EXPRs are chained through their RHS. The RHS of the last |
10044 COMPOUND_EXPR in the chain will contain the tree for the simplified | 10619 COMPOUND_EXPR in the chain will contain the tree for the simplified |
10045 form of the builtin function call. */ | 10620 form of the builtin function call. */ |
10046 | 10621 |
10047 static tree | 10622 static tree |
10048 fold_builtin_strpbrk (location_t loc, tree s1, tree s2, tree type) | 10623 fold_builtin_strpbrk (location_t loc, tree expr, tree s1, tree s2, tree type) |
10049 { | 10624 { |
10050 if (!validate_arg (s1, POINTER_TYPE) | 10625 if (!validate_arg (s1, POINTER_TYPE) |
10051 || !validate_arg (s2, POINTER_TYPE)) | 10626 || !validate_arg (s2, POINTER_TYPE)) |
10052 return NULL_TREE; | 10627 return NULL_TREE; |
10053 else | 10628 |
10054 { | 10629 if (!check_nul_terminated_array (expr, s1) |
10055 tree fn; | 10630 || !check_nul_terminated_array (expr, s2)) |
10056 const char *p1, *p2; | 10631 return NULL_TREE; |
10057 | 10632 |
10058 p2 = c_getstr (s2); | 10633 tree fn; |
10059 if (p2 == NULL) | 10634 const char *p1, *p2; |
10060 return NULL_TREE; | 10635 |
10061 | 10636 p2 = c_getstr (s2); |
10062 p1 = c_getstr (s1); | 10637 if (p2 == NULL) |
10063 if (p1 != NULL) | 10638 return NULL_TREE; |
10064 { | 10639 |
10065 const char *r = strpbrk (p1, p2); | 10640 p1 = c_getstr (s1); |
10066 tree tem; | 10641 if (p1 != NULL) |
10067 | 10642 { |
10068 if (r == NULL) | 10643 const char *r = strpbrk (p1, p2); |
10069 return build_int_cst (TREE_TYPE (s1), 0); | 10644 tree tem; |
10070 | 10645 |
10071 /* Return an offset into the constant string argument. */ | 10646 if (r == NULL) |
10072 tem = fold_build_pointer_plus_hwi_loc (loc, s1, r - p1); | 10647 return build_int_cst (TREE_TYPE (s1), 0); |
10073 return fold_convert_loc (loc, type, tem); | 10648 |
10074 } | 10649 /* Return an offset into the constant string argument. */ |
10075 | 10650 tem = fold_build_pointer_plus_hwi_loc (loc, s1, r - p1); |
10076 if (p2[0] == '\0') | 10651 return fold_convert_loc (loc, type, tem); |
10077 /* strpbrk(x, "") == NULL. | 10652 } |
10078 Evaluate and ignore s1 in case it had side-effects. */ | 10653 |
10079 return omit_one_operand_loc (loc, type, integer_zero_node, s1); | 10654 if (p2[0] == '\0') |
10080 | 10655 /* strpbrk(x, "") == NULL. |
10081 if (p2[1] != '\0') | 10656 Evaluate and ignore s1 in case it had side-effects. */ |
10082 return NULL_TREE; /* Really call strpbrk. */ | 10657 return omit_one_operand_loc (loc, type, integer_zero_node, s1); |
10083 | 10658 |
10084 fn = builtin_decl_implicit (BUILT_IN_STRCHR); | 10659 if (p2[1] != '\0') |
10085 if (!fn) | 10660 return NULL_TREE; /* Really call strpbrk. */ |
10086 return NULL_TREE; | 10661 |
10087 | 10662 fn = builtin_decl_implicit (BUILT_IN_STRCHR); |
10088 /* New argument list transforming strpbrk(s1, s2) to | 10663 if (!fn) |
10089 strchr(s1, s2[0]). */ | 10664 return NULL_TREE; |
10090 return build_call_expr_loc (loc, fn, 2, s1, | 10665 |
10091 build_int_cst (integer_type_node, p2[0])); | 10666 /* New argument list transforming strpbrk(s1, s2) to |
10092 } | 10667 strchr(s1, s2[0]). */ |
10668 return build_call_expr_loc (loc, fn, 2, s1, | |
10669 build_int_cst (integer_type_node, p2[0])); | |
10093 } | 10670 } |
10094 | 10671 |
10095 /* Simplify a call to the strspn builtin. S1 and S2 are the arguments | 10672 /* Simplify a call to the strspn builtin. S1 and S2 are the arguments |
10096 to the call. | 10673 to the call. |
10097 | 10674 |
10109 COMPOUND_EXPRs are chained through their RHS. The RHS of the last | 10686 COMPOUND_EXPRs are chained through their RHS. The RHS of the last |
10110 COMPOUND_EXPR in the chain will contain the tree for the simplified | 10687 COMPOUND_EXPR in the chain will contain the tree for the simplified |
10111 form of the builtin function call. */ | 10688 form of the builtin function call. */ |
10112 | 10689 |
10113 static tree | 10690 static tree |
10114 fold_builtin_strspn (location_t loc, tree s1, tree s2) | 10691 fold_builtin_strspn (location_t loc, tree expr, tree s1, tree s2) |
10115 { | 10692 { |
10116 if (!validate_arg (s1, POINTER_TYPE) | 10693 if (!validate_arg (s1, POINTER_TYPE) |
10117 || !validate_arg (s2, POINTER_TYPE)) | 10694 || !validate_arg (s2, POINTER_TYPE)) |
10118 return NULL_TREE; | 10695 return NULL_TREE; |
10119 else | 10696 |
10120 { | 10697 if (!check_nul_terminated_array (expr, s1) |
10121 const char *p1 = c_getstr (s1), *p2 = c_getstr (s2); | 10698 || !check_nul_terminated_array (expr, s2)) |
10122 | 10699 return NULL_TREE; |
10123 /* If either argument is "", return NULL_TREE. */ | 10700 |
10124 if ((p1 && *p1 == '\0') || (p2 && *p2 == '\0')) | 10701 const char *p1 = c_getstr (s1), *p2 = c_getstr (s2); |
10125 /* Evaluate and ignore both arguments in case either one has | 10702 |
10126 side-effects. */ | 10703 /* If either argument is "", return NULL_TREE. */ |
10127 return omit_two_operands_loc (loc, size_type_node, size_zero_node, | 10704 if ((p1 && *p1 == '\0') || (p2 && *p2 == '\0')) |
10705 /* Evaluate and ignore both arguments in case either one has | |
10706 side-effects. */ | |
10707 return omit_two_operands_loc (loc, size_type_node, size_zero_node, | |
10128 s1, s2); | 10708 s1, s2); |
10129 return NULL_TREE; | 10709 return NULL_TREE; |
10130 } | |
10131 } | 10710 } |
10132 | 10711 |
10133 /* Simplify a call to the strcspn builtin. S1 and S2 are the arguments | 10712 /* Simplify a call to the strcspn builtin. S1 and S2 are the arguments |
10134 to the call. | 10713 to the call. |
10135 | 10714 |
10147 COMPOUND_EXPRs are chained through their RHS. The RHS of the last | 10726 COMPOUND_EXPRs are chained through their RHS. The RHS of the last |
10148 COMPOUND_EXPR in the chain will contain the tree for the simplified | 10727 COMPOUND_EXPR in the chain will contain the tree for the simplified |
10149 form of the builtin function call. */ | 10728 form of the builtin function call. */ |
10150 | 10729 |
10151 static tree | 10730 static tree |
10152 fold_builtin_strcspn (location_t loc, tree s1, tree s2) | 10731 fold_builtin_strcspn (location_t loc, tree expr, tree s1, tree s2) |
10153 { | 10732 { |
10154 if (!validate_arg (s1, POINTER_TYPE) | 10733 if (!validate_arg (s1, POINTER_TYPE) |
10155 || !validate_arg (s2, POINTER_TYPE)) | 10734 || !validate_arg (s2, POINTER_TYPE)) |
10156 return NULL_TREE; | 10735 return NULL_TREE; |
10157 else | 10736 |
10158 { | 10737 if (!check_nul_terminated_array (expr, s1) |
10159 /* If the first argument is "", return NULL_TREE. */ | 10738 || !check_nul_terminated_array (expr, s2)) |
10160 const char *p1 = c_getstr (s1); | 10739 return NULL_TREE; |
10161 if (p1 && *p1 == '\0') | 10740 |
10162 { | 10741 /* If the first argument is "", return NULL_TREE. */ |
10163 /* Evaluate and ignore argument s2 in case it has | 10742 const char *p1 = c_getstr (s1); |
10164 side-effects. */ | 10743 if (p1 && *p1 == '\0') |
10165 return omit_one_operand_loc (loc, size_type_node, | 10744 { |
10745 /* Evaluate and ignore argument s2 in case it has | |
10746 side-effects. */ | |
10747 return omit_one_operand_loc (loc, size_type_node, | |
10166 size_zero_node, s2); | 10748 size_zero_node, s2); |
10167 } | 10749 } |
10168 | 10750 |
10169 /* If the second argument is "", return __builtin_strlen(s1). */ | 10751 /* If the second argument is "", return __builtin_strlen(s1). */ |
10170 const char *p2 = c_getstr (s2); | 10752 const char *p2 = c_getstr (s2); |
10171 if (p2 && *p2 == '\0') | 10753 if (p2 && *p2 == '\0') |
10172 { | 10754 { |
10173 tree fn = builtin_decl_implicit (BUILT_IN_STRLEN); | 10755 tree fn = builtin_decl_implicit (BUILT_IN_STRLEN); |
10174 | 10756 |
10175 /* If the replacement _DECL isn't initialized, don't do the | 10757 /* If the replacement _DECL isn't initialized, don't do the |
10176 transformation. */ | 10758 transformation. */ |
10177 if (!fn) | 10759 if (!fn) |
10178 return NULL_TREE; | 10760 return NULL_TREE; |
10179 | 10761 |
10180 return build_call_expr_loc (loc, fn, 1, s1); | 10762 return build_call_expr_loc (loc, fn, 1, s1); |
10181 } | 10763 } |
10182 return NULL_TREE; | 10764 return NULL_TREE; |
10183 } | |
10184 } | 10765 } |
10185 | 10766 |
10186 /* Fold the next_arg or va_start call EXP. Returns true if there was an error | 10767 /* Fold the next_arg or va_start call EXP. Returns true if there was an error |
10187 produced. False otherwise. This is done so that we don't output the error | 10768 produced. False otherwise. This is done so that we don't output the error |
10188 or warning twice or three times. */ | 10769 or warning twice or three times. */ |
10195 tree arg; | 10776 tree arg; |
10196 /* There is good chance the current input_location points inside the | 10777 /* There is good chance the current input_location points inside the |
10197 definition of the va_start macro (perhaps on the token for | 10778 definition of the va_start macro (perhaps on the token for |
10198 builtin) in a system header, so warnings will not be emitted. | 10779 builtin) in a system header, so warnings will not be emitted. |
10199 Use the location in real source code. */ | 10780 Use the location in real source code. */ |
10200 source_location current_location = | 10781 location_t current_location = |
10201 linemap_unwind_to_first_non_reserved_loc (line_table, input_location, | 10782 linemap_unwind_to_first_non_reserved_loc (line_table, input_location, |
10202 NULL); | 10783 NULL); |
10203 | 10784 |
10204 if (!stdarg_p (fntype)) | 10785 if (!stdarg_p (fntype)) |
10205 { | 10786 { |
10206 error ("%<va_start%> used in function with fixed args"); | 10787 error ("%<va_start%> used in function with fixed arguments"); |
10207 return true; | 10788 return true; |
10208 } | 10789 } |
10209 | 10790 |
10210 if (va_start_p) | 10791 if (va_start_p) |
10211 { | 10792 { |
10580 /* Emit warning if a free is called with address of a variable. */ | 11161 /* Emit warning if a free is called with address of a variable. */ |
10581 | 11162 |
10582 static void | 11163 static void |
10583 maybe_emit_free_warning (tree exp) | 11164 maybe_emit_free_warning (tree exp) |
10584 { | 11165 { |
11166 if (call_expr_nargs (exp) != 1) | |
11167 return; | |
11168 | |
10585 tree arg = CALL_EXPR_ARG (exp, 0); | 11169 tree arg = CALL_EXPR_ARG (exp, 0); |
10586 | 11170 |
10587 STRIP_NOPS (arg); | 11171 STRIP_NOPS (arg); |
10588 if (TREE_CODE (arg) != ADDR_EXPR) | 11172 if (TREE_CODE (arg) != ADDR_EXPR) |
10589 return; | 11173 return; |
10728 if (mpfr_number_p (m) && !mpfr_overflow_p () && !mpfr_underflow_p () | 11312 if (mpfr_number_p (m) && !mpfr_overflow_p () && !mpfr_underflow_p () |
10729 && (!flag_rounding_math || !inexact)) | 11313 && (!flag_rounding_math || !inexact)) |
10730 { | 11314 { |
10731 REAL_VALUE_TYPE rr; | 11315 REAL_VALUE_TYPE rr; |
10732 | 11316 |
10733 real_from_mpfr (&rr, m, type, GMP_RNDN); | 11317 real_from_mpfr (&rr, m, type, MPFR_RNDN); |
10734 /* Proceed iff GCC's REAL_VALUE_TYPE can hold the MPFR value, | 11318 /* Proceed iff GCC's REAL_VALUE_TYPE can hold the MPFR value, |
10735 check for overflow/underflow. If the REAL_VALUE_TYPE is zero | 11319 check for overflow/underflow. If the REAL_VALUE_TYPE is zero |
10736 but the mpft_t is not, then we underflowed in the | 11320 but the mpft_t is not, then we underflowed in the |
10737 conversion. */ | 11321 conversion. */ |
10738 if (real_isfinite (&rr) | 11322 if (real_isfinite (&rr) |
10768 && !mpfr_overflow_p () && !mpfr_underflow_p () | 11352 && !mpfr_overflow_p () && !mpfr_underflow_p () |
10769 && (!flag_rounding_math || !inexact))) | 11353 && (!flag_rounding_math || !inexact))) |
10770 { | 11354 { |
10771 REAL_VALUE_TYPE re, im; | 11355 REAL_VALUE_TYPE re, im; |
10772 | 11356 |
10773 real_from_mpfr (&re, mpc_realref (m), TREE_TYPE (type), GMP_RNDN); | 11357 real_from_mpfr (&re, mpc_realref (m), TREE_TYPE (type), MPFR_RNDN); |
10774 real_from_mpfr (&im, mpc_imagref (m), TREE_TYPE (type), GMP_RNDN); | 11358 real_from_mpfr (&im, mpc_imagref (m), TREE_TYPE (type), MPFR_RNDN); |
10775 /* Proceed iff GCC's REAL_VALUE_TYPE can hold the MPFR values, | 11359 /* Proceed iff GCC's REAL_VALUE_TYPE can hold the MPFR values, |
10776 check for overflow/underflow. If the REAL_VALUE_TYPE is zero | 11360 check for overflow/underflow. If the REAL_VALUE_TYPE is zero |
10777 but the mpft_t is not, then we underflowed in the | 11361 but the mpft_t is not, then we underflowed in the |
10778 conversion. */ | 11362 conversion. */ |
10779 if (force_convert | 11363 if (force_convert |
10821 | 11405 |
10822 if (real_isfinite (ra0) && real_isfinite (ra1)) | 11406 if (real_isfinite (ra0) && real_isfinite (ra1)) |
10823 { | 11407 { |
10824 const struct real_format *fmt = REAL_MODE_FORMAT (TYPE_MODE (type)); | 11408 const struct real_format *fmt = REAL_MODE_FORMAT (TYPE_MODE (type)); |
10825 const int prec = fmt->p; | 11409 const int prec = fmt->p; |
10826 const mp_rnd_t rnd = fmt->round_towards_zero? GMP_RNDZ : GMP_RNDN; | 11410 const mpfr_rnd_t rnd = fmt->round_towards_zero? MPFR_RNDZ : MPFR_RNDN; |
10827 tree result_rem; | 11411 tree result_rem; |
10828 long integer_quo; | 11412 long integer_quo; |
10829 mpfr_t m0, m1; | 11413 mpfr_t m0, m1; |
10830 | 11414 |
10831 mpfr_inits2 (prec, m0, m1, NULL); | 11415 mpfr_inits2 (prec, m0, m1, NULL); |
10832 mpfr_from_real (m0, ra0, GMP_RNDN); | 11416 mpfr_from_real (m0, ra0, MPFR_RNDN); |
10833 mpfr_from_real (m1, ra1, GMP_RNDN); | 11417 mpfr_from_real (m1, ra1, MPFR_RNDN); |
10834 mpfr_clear_flags (); | 11418 mpfr_clear_flags (); |
10835 mpfr_remquo (m0, &integer_quo, m0, m1, rnd); | 11419 mpfr_remquo (m0, &integer_quo, m0, m1, rnd); |
10836 /* Remquo is independent of the rounding mode, so pass | 11420 /* Remquo is independent of the rounding mode, so pass |
10837 inexact=0 to do_mpfr_ckconv(). */ | 11421 inexact=0 to do_mpfr_ckconv(). */ |
10838 result_rem = do_mpfr_ckconv (m0, type, /*inexact=*/ 0); | 11422 result_rem = do_mpfr_ckconv (m0, type, /*inexact=*/ 0); |
10901 && ra->cl != rvc_zero | 11485 && ra->cl != rvc_zero |
10902 && !(real_isneg (ra) && real_isinteger (ra, TYPE_MODE (type)))) | 11486 && !(real_isneg (ra) && real_isinteger (ra, TYPE_MODE (type)))) |
10903 { | 11487 { |
10904 const struct real_format *fmt = REAL_MODE_FORMAT (TYPE_MODE (type)); | 11488 const struct real_format *fmt = REAL_MODE_FORMAT (TYPE_MODE (type)); |
10905 const int prec = fmt->p; | 11489 const int prec = fmt->p; |
10906 const mp_rnd_t rnd = fmt->round_towards_zero? GMP_RNDZ : GMP_RNDN; | 11490 const mpfr_rnd_t rnd = fmt->round_towards_zero? MPFR_RNDZ : MPFR_RNDN; |
10907 int inexact, sg; | 11491 int inexact, sg; |
10908 mpfr_t m; | 11492 mpfr_t m; |
10909 tree result_lg; | 11493 tree result_lg; |
10910 | 11494 |
10911 mpfr_init2 (m, prec); | 11495 mpfr_init2 (m, prec); |
10912 mpfr_from_real (m, ra, GMP_RNDN); | 11496 mpfr_from_real (m, ra, MPFR_RNDN); |
10913 mpfr_clear_flags (); | 11497 mpfr_clear_flags (); |
10914 inexact = mpfr_lgamma (m, &sg, m, rnd); | 11498 inexact = mpfr_lgamma (m, &sg, m, rnd); |
10915 result_lg = do_mpfr_ckconv (m, type, inexact); | 11499 result_lg = do_mpfr_ckconv (m, type, inexact); |
10916 mpfr_clear (m); | 11500 mpfr_clear (m); |
10917 if (result_lg) | 11501 if (result_lg) |
10970 && real_isfinite (re1) && real_isfinite (im1))) | 11554 && real_isfinite (re1) && real_isfinite (im1))) |
10971 { | 11555 { |
10972 const struct real_format *const fmt = | 11556 const struct real_format *const fmt = |
10973 REAL_MODE_FORMAT (TYPE_MODE (TREE_TYPE (type))); | 11557 REAL_MODE_FORMAT (TYPE_MODE (TREE_TYPE (type))); |
10974 const int prec = fmt->p; | 11558 const int prec = fmt->p; |
10975 const mp_rnd_t rnd = fmt->round_towards_zero ? GMP_RNDZ : GMP_RNDN; | 11559 const mpfr_rnd_t rnd = fmt->round_towards_zero |
11560 ? MPFR_RNDZ : MPFR_RNDN; | |
10976 const mpc_rnd_t crnd = fmt->round_towards_zero ? MPC_RNDZZ : MPC_RNDNN; | 11561 const mpc_rnd_t crnd = fmt->round_towards_zero ? MPC_RNDZZ : MPC_RNDNN; |
10977 int inexact; | 11562 int inexact; |
10978 mpc_t m0, m1; | 11563 mpc_t m0, m1; |
10979 | 11564 |
10980 mpc_init2 (m0, prec); | 11565 mpc_init2 (m0, prec); |
11018 { | 11603 { |
11019 return targetm.fold_builtin (fndecl, nargs, args, ignore); | 11604 return targetm.fold_builtin (fndecl, nargs, args, ignore); |
11020 } | 11605 } |
11021 else | 11606 else |
11022 { | 11607 { |
11023 ret = fold_builtin_n (loc, fndecl, args, nargs, ignore); | 11608 ret = fold_builtin_n (loc, NULL_TREE, fndecl, args, nargs, ignore); |
11024 if (ret) | 11609 if (ret) |
11025 { | 11610 { |
11026 /* Propagate location information from original call to | 11611 /* Propagate location information from original call to |
11027 expansion of builtin. Otherwise things like | 11612 expansion of builtin. Otherwise things like |
11028 maybe_emit_chk_warning, that operate on the expansion | 11613 maybe_emit_chk_warning, that operate on the expansion |
11200 | 11785 |
11201 *p = (char)tree_to_uhwi (t); | 11786 *p = (char)tree_to_uhwi (t); |
11202 return true; | 11787 return true; |
11203 } | 11788 } |
11204 | 11789 |
11205 /* Return the maximum object size. */ | 11790 /* Return true if the builtin DECL is implemented in a standard library. |
11206 | 11791 Otherwise returns false which doesn't guarantee it is not (thus the list of |
11207 tree | 11792 handled builtins below may be incomplete). */ |
11208 max_object_size (void) | 11793 |
11209 { | 11794 bool |
11210 /* To do: Make this a configurable parameter. */ | 11795 builtin_with_linkage_p (tree decl) |
11211 return TYPE_MAX_VALUE (ptrdiff_type_node); | 11796 { |
11212 } | 11797 if (DECL_BUILT_IN_CLASS (decl) == BUILT_IN_NORMAL) |
11798 switch (DECL_FUNCTION_CODE (decl)) | |
11799 { | |
11800 CASE_FLT_FN (BUILT_IN_ACOS): | |
11801 CASE_FLT_FN (BUILT_IN_ACOSH): | |
11802 CASE_FLT_FN (BUILT_IN_ASIN): | |
11803 CASE_FLT_FN (BUILT_IN_ASINH): | |
11804 CASE_FLT_FN (BUILT_IN_ATAN): | |
11805 CASE_FLT_FN (BUILT_IN_ATANH): | |
11806 CASE_FLT_FN (BUILT_IN_ATAN2): | |
11807 CASE_FLT_FN (BUILT_IN_CBRT): | |
11808 CASE_FLT_FN (BUILT_IN_CEIL): | |
11809 CASE_FLT_FN_FLOATN_NX (BUILT_IN_CEIL): | |
11810 CASE_FLT_FN (BUILT_IN_COPYSIGN): | |
11811 CASE_FLT_FN_FLOATN_NX (BUILT_IN_COPYSIGN): | |
11812 CASE_FLT_FN (BUILT_IN_COS): | |
11813 CASE_FLT_FN (BUILT_IN_COSH): | |
11814 CASE_FLT_FN (BUILT_IN_ERF): | |
11815 CASE_FLT_FN (BUILT_IN_ERFC): | |
11816 CASE_FLT_FN (BUILT_IN_EXP): | |
11817 CASE_FLT_FN (BUILT_IN_EXP2): | |
11818 CASE_FLT_FN (BUILT_IN_EXPM1): | |
11819 CASE_FLT_FN (BUILT_IN_FABS): | |
11820 CASE_FLT_FN_FLOATN_NX (BUILT_IN_FABS): | |
11821 CASE_FLT_FN (BUILT_IN_FDIM): | |
11822 CASE_FLT_FN (BUILT_IN_FLOOR): | |
11823 CASE_FLT_FN_FLOATN_NX (BUILT_IN_FLOOR): | |
11824 CASE_FLT_FN (BUILT_IN_FMA): | |
11825 CASE_FLT_FN_FLOATN_NX (BUILT_IN_FMA): | |
11826 CASE_FLT_FN (BUILT_IN_FMAX): | |
11827 CASE_FLT_FN_FLOATN_NX (BUILT_IN_FMAX): | |
11828 CASE_FLT_FN (BUILT_IN_FMIN): | |
11829 CASE_FLT_FN_FLOATN_NX (BUILT_IN_FMIN): | |
11830 CASE_FLT_FN (BUILT_IN_FMOD): | |
11831 CASE_FLT_FN (BUILT_IN_FREXP): | |
11832 CASE_FLT_FN (BUILT_IN_HYPOT): | |
11833 CASE_FLT_FN (BUILT_IN_ILOGB): | |
11834 CASE_FLT_FN (BUILT_IN_LDEXP): | |
11835 CASE_FLT_FN (BUILT_IN_LGAMMA): | |
11836 CASE_FLT_FN (BUILT_IN_LLRINT): | |
11837 CASE_FLT_FN (BUILT_IN_LLROUND): | |
11838 CASE_FLT_FN (BUILT_IN_LOG): | |
11839 CASE_FLT_FN (BUILT_IN_LOG10): | |
11840 CASE_FLT_FN (BUILT_IN_LOG1P): | |
11841 CASE_FLT_FN (BUILT_IN_LOG2): | |
11842 CASE_FLT_FN (BUILT_IN_LOGB): | |
11843 CASE_FLT_FN (BUILT_IN_LRINT): | |
11844 CASE_FLT_FN (BUILT_IN_LROUND): | |
11845 CASE_FLT_FN (BUILT_IN_MODF): | |
11846 CASE_FLT_FN (BUILT_IN_NAN): | |
11847 CASE_FLT_FN (BUILT_IN_NEARBYINT): | |
11848 CASE_FLT_FN_FLOATN_NX (BUILT_IN_NEARBYINT): | |
11849 CASE_FLT_FN (BUILT_IN_NEXTAFTER): | |
11850 CASE_FLT_FN (BUILT_IN_NEXTTOWARD): | |
11851 CASE_FLT_FN (BUILT_IN_POW): | |
11852 CASE_FLT_FN (BUILT_IN_REMAINDER): | |
11853 CASE_FLT_FN (BUILT_IN_REMQUO): | |
11854 CASE_FLT_FN (BUILT_IN_RINT): | |
11855 CASE_FLT_FN_FLOATN_NX (BUILT_IN_RINT): | |
11856 CASE_FLT_FN (BUILT_IN_ROUND): | |
11857 CASE_FLT_FN_FLOATN_NX (BUILT_IN_ROUND): | |
11858 CASE_FLT_FN (BUILT_IN_SCALBLN): | |
11859 CASE_FLT_FN (BUILT_IN_SCALBN): | |
11860 CASE_FLT_FN (BUILT_IN_SIN): | |
11861 CASE_FLT_FN (BUILT_IN_SINH): | |
11862 CASE_FLT_FN (BUILT_IN_SINCOS): | |
11863 CASE_FLT_FN (BUILT_IN_SQRT): | |
11864 CASE_FLT_FN_FLOATN_NX (BUILT_IN_SQRT): | |
11865 CASE_FLT_FN (BUILT_IN_TAN): | |
11866 CASE_FLT_FN (BUILT_IN_TANH): | |
11867 CASE_FLT_FN (BUILT_IN_TGAMMA): | |
11868 CASE_FLT_FN (BUILT_IN_TRUNC): | |
11869 CASE_FLT_FN_FLOATN_NX (BUILT_IN_TRUNC): | |
11870 return true; | |
11871 default: | |
11872 break; | |
11873 } | |
11874 return false; | |
11875 } |