Mercurial > hg > CbC > CbC_gcc
comparison gcc/builtins.c @ 132:d34655255c78
update gcc-8.2
author | mir3636 |
---|---|
date | Thu, 25 Oct 2018 10:21:07 +0900 |
parents | 84e7813d76e9 |
children | 1830386684a0 |
comparison
equal
deleted
inserted
replaced
130:e108057fa461 | 132:d34655255c78 |
---|---|
1 /* Expand builtin functions. | 1 /* Expand builtin functions. |
2 Copyright (C) 1988-2017 Free Software Foundation, Inc. | 2 Copyright (C) 1988-2018 Free Software Foundation, Inc. |
3 | 3 |
4 This file is part of GCC. | 4 This file is part of GCC. |
5 | 5 |
6 GCC is free software; you can redistribute it and/or modify it under | 6 GCC is free software; you can redistribute it and/or modify it under |
7 the terms of the GNU General Public License as published by the Free | 7 the terms of the GNU General Public License as published by the Free |
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" | |
34 #include "tm_p.h" | 35 #include "tm_p.h" |
35 #include "stringpool.h" | 36 #include "stringpool.h" |
36 #include "tree-vrp.h" | 37 #include "tree-vrp.h" |
37 #include "tree-ssanames.h" | 38 #include "tree-ssanames.h" |
38 #include "expmed.h" | 39 #include "expmed.h" |
41 #include "recog.h" | 42 #include "recog.h" |
42 #include "diagnostic-core.h" | 43 #include "diagnostic-core.h" |
43 #include "alias.h" | 44 #include "alias.h" |
44 #include "fold-const.h" | 45 #include "fold-const.h" |
45 #include "fold-const-call.h" | 46 #include "fold-const-call.h" |
47 #include "gimple-ssa-warn-restrict.h" | |
46 #include "stor-layout.h" | 48 #include "stor-layout.h" |
47 #include "calls.h" | 49 #include "calls.h" |
48 #include "varasm.h" | 50 #include "varasm.h" |
49 #include "tree-object-size.h" | 51 #include "tree-object-size.h" |
50 #include "realmpfr.h" | 52 #include "realmpfr.h" |
61 #include "value-prof.h" | 63 #include "value-prof.h" |
62 #include "builtins.h" | 64 #include "builtins.h" |
63 #include "stringpool.h" | 65 #include "stringpool.h" |
64 #include "attribs.h" | 66 #include "attribs.h" |
65 #include "asan.h" | 67 #include "asan.h" |
66 #include "cilk.h" | |
67 #include "tree-chkp.h" | |
68 #include "rtl-chkp.h" | |
69 #include "internal-fn.h" | 68 #include "internal-fn.h" |
70 #include "case-cfn-macros.h" | 69 #include "case-cfn-macros.h" |
71 #include "gimple-fold.h" | 70 #include "gimple-fold.h" |
72 #include "intl.h" | 71 #include "intl.h" |
72 #include "file-prefix-map.h" /* remap_macro_filename() */ | |
73 #include "gomp-constants.h" | |
74 #include "omp-general.h" | |
73 | 75 |
74 struct target_builtins default_target_builtins; | 76 struct target_builtins default_target_builtins; |
75 #if SWITCHABLE_TARGET | 77 #if SWITCHABLE_TARGET |
76 struct target_builtins *this_target_builtins = &default_target_builtins; | 78 struct target_builtins *this_target_builtins = &default_target_builtins; |
77 #endif | 79 #endif |
115 static rtx expand_builtin_int_roundingfn_2 (tree, rtx); | 117 static rtx expand_builtin_int_roundingfn_2 (tree, rtx); |
116 static rtx expand_builtin_next_arg (void); | 118 static rtx expand_builtin_next_arg (void); |
117 static rtx expand_builtin_va_start (tree); | 119 static rtx expand_builtin_va_start (tree); |
118 static rtx expand_builtin_va_end (tree); | 120 static rtx expand_builtin_va_end (tree); |
119 static rtx expand_builtin_va_copy (tree); | 121 static rtx expand_builtin_va_copy (tree); |
122 static rtx inline_expand_builtin_string_cmp (tree, rtx); | |
120 static rtx expand_builtin_strcmp (tree, rtx); | 123 static rtx expand_builtin_strcmp (tree, rtx); |
121 static rtx expand_builtin_strncmp (tree, rtx, machine_mode); | 124 static rtx expand_builtin_strncmp (tree, rtx, machine_mode); |
122 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); |
123 static rtx expand_builtin_memchr (tree, rtx); | 126 static rtx expand_builtin_memchr (tree, rtx); |
124 static rtx expand_builtin_memcpy (tree, rtx); | 127 static rtx expand_builtin_memcpy (tree, rtx); |
125 static rtx expand_builtin_memcpy_with_bounds (tree, rtx); | |
126 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, |
127 rtx target, tree exp, int endp); | 129 rtx target, tree exp, int endp); |
128 static rtx expand_builtin_memmove (tree, rtx); | 130 static rtx expand_builtin_memmove (tree, rtx); |
129 static rtx expand_builtin_mempcpy (tree, rtx); | 131 static rtx expand_builtin_mempcpy (tree, rtx); |
130 static rtx expand_builtin_mempcpy_with_bounds (tree, rtx); | |
131 static rtx expand_builtin_mempcpy_args (tree, tree, tree, rtx, tree, int); | 132 static rtx expand_builtin_mempcpy_args (tree, tree, tree, rtx, tree, int); |
132 static rtx expand_builtin_strcat (tree, rtx); | 133 static rtx expand_builtin_strcat (tree, rtx); |
133 static rtx expand_builtin_strcpy (tree, rtx); | 134 static rtx expand_builtin_strcpy (tree, rtx); |
134 static rtx expand_builtin_strcpy_args (tree, tree, rtx); | 135 static rtx expand_builtin_strcpy_args (tree, tree, tree, rtx); |
135 static rtx expand_builtin_stpcpy (tree, rtx, machine_mode); | 136 static rtx expand_builtin_stpcpy (tree, rtx, machine_mode); |
136 static rtx expand_builtin_stpncpy (tree, rtx); | 137 static rtx expand_builtin_stpncpy (tree, rtx); |
137 static rtx expand_builtin_strncat (tree, rtx); | 138 static rtx expand_builtin_strncat (tree, rtx); |
138 static rtx expand_builtin_strncpy (tree, rtx); | 139 static rtx expand_builtin_strncpy (tree, rtx); |
139 static rtx builtin_memset_gen_str (void *, HOST_WIDE_INT, scalar_int_mode); | 140 static rtx builtin_memset_gen_str (void *, HOST_WIDE_INT, scalar_int_mode); |
140 static rtx expand_builtin_memset (tree, rtx, machine_mode); | 141 static rtx expand_builtin_memset (tree, rtx, machine_mode); |
141 static rtx expand_builtin_memset_with_bounds (tree, rtx, machine_mode); | |
142 static rtx expand_builtin_memset_args (tree, tree, tree, rtx, machine_mode, tree); | 142 static rtx expand_builtin_memset_args (tree, tree, tree, rtx, machine_mode, tree); |
143 static rtx expand_builtin_bzero (tree); | 143 static rtx expand_builtin_bzero (tree); |
144 static rtx expand_builtin_strlen (tree, rtx, machine_mode); | 144 static rtx expand_builtin_strlen (tree, rtx, machine_mode); |
145 static rtx expand_builtin_strnlen (tree, rtx, machine_mode); | |
145 static rtx expand_builtin_alloca (tree); | 146 static rtx expand_builtin_alloca (tree); |
146 static rtx expand_builtin_unop (machine_mode, tree, rtx, rtx, optab); | 147 static rtx expand_builtin_unop (machine_mode, tree, rtx, rtx, optab); |
147 static rtx expand_builtin_frame_address (tree, tree); | 148 static rtx expand_builtin_frame_address (tree, tree); |
148 static tree stabilize_va_list_loc (location_t, tree, int); | 149 static tree stabilize_va_list_loc (location_t, tree, int); |
149 static rtx expand_builtin_expect (tree, rtx); | 150 static rtx expand_builtin_expect (tree, rtx); |
151 static rtx expand_builtin_expect_with_probability (tree, rtx); | |
150 static tree fold_builtin_constant_p (tree); | 152 static tree fold_builtin_constant_p (tree); |
151 static tree fold_builtin_classify_type (tree); | 153 static tree fold_builtin_classify_type (tree); |
152 static tree fold_builtin_strlen (location_t, tree, tree); | 154 static tree fold_builtin_strlen (location_t, tree, tree); |
153 static tree fold_builtin_inf (location_t, tree, int); | 155 static tree fold_builtin_inf (location_t, tree, int); |
154 static tree rewrite_call_expr (location_t, tree, int, tree, int, ...); | 156 static tree rewrite_call_expr (location_t, tree, int, tree, int, ...); |
201 return true; | 203 return true; |
202 if (strncmp (name, "__sync_", 7) == 0) | 204 if (strncmp (name, "__sync_", 7) == 0) |
203 return true; | 205 return true; |
204 if (strncmp (name, "__atomic_", 9) == 0) | 206 if (strncmp (name, "__atomic_", 9) == 0) |
205 return true; | 207 return true; |
206 if (flag_cilkplus | |
207 && (!strcmp (name, "__cilkrts_detach") | |
208 || !strcmp (name, "__cilkrts_pop_frame"))) | |
209 return true; | |
210 return false; | 208 return false; |
211 } | |
212 | |
213 | |
214 /* Return true if DECL is a function symbol representing a built-in. */ | |
215 | |
216 bool | |
217 is_builtin_fn (tree decl) | |
218 { | |
219 return TREE_CODE (decl) == FUNCTION_DECL && DECL_BUILT_IN (decl); | |
220 } | 209 } |
221 | 210 |
222 /* Return true if NODE should be considered for inline expansion regardless | 211 /* Return true if NODE should be considered for inline expansion regardless |
223 of the optimization level. This means whenever a function is invoked with | 212 of the optimization level. This means whenever a function is invoked with |
224 its "internal" name, which normally contains the prefix "__builtin". */ | 213 its "internal" name, which normally contains the prefix "__builtin". */ |
250 | 239 |
251 static bool | 240 static bool |
252 get_object_alignment_2 (tree exp, unsigned int *alignp, | 241 get_object_alignment_2 (tree exp, unsigned int *alignp, |
253 unsigned HOST_WIDE_INT *bitposp, bool addr_p) | 242 unsigned HOST_WIDE_INT *bitposp, bool addr_p) |
254 { | 243 { |
255 HOST_WIDE_INT bitsize, bitpos; | 244 poly_int64 bitsize, bitpos; |
256 tree offset; | 245 tree offset; |
257 machine_mode mode; | 246 machine_mode mode; |
258 int unsignedp, reversep, volatilep; | 247 int unsignedp, reversep, volatilep; |
259 unsigned int align = BITS_PER_UNIT; | 248 unsigned int align = BITS_PER_UNIT; |
260 bool known_alignment = false; | 249 bool known_alignment = false; |
348 { | 337 { |
349 /* Else adjust bitpos accordingly. */ | 338 /* Else adjust bitpos accordingly. */ |
350 bitpos += ptr_bitpos; | 339 bitpos += ptr_bitpos; |
351 if (TREE_CODE (exp) == MEM_REF | 340 if (TREE_CODE (exp) == MEM_REF |
352 || TREE_CODE (exp) == TARGET_MEM_REF) | 341 || TREE_CODE (exp) == TARGET_MEM_REF) |
353 bitpos += mem_ref_offset (exp).to_short_addr () * BITS_PER_UNIT; | 342 bitpos += mem_ref_offset (exp).force_shwi () * BITS_PER_UNIT; |
354 } | 343 } |
355 } | 344 } |
356 else if (TREE_CODE (exp) == STRING_CST) | 345 else if (TREE_CODE (exp) == STRING_CST) |
357 { | 346 { |
358 /* STRING_CST are the only constant objects we allow to be not | 347 /* STRING_CST are the only constant objects we allow to be not |
375 if (inner) | 364 if (inner) |
376 align = MIN (align, inner); | 365 align = MIN (align, inner); |
377 } | 366 } |
378 } | 367 } |
379 | 368 |
369 /* Account for the alignment of runtime coefficients, so that the constant | |
370 bitpos is guaranteed to be accurate. */ | |
371 unsigned int alt_align = ::known_alignment (bitpos - bitpos.coeffs[0]); | |
372 if (alt_align != 0 && alt_align < align) | |
373 { | |
374 align = alt_align; | |
375 known_alignment = false; | |
376 } | |
377 | |
380 *alignp = align; | 378 *alignp = align; |
381 *bitposp = bitpos & (*alignp - 1); | 379 *bitposp = bitpos.coeffs[0] & (align - 1); |
382 return known_alignment; | 380 return known_alignment; |
383 } | 381 } |
384 | 382 |
385 /* For a memory reference expression EXP compute values M and N such that M | 383 /* For a memory reference expression EXP compute values M and N such that M |
386 divides (&EXP - N) and such that N < M. If these numbers can be determined, | 384 divides (&EXP - N) and such that N < M. If these numbers can be determined, |
509 align = least_bit_hwi (bitpos); | 507 align = least_bit_hwi (bitpos); |
510 | 508 |
511 return align; | 509 return align; |
512 } | 510 } |
513 | 511 |
514 /* Return the number of non-zero elements in the sequence | 512 /* Return the number of leading non-zero elements in the sequence |
515 [ PTR, PTR + MAXELTS ) where each element's size is ELTSIZE bytes. | 513 [ PTR, PTR + MAXELTS ) where each element's size is ELTSIZE bytes. |
516 ELTSIZE must be a power of 2 less than 8. Used by c_strlen. */ | 514 ELTSIZE must be a power of 2 less than 8. Used by c_strlen. */ |
517 | 515 |
518 static unsigned | 516 unsigned |
519 string_length (const void *ptr, unsigned eltsize, unsigned maxelts) | 517 string_length (const void *ptr, unsigned eltsize, unsigned maxelts) |
520 { | 518 { |
521 gcc_checking_assert (eltsize == 1 || eltsize == 2 || eltsize == 4); | 519 gcc_checking_assert (eltsize == 1 || eltsize == 2 || eltsize == 4); |
522 | 520 |
523 unsigned n; | 521 unsigned n; |
542 } | 540 } |
543 } | 541 } |
544 return n; | 542 return n; |
545 } | 543 } |
546 | 544 |
545 /* For a call at LOC to a function FN that expects a string in the argument | |
546 ARG, issue a diagnostic due to it being a called with an argument | |
547 declared at NONSTR that is a character array with no terminating NUL. */ | |
548 | |
549 void | |
550 warn_string_no_nul (location_t loc, const char *fn, tree arg, tree decl) | |
551 { | |
552 if (TREE_NO_WARNING (arg)) | |
553 return; | |
554 | |
555 loc = expansion_point_location_if_in_system_header (loc); | |
556 | |
557 if (warning_at (loc, OPT_Wstringop_overflow_, | |
558 "%qs argument missing terminating nul", fn)) | |
559 { | |
560 inform (DECL_SOURCE_LOCATION (decl), | |
561 "referenced argument declared here"); | |
562 TREE_NO_WARNING (arg) = 1; | |
563 } | |
564 } | |
565 | |
566 /* If EXP refers to an unterminated constant character array return | |
567 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 | |
569 the unterminated array and set *EXACT if the size is exact or | |
570 clear it otherwise. Otherwise return null. */ | |
571 | |
572 tree | |
573 unterminated_array (tree exp, tree *size /* = NULL */, bool *exact /* = NULL */) | |
574 { | |
575 /* C_STRLEN will return NULL and set DECL in the info | |
576 structure if EXP references a unterminated array. */ | |
577 c_strlen_data data; | |
578 memset (&data, 0, sizeof (c_strlen_data)); | |
579 tree len = c_strlen (exp, 1, &data); | |
580 if (len == NULL_TREE && data.len && data.decl) | |
581 { | |
582 if (size) | |
583 { | |
584 len = data.len; | |
585 if (data.off) | |
586 { | |
587 /* Constant offsets are already accounted for in data.len, but | |
588 not in a SSA_NAME + CST expression. */ | |
589 if (TREE_CODE (data.off) == INTEGER_CST) | |
590 *exact = true; | |
591 else if (TREE_CODE (data.off) == PLUS_EXPR | |
592 && TREE_CODE (TREE_OPERAND (data.off, 1)) == INTEGER_CST) | |
593 { | |
594 /* Subtract the offset from the size of the array. */ | |
595 *exact = false; | |
596 tree temp = TREE_OPERAND (data.off, 1); | |
597 temp = fold_convert (ssizetype, temp); | |
598 len = fold_build2 (MINUS_EXPR, ssizetype, len, temp); | |
599 } | |
600 else | |
601 *exact = false; | |
602 } | |
603 else | |
604 *exact = true; | |
605 | |
606 *size = len; | |
607 } | |
608 return data.decl; | |
609 } | |
610 | |
611 return NULL_TREE; | |
612 } | |
613 | |
547 /* Compute the length of a null-terminated character string or wide | 614 /* Compute the length of a null-terminated character string or wide |
548 character string handling character sizes of 1, 2, and 4 bytes. | 615 character string handling character sizes of 1, 2, and 4 bytes. |
549 TREE_STRING_LENGTH is not the right way because it evaluates to | 616 TREE_STRING_LENGTH is not the right way because it evaluates to |
550 the size of the character array in bytes (as opposed to characters) | 617 the size of the character array in bytes (as opposed to characters) |
551 and because it can contain a zero byte in the middle. | 618 and because it can contain a zero byte in the middle. |
559 | 626 |
560 If ONLY_VALUE is two then we do not emit warnings about out-of-bound | 627 If ONLY_VALUE is two then we do not emit warnings about out-of-bound |
561 accesses. Note that this implies the result is not going to be emitted | 628 accesses. Note that this implies the result is not going to be emitted |
562 into the instruction stream. | 629 into the instruction stream. |
563 | 630 |
564 The value returned is of type `ssizetype'. | 631 Additional information about the string accessed may be recorded |
565 | 632 in DATA. For example, if SRC references an unterminated string, |
566 Unfortunately, string_constant can't access the values of const char | 633 then the declaration will be stored in the DECL field. If the |
567 arrays with initializers, so neither can we do so here. */ | 634 length of the unterminated string can be determined, it'll be |
635 stored in the LEN field. Note this length could well be different | |
636 than what a C strlen call would return. | |
637 | |
638 ELTSIZE is 1 for normal single byte character strings, and 2 or | |
639 4 for wide characer strings. ELTSIZE is by default 1. | |
640 | |
641 The value returned is of type `ssizetype'. */ | |
568 | 642 |
569 tree | 643 tree |
570 c_strlen (tree src, int only_value) | 644 c_strlen (tree src, int only_value, c_strlen_data *data, unsigned eltsize) |
571 { | 645 { |
646 /* 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 | |
648 each time we want to use it. */ | |
649 c_strlen_data local_strlen_data; | |
650 memset (&local_strlen_data, 0, sizeof (c_strlen_data)); | |
651 if (!data) | |
652 data = &local_strlen_data; | |
653 | |
654 gcc_checking_assert (eltsize == 1 || eltsize == 2 || eltsize == 4); | |
572 STRIP_NOPS (src); | 655 STRIP_NOPS (src); |
573 if (TREE_CODE (src) == COND_EXPR | 656 if (TREE_CODE (src) == COND_EXPR |
574 && (only_value || !TREE_SIDE_EFFECTS (TREE_OPERAND (src, 0)))) | 657 && (only_value || !TREE_SIDE_EFFECTS (TREE_OPERAND (src, 0)))) |
575 { | 658 { |
576 tree len1, len2; | 659 tree len1, len2; |
577 | 660 |
578 len1 = c_strlen (TREE_OPERAND (src, 1), only_value); | 661 len1 = c_strlen (TREE_OPERAND (src, 1), only_value, data, eltsize); |
579 len2 = c_strlen (TREE_OPERAND (src, 2), only_value); | 662 len2 = c_strlen (TREE_OPERAND (src, 2), only_value, data, eltsize); |
580 if (tree_int_cst_equal (len1, len2)) | 663 if (tree_int_cst_equal (len1, len2)) |
581 return len1; | 664 return len1; |
582 } | 665 } |
583 | 666 |
584 if (TREE_CODE (src) == COMPOUND_EXPR | 667 if (TREE_CODE (src) == COMPOUND_EXPR |
585 && (only_value || !TREE_SIDE_EFFECTS (TREE_OPERAND (src, 0)))) | 668 && (only_value || !TREE_SIDE_EFFECTS (TREE_OPERAND (src, 0)))) |
586 return c_strlen (TREE_OPERAND (src, 1), only_value); | 669 return c_strlen (TREE_OPERAND (src, 1), only_value, data, eltsize); |
587 | 670 |
588 location_t loc = EXPR_LOC_OR_LOC (src, input_location); | 671 location_t loc = EXPR_LOC_OR_LOC (src, input_location); |
589 | 672 |
590 /* Offset from the beginning of the string in bytes. */ | 673 /* Offset from the beginning of the string in bytes. */ |
591 tree byteoff; | 674 tree byteoff; |
592 src = string_constant (src, &byteoff); | 675 tree memsize; |
676 tree decl; | |
677 src = string_constant (src, &byteoff, &memsize, &decl); | |
593 if (src == 0) | 678 if (src == 0) |
594 return NULL_TREE; | 679 return NULL_TREE; |
595 | 680 |
596 /* Determine the size of the string element. */ | 681 /* Determine the size of the string element. */ |
597 unsigned eltsize | 682 if (eltsize != tree_to_uhwi (TYPE_SIZE_UNIT (TREE_TYPE (TREE_TYPE (src))))) |
598 = tree_to_uhwi (TYPE_SIZE_UNIT (TREE_TYPE (TREE_TYPE (src)))); | 683 return NULL_TREE; |
599 | 684 |
600 /* Set MAXELTS to sizeof (SRC) / sizeof (*SRC) - 1, the maximum possible | 685 /* Set MAXELTS to sizeof (SRC) / sizeof (*SRC) - 1, the maximum possible |
601 length of SRC. */ | 686 length of SRC. Prefer TYPE_SIZE() to TREE_STRING_LENGTH() if possible |
602 unsigned maxelts = TREE_STRING_LENGTH (src) / eltsize - 1; | 687 in case the latter is less than the size of the array, such as when |
688 SRC refers to a short string literal used to initialize a large array. | |
689 In that case, the elements of the array after the terminating NUL are | |
690 all NUL. */ | |
691 HOST_WIDE_INT strelts = TREE_STRING_LENGTH (src); | |
692 strelts = strelts / eltsize; | |
693 | |
694 if (!tree_fits_uhwi_p (memsize)) | |
695 return NULL_TREE; | |
696 | |
697 HOST_WIDE_INT maxelts = tree_to_uhwi (memsize) / eltsize; | |
603 | 698 |
604 /* PTR can point to the byte representation of any string type, including | 699 /* PTR can point to the byte representation of any string type, including |
605 char* and wchar_t*. */ | 700 char* and wchar_t*. */ |
606 const char *ptr = TREE_STRING_POINTER (src); | 701 const char *ptr = TREE_STRING_POINTER (src); |
607 | 702 |
608 if (byteoff && TREE_CODE (byteoff) != INTEGER_CST) | 703 if (byteoff && TREE_CODE (byteoff) != INTEGER_CST) |
609 { | 704 { |
610 /* If the string has an internal zero byte (e.g., "foo\0bar"), we can't | 705 /* The code below works only for single byte character types. */ |
611 compute the offset to the following null if we don't know where to | 706 if (eltsize != 1) |
707 return NULL_TREE; | |
708 | |
709 /* If the string has an internal NUL character followed by any | |
710 non-NUL characters (e.g., "foo\0bar"), we can't compute | |
711 the offset to the following NUL if we don't know where to | |
612 start searching for it. */ | 712 start searching for it. */ |
613 if (string_length (ptr, eltsize, maxelts) < maxelts) | 713 unsigned len = string_length (ptr, eltsize, strelts); |
714 | |
715 /* Return when an embedded null character is found or none at all. | |
716 In the latter case, set the DECL/LEN field in the DATA structure | |
717 so that callers may examine them. */ | |
718 if (len + 1 < strelts) | |
719 return NULL_TREE; | |
720 else if (len >= maxelts) | |
614 { | 721 { |
615 /* Return when an embedded null character is found. */ | 722 data->decl = decl; |
723 data->off = byteoff; | |
724 data->len = ssize_int (len); | |
616 return NULL_TREE; | 725 return NULL_TREE; |
617 } | 726 } |
618 | 727 |
728 /* For empty strings the result should be zero. */ | |
729 if (len == 0) | |
730 return ssize_int (0); | |
731 | |
619 /* We don't know the starting offset, but we do know that the string | 732 /* We don't know the starting offset, but we do know that the string |
620 has no internal zero bytes. We can assume that the offset falls | 733 has no internal zero bytes. If the offset falls within the bounds |
621 within the bounds of the string; otherwise, the programmer deserves | 734 of the string subtract the offset from the length of the string, |
622 what he gets. Subtract the offset from the length of the string, | 735 and return that. Otherwise the length is zero. Take care to |
623 and return that. This would perhaps not be valid if we were dealing | 736 use SAVE_EXPR in case the OFFSET has side-effects. */ |
624 with named arrays in addition to literal string constants. */ | 737 tree offsave = TREE_SIDE_EFFECTS (byteoff) ? save_expr (byteoff) : byteoff; |
625 | 738 offsave = fold_convert (ssizetype, offsave); |
626 return size_diffop_loc (loc, size_int (maxelts * eltsize), byteoff); | 739 tree condexp = fold_build2_loc (loc, LE_EXPR, boolean_type_node, offsave, |
740 build_int_cst (ssizetype, len)); | |
741 tree lenexp = size_diffop_loc (loc, ssize_int (len), offsave); | |
742 return fold_build3_loc (loc, COND_EXPR, ssizetype, condexp, lenexp, | |
743 build_zero_cst (ssizetype)); | |
627 } | 744 } |
628 | 745 |
629 /* Offset from the beginning of the string in elements. */ | 746 /* Offset from the beginning of the string in elements. */ |
630 HOST_WIDE_INT eltoff; | 747 HOST_WIDE_INT eltoff; |
631 | 748 |
632 /* We have a known offset into the string. Start searching there for | 749 /* We have a known offset into the string. Start searching there for |
633 a null character if we can represent it as a single HOST_WIDE_INT. */ | 750 a null character if we can represent it as a single HOST_WIDE_INT. */ |
634 if (byteoff == 0) | 751 if (byteoff == 0) |
635 eltoff = 0; | 752 eltoff = 0; |
636 else if (! tree_fits_shwi_p (byteoff)) | 753 else if (! tree_fits_uhwi_p (byteoff) || tree_to_uhwi (byteoff) % eltsize) |
637 eltoff = -1; | 754 eltoff = -1; |
638 else | 755 else |
639 eltoff = tree_to_shwi (byteoff) / eltsize; | 756 eltoff = tree_to_uhwi (byteoff) / eltsize; |
640 | 757 |
641 /* If the offset is known to be out of bounds, warn, and call strlen at | 758 /* If the offset is known to be out of bounds, warn, and call strlen at |
642 runtime. */ | 759 runtime. */ |
643 if (eltoff < 0 || eltoff > maxelts) | 760 if (eltoff < 0 || eltoff >= maxelts) |
644 { | 761 { |
645 /* Suppress multiple warnings for propagated constant strings. */ | 762 /* Suppress multiple warnings for propagated constant strings. */ |
646 if (only_value != 2 | 763 if (only_value != 2 |
647 && !TREE_NO_WARNING (src)) | 764 && !TREE_NO_WARNING (src)) |
648 { | 765 { |
649 warning_at (loc, 0, "offset %qwi outside bounds of constant string", | 766 warning_at (loc, OPT_Warray_bounds, |
767 "offset %qwi outside bounds of constant string", | |
650 eltoff); | 768 eltoff); |
651 TREE_NO_WARNING (src) = 1; | 769 TREE_NO_WARNING (src) = 1; |
652 } | 770 } |
653 return NULL_TREE; | 771 return NULL_TREE; |
654 } | 772 } |
655 | 773 |
774 /* If eltoff is larger than strelts but less than maxelts the | |
775 string length is zero, since the excess memory will be zero. */ | |
776 if (eltoff > strelts) | |
777 return ssize_int (0); | |
778 | |
656 /* Use strlen to search for the first zero byte. Since any strings | 779 /* Use strlen to search for the first zero byte. Since any strings |
657 constructed with build_string will have nulls appended, we win even | 780 constructed with build_string will have nulls appended, we win even |
658 if we get handed something like (char[4])"abcd". | 781 if we get handed something like (char[4])"abcd". |
659 | 782 |
660 Since ELTOFF is our starting index into the string, no further | 783 Since ELTOFF is our starting index into the string, no further |
661 calculation is needed. */ | 784 calculation is needed. */ |
662 unsigned len = string_length (ptr + eltoff * eltsize, eltsize, | 785 unsigned len = string_length (ptr + eltoff * eltsize, eltsize, |
663 maxelts - eltoff); | 786 strelts - eltoff); |
787 | |
788 /* Don't know what to return if there was no zero termination. | |
789 Ideally this would turn into a gcc_checking_assert over time. | |
790 Set DECL/LEN so callers can examine them. */ | |
791 if (len >= maxelts - eltoff) | |
792 { | |
793 data->decl = decl; | |
794 data->off = byteoff; | |
795 data->len = ssize_int (len); | |
796 return NULL_TREE; | |
797 } | |
664 | 798 |
665 return ssize_int (len); | 799 return ssize_int (len); |
666 } | 800 } |
667 | 801 |
668 /* Return a constant integer corresponding to target reading | 802 /* Return a constant integer corresponding to target reading |
880 marked as used by this function. */ | 1014 marked as used by this function. */ |
881 emit_use (hard_frame_pointer_rtx); | 1015 emit_use (hard_frame_pointer_rtx); |
882 | 1016 |
883 /* Mark the static chain as clobbered here so life information | 1017 /* Mark the static chain as clobbered here so life information |
884 doesn't get messed up for it. */ | 1018 doesn't get messed up for it. */ |
885 chain = targetm.calls.static_chain (current_function_decl, true); | 1019 chain = rtx_for_static_chain (current_function_decl, true); |
886 if (chain && REG_P (chain)) | 1020 if (chain && REG_P (chain)) |
887 emit_clobber (chain); | 1021 emit_clobber (chain); |
888 | 1022 |
889 /* Now put in the code to restore the frame pointer, and argument | 1023 /* Now put in the code to restore the frame pointer, and argument |
890 pointer, if needed. */ | 1024 pointer, if needed. */ |
1357 apply_args_size (void) | 1491 apply_args_size (void) |
1358 { | 1492 { |
1359 static int size = -1; | 1493 static int size = -1; |
1360 int align; | 1494 int align; |
1361 unsigned int regno; | 1495 unsigned int regno; |
1362 machine_mode mode; | |
1363 | 1496 |
1364 /* The values computed by this function never change. */ | 1497 /* The values computed by this function never change. */ |
1365 if (size < 0) | 1498 if (size < 0) |
1366 { | 1499 { |
1367 /* The first value is the incoming arg-pointer. */ | 1500 /* The first value is the incoming arg-pointer. */ |
1373 size += GET_MODE_SIZE (Pmode); | 1506 size += GET_MODE_SIZE (Pmode); |
1374 | 1507 |
1375 for (regno = 0; regno < FIRST_PSEUDO_REGISTER; regno++) | 1508 for (regno = 0; regno < FIRST_PSEUDO_REGISTER; regno++) |
1376 if (FUNCTION_ARG_REGNO_P (regno)) | 1509 if (FUNCTION_ARG_REGNO_P (regno)) |
1377 { | 1510 { |
1378 mode = targetm.calls.get_raw_arg_mode (regno); | 1511 fixed_size_mode mode = targetm.calls.get_raw_arg_mode (regno); |
1379 | 1512 |
1380 gcc_assert (mode != VOIDmode); | 1513 gcc_assert (mode != VOIDmode); |
1381 | 1514 |
1382 align = GET_MODE_ALIGNMENT (mode) / BITS_PER_UNIT; | 1515 align = GET_MODE_ALIGNMENT (mode) / BITS_PER_UNIT; |
1383 if (size % align != 0) | 1516 if (size % align != 0) |
1385 size += GET_MODE_SIZE (mode); | 1518 size += GET_MODE_SIZE (mode); |
1386 apply_args_mode[regno] = mode; | 1519 apply_args_mode[regno] = mode; |
1387 } | 1520 } |
1388 else | 1521 else |
1389 { | 1522 { |
1390 apply_args_mode[regno] = VOIDmode; | 1523 apply_args_mode[regno] = as_a <fixed_size_mode> (VOIDmode); |
1391 } | 1524 } |
1392 } | 1525 } |
1393 return size; | 1526 return size; |
1394 } | 1527 } |
1395 | 1528 |
1399 static int | 1532 static int |
1400 apply_result_size (void) | 1533 apply_result_size (void) |
1401 { | 1534 { |
1402 static int size = -1; | 1535 static int size = -1; |
1403 int align, regno; | 1536 int align, regno; |
1404 machine_mode mode; | |
1405 | 1537 |
1406 /* The values computed by this function never change. */ | 1538 /* The values computed by this function never change. */ |
1407 if (size < 0) | 1539 if (size < 0) |
1408 { | 1540 { |
1409 size = 0; | 1541 size = 0; |
1410 | 1542 |
1411 for (regno = 0; regno < FIRST_PSEUDO_REGISTER; regno++) | 1543 for (regno = 0; regno < FIRST_PSEUDO_REGISTER; regno++) |
1412 if (targetm.calls.function_value_regno_p (regno)) | 1544 if (targetm.calls.function_value_regno_p (regno)) |
1413 { | 1545 { |
1414 mode = targetm.calls.get_raw_result_mode (regno); | 1546 fixed_size_mode mode = targetm.calls.get_raw_result_mode (regno); |
1415 | 1547 |
1416 gcc_assert (mode != VOIDmode); | 1548 gcc_assert (mode != VOIDmode); |
1417 | 1549 |
1418 align = GET_MODE_ALIGNMENT (mode) / BITS_PER_UNIT; | 1550 align = GET_MODE_ALIGNMENT (mode) / BITS_PER_UNIT; |
1419 if (size % align != 0) | 1551 if (size % align != 0) |
1420 size = CEIL (size, align) * align; | 1552 size = CEIL (size, align) * align; |
1421 size += GET_MODE_SIZE (mode); | 1553 size += GET_MODE_SIZE (mode); |
1422 apply_result_mode[regno] = mode; | 1554 apply_result_mode[regno] = mode; |
1423 } | 1555 } |
1424 else | 1556 else |
1425 apply_result_mode[regno] = VOIDmode; | 1557 apply_result_mode[regno] = as_a <fixed_size_mode> (VOIDmode); |
1426 | 1558 |
1427 /* Allow targets that use untyped_call and untyped_return to override | 1559 /* Allow targets that use untyped_call and untyped_return to override |
1428 the size so that machine-specific information can be stored here. */ | 1560 the size so that machine-specific information can be stored here. */ |
1429 #ifdef APPLY_RESULT_SIZE | 1561 #ifdef APPLY_RESULT_SIZE |
1430 size = APPLY_RESULT_SIZE; | 1562 size = APPLY_RESULT_SIZE; |
1439 | 1571 |
1440 static rtx | 1572 static rtx |
1441 result_vector (int savep, rtx result) | 1573 result_vector (int savep, rtx result) |
1442 { | 1574 { |
1443 int regno, size, align, nelts; | 1575 int regno, size, align, nelts; |
1444 machine_mode mode; | 1576 fixed_size_mode mode; |
1445 rtx reg, mem; | 1577 rtx reg, mem; |
1446 rtx *savevec = XALLOCAVEC (rtx, FIRST_PSEUDO_REGISTER); | 1578 rtx *savevec = XALLOCAVEC (rtx, FIRST_PSEUDO_REGISTER); |
1447 | 1579 |
1448 size = nelts = 0; | 1580 size = nelts = 0; |
1449 for (regno = 0; regno < FIRST_PSEUDO_REGISTER; regno++) | 1581 for (regno = 0; regno < FIRST_PSEUDO_REGISTER; regno++) |
1468 static rtx | 1600 static rtx |
1469 expand_builtin_apply_args_1 (void) | 1601 expand_builtin_apply_args_1 (void) |
1470 { | 1602 { |
1471 rtx registers, tem; | 1603 rtx registers, tem; |
1472 int size, align, regno; | 1604 int size, align, regno; |
1473 machine_mode mode; | 1605 fixed_size_mode mode; |
1474 rtx struct_incoming_value = targetm.calls.struct_value_rtx (cfun ? TREE_TYPE (cfun->decl) : 0, 1); | 1606 rtx struct_incoming_value = targetm.calls.struct_value_rtx (cfun ? TREE_TYPE (cfun->decl) : 0, 1); |
1475 | 1607 |
1476 /* Create a block where the arg-pointer, structure value address, | 1608 /* Create a block where the arg-pointer, structure value address, |
1477 and argument registers can be saved. */ | 1609 and argument registers can be saved. */ |
1478 registers = assign_stack_local (BLKmode, apply_args_size (), -1); | 1610 registers = assign_stack_local (BLKmode, apply_args_size (), -1); |
1572 | 1704 |
1573 static rtx | 1705 static rtx |
1574 expand_builtin_apply (rtx function, rtx arguments, rtx argsize) | 1706 expand_builtin_apply (rtx function, rtx arguments, rtx argsize) |
1575 { | 1707 { |
1576 int size, align, regno; | 1708 int size, align, regno; |
1577 machine_mode mode; | 1709 fixed_size_mode mode; |
1578 rtx incoming_args, result, reg, dest, src; | 1710 rtx incoming_args, result, reg, dest, src; |
1579 rtx_call_insn *call_insn; | 1711 rtx_call_insn *call_insn; |
1580 rtx old_stack_level = 0; | 1712 rtx old_stack_level = 0; |
1581 rtx call_fusage = 0; | 1713 rtx call_fusage = 0; |
1582 rtx struct_value = targetm.calls.struct_value_rtx (cfun ? TREE_TYPE (cfun->decl) : 0, 0); | 1714 rtx struct_value = targetm.calls.struct_value_rtx (cfun ? TREE_TYPE (cfun->decl) : 0, 0); |
1733 | 1865 |
1734 static void | 1866 static void |
1735 expand_builtin_return (rtx result) | 1867 expand_builtin_return (rtx result) |
1736 { | 1868 { |
1737 int size, align, regno; | 1869 int size, align, regno; |
1738 machine_mode mode; | 1870 fixed_size_mode mode; |
1739 rtx reg; | 1871 rtx reg; |
1740 rtx_insn *call_fusage = 0; | 1872 rtx_insn *call_fusage = 0; |
1741 | 1873 |
1742 result = convert_memory_address (Pmode, result); | 1874 result = convert_memory_address (Pmode, result); |
1743 | 1875 |
1814 if (call_expr_nargs (exp)) | 1946 if (call_expr_nargs (exp)) |
1815 return GEN_INT (type_to_class (TREE_TYPE (CALL_EXPR_ARG (exp, 0)))); | 1947 return GEN_INT (type_to_class (TREE_TYPE (CALL_EXPR_ARG (exp, 0)))); |
1816 return GEN_INT (no_type_class); | 1948 return GEN_INT (no_type_class); |
1817 } | 1949 } |
1818 | 1950 |
1819 /* This helper macro, meant to be used in mathfn_built_in below, | 1951 /* This helper macro, meant to be used in mathfn_built_in below, determines |
1820 determines which among a set of three builtin math functions is | 1952 which among a set of builtin math functions is appropriate for a given type |
1821 appropriate for a given type mode. The `F' and `L' cases are | 1953 mode. The `F' (float) and `L' (long double) are automatically generated |
1822 automatically generated from the `double' case. */ | 1954 from the 'double' case. If a function supports the _Float<N> and _Float<N>X |
1955 types, there are additional types that are considered with 'F32', 'F64', | |
1956 'F128', etc. suffixes. */ | |
1823 #define CASE_MATHFN(MATHFN) \ | 1957 #define CASE_MATHFN(MATHFN) \ |
1824 CASE_CFN_##MATHFN: \ | 1958 CASE_CFN_##MATHFN: \ |
1825 fcode = BUILT_IN_##MATHFN; fcodef = BUILT_IN_##MATHFN##F ; \ | 1959 fcode = BUILT_IN_##MATHFN; fcodef = BUILT_IN_##MATHFN##F ; \ |
1826 fcodel = BUILT_IN_##MATHFN##L ; break; | 1960 fcodel = BUILT_IN_##MATHFN##L ; break; |
1961 /* Similar to the above, but also add support for the _Float<N> and _Float<N>X | |
1962 types. */ | |
1963 #define CASE_MATHFN_FLOATN(MATHFN) \ | |
1964 CASE_CFN_##MATHFN: \ | |
1965 fcode = BUILT_IN_##MATHFN; fcodef = BUILT_IN_##MATHFN##F ; \ | |
1966 fcodel = BUILT_IN_##MATHFN##L ; fcodef16 = BUILT_IN_##MATHFN##F16 ; \ | |
1967 fcodef32 = BUILT_IN_##MATHFN##F32; fcodef64 = BUILT_IN_##MATHFN##F64 ; \ | |
1968 fcodef128 = BUILT_IN_##MATHFN##F128 ; fcodef32x = BUILT_IN_##MATHFN##F32X ; \ | |
1969 fcodef64x = BUILT_IN_##MATHFN##F64X ; fcodef128x = BUILT_IN_##MATHFN##F128X ;\ | |
1970 break; | |
1827 /* Similar to above, but appends _R after any F/L suffix. */ | 1971 /* Similar to above, but appends _R after any F/L suffix. */ |
1828 #define CASE_MATHFN_REENT(MATHFN) \ | 1972 #define CASE_MATHFN_REENT(MATHFN) \ |
1829 case CFN_BUILT_IN_##MATHFN##_R: \ | 1973 case CFN_BUILT_IN_##MATHFN##_R: \ |
1830 case CFN_BUILT_IN_##MATHFN##F_R: \ | 1974 case CFN_BUILT_IN_##MATHFN##F_R: \ |
1831 case CFN_BUILT_IN_##MATHFN##L_R: \ | 1975 case CFN_BUILT_IN_##MATHFN##L_R: \ |
1838 that the target actually has an implementation of the function. */ | 1982 that the target actually has an implementation of the function. */ |
1839 | 1983 |
1840 static built_in_function | 1984 static built_in_function |
1841 mathfn_built_in_2 (tree type, combined_fn fn) | 1985 mathfn_built_in_2 (tree type, combined_fn fn) |
1842 { | 1986 { |
1987 tree mtype; | |
1843 built_in_function fcode, fcodef, fcodel; | 1988 built_in_function fcode, fcodef, fcodel; |
1989 built_in_function fcodef16 = END_BUILTINS; | |
1990 built_in_function fcodef32 = END_BUILTINS; | |
1991 built_in_function fcodef64 = END_BUILTINS; | |
1992 built_in_function fcodef128 = END_BUILTINS; | |
1993 built_in_function fcodef32x = END_BUILTINS; | |
1994 built_in_function fcodef64x = END_BUILTINS; | |
1995 built_in_function fcodef128x = END_BUILTINS; | |
1844 | 1996 |
1845 switch (fn) | 1997 switch (fn) |
1846 { | 1998 { |
1847 CASE_MATHFN (ACOS) | 1999 CASE_MATHFN (ACOS) |
1848 CASE_MATHFN (ACOSH) | 2000 CASE_MATHFN (ACOSH) |
1850 CASE_MATHFN (ASINH) | 2002 CASE_MATHFN (ASINH) |
1851 CASE_MATHFN (ATAN) | 2003 CASE_MATHFN (ATAN) |
1852 CASE_MATHFN (ATAN2) | 2004 CASE_MATHFN (ATAN2) |
1853 CASE_MATHFN (ATANH) | 2005 CASE_MATHFN (ATANH) |
1854 CASE_MATHFN (CBRT) | 2006 CASE_MATHFN (CBRT) |
1855 CASE_MATHFN (CEIL) | 2007 CASE_MATHFN_FLOATN (CEIL) |
1856 CASE_MATHFN (CEXPI) | 2008 CASE_MATHFN (CEXPI) |
1857 CASE_MATHFN (COPYSIGN) | 2009 CASE_MATHFN_FLOATN (COPYSIGN) |
1858 CASE_MATHFN (COS) | 2010 CASE_MATHFN (COS) |
1859 CASE_MATHFN (COSH) | 2011 CASE_MATHFN (COSH) |
1860 CASE_MATHFN (DREM) | 2012 CASE_MATHFN (DREM) |
1861 CASE_MATHFN (ERF) | 2013 CASE_MATHFN (ERF) |
1862 CASE_MATHFN (ERFC) | 2014 CASE_MATHFN (ERFC) |
1864 CASE_MATHFN (EXP10) | 2016 CASE_MATHFN (EXP10) |
1865 CASE_MATHFN (EXP2) | 2017 CASE_MATHFN (EXP2) |
1866 CASE_MATHFN (EXPM1) | 2018 CASE_MATHFN (EXPM1) |
1867 CASE_MATHFN (FABS) | 2019 CASE_MATHFN (FABS) |
1868 CASE_MATHFN (FDIM) | 2020 CASE_MATHFN (FDIM) |
1869 CASE_MATHFN (FLOOR) | 2021 CASE_MATHFN_FLOATN (FLOOR) |
1870 CASE_MATHFN (FMA) | 2022 CASE_MATHFN_FLOATN (FMA) |
1871 CASE_MATHFN (FMAX) | 2023 CASE_MATHFN_FLOATN (FMAX) |
1872 CASE_MATHFN (FMIN) | 2024 CASE_MATHFN_FLOATN (FMIN) |
1873 CASE_MATHFN (FMOD) | 2025 CASE_MATHFN (FMOD) |
1874 CASE_MATHFN (FREXP) | 2026 CASE_MATHFN (FREXP) |
1875 CASE_MATHFN (GAMMA) | 2027 CASE_MATHFN (GAMMA) |
1876 CASE_MATHFN_REENT (GAMMA) /* GAMMA_R */ | 2028 CASE_MATHFN_REENT (GAMMA) /* GAMMA_R */ |
1877 CASE_MATHFN (HUGE_VAL) | 2029 CASE_MATHFN (HUGE_VAL) |
1903 CASE_MATHFN (LRINT) | 2055 CASE_MATHFN (LRINT) |
1904 CASE_MATHFN (LROUND) | 2056 CASE_MATHFN (LROUND) |
1905 CASE_MATHFN (MODF) | 2057 CASE_MATHFN (MODF) |
1906 CASE_MATHFN (NAN) | 2058 CASE_MATHFN (NAN) |
1907 CASE_MATHFN (NANS) | 2059 CASE_MATHFN (NANS) |
1908 CASE_MATHFN (NEARBYINT) | 2060 CASE_MATHFN_FLOATN (NEARBYINT) |
1909 CASE_MATHFN (NEXTAFTER) | 2061 CASE_MATHFN (NEXTAFTER) |
1910 CASE_MATHFN (NEXTTOWARD) | 2062 CASE_MATHFN (NEXTTOWARD) |
1911 CASE_MATHFN (POW) | 2063 CASE_MATHFN (POW) |
1912 CASE_MATHFN (POWI) | 2064 CASE_MATHFN (POWI) |
1913 CASE_MATHFN (POW10) | 2065 CASE_MATHFN (POW10) |
1914 CASE_MATHFN (REMAINDER) | 2066 CASE_MATHFN (REMAINDER) |
1915 CASE_MATHFN (REMQUO) | 2067 CASE_MATHFN (REMQUO) |
1916 CASE_MATHFN (RINT) | 2068 CASE_MATHFN_FLOATN (RINT) |
1917 CASE_MATHFN (ROUND) | 2069 CASE_MATHFN_FLOATN (ROUND) |
1918 CASE_MATHFN (SCALB) | 2070 CASE_MATHFN (SCALB) |
1919 CASE_MATHFN (SCALBLN) | 2071 CASE_MATHFN (SCALBLN) |
1920 CASE_MATHFN (SCALBN) | 2072 CASE_MATHFN (SCALBN) |
1921 CASE_MATHFN (SIGNBIT) | 2073 CASE_MATHFN (SIGNBIT) |
1922 CASE_MATHFN (SIGNIFICAND) | 2074 CASE_MATHFN (SIGNIFICAND) |
1923 CASE_MATHFN (SIN) | 2075 CASE_MATHFN (SIN) |
1924 CASE_MATHFN (SINCOS) | 2076 CASE_MATHFN (SINCOS) |
1925 CASE_MATHFN (SINH) | 2077 CASE_MATHFN (SINH) |
1926 CASE_MATHFN (SQRT) | 2078 CASE_MATHFN_FLOATN (SQRT) |
1927 CASE_MATHFN (TAN) | 2079 CASE_MATHFN (TAN) |
1928 CASE_MATHFN (TANH) | 2080 CASE_MATHFN (TANH) |
1929 CASE_MATHFN (TGAMMA) | 2081 CASE_MATHFN (TGAMMA) |
1930 CASE_MATHFN (TRUNC) | 2082 CASE_MATHFN_FLOATN (TRUNC) |
1931 CASE_MATHFN (Y0) | 2083 CASE_MATHFN (Y0) |
1932 CASE_MATHFN (Y1) | 2084 CASE_MATHFN (Y1) |
1933 CASE_MATHFN (YN) | 2085 CASE_MATHFN (YN) |
1934 | 2086 |
1935 default: | 2087 default: |
1936 return END_BUILTINS; | 2088 return END_BUILTINS; |
1937 } | 2089 } |
1938 | 2090 |
1939 if (TYPE_MAIN_VARIANT (type) == double_type_node) | 2091 mtype = TYPE_MAIN_VARIANT (type); |
2092 if (mtype == double_type_node) | |
1940 return fcode; | 2093 return fcode; |
1941 else if (TYPE_MAIN_VARIANT (type) == float_type_node) | 2094 else if (mtype == float_type_node) |
1942 return fcodef; | 2095 return fcodef; |
1943 else if (TYPE_MAIN_VARIANT (type) == long_double_type_node) | 2096 else if (mtype == long_double_type_node) |
1944 return fcodel; | 2097 return fcodel; |
2098 else if (mtype == float16_type_node) | |
2099 return fcodef16; | |
2100 else if (mtype == float32_type_node) | |
2101 return fcodef32; | |
2102 else if (mtype == float64_type_node) | |
2103 return fcodef64; | |
2104 else if (mtype == float128_type_node) | |
2105 return fcodef128; | |
2106 else if (mtype == float32x_type_node) | |
2107 return fcodef32x; | |
2108 else if (mtype == float64x_type_node) | |
2109 return fcodef64x; | |
2110 else if (mtype == float128x_type_node) | |
2111 return fcodef128x; | |
1945 else | 2112 else |
1946 return END_BUILTINS; | 2113 return END_BUILTINS; |
1947 } | 2114 } |
1948 | 2115 |
1949 /* Return mathematic function equivalent to FN but operating directly on TYPE, | 2116 /* Return mathematic function equivalent to FN but operating directly on TYPE, |
1993 tree return_type = TREE_TYPE (TREE_TYPE (fndecl)); | 2160 tree return_type = TREE_TYPE (TREE_TYPE (fndecl)); |
1994 switch (DECL_FUNCTION_CODE (fndecl)) | 2161 switch (DECL_FUNCTION_CODE (fndecl)) |
1995 { | 2162 { |
1996 #define DEF_INTERNAL_FLT_FN(NAME, FLAGS, OPTAB, TYPE) \ | 2163 #define DEF_INTERNAL_FLT_FN(NAME, FLAGS, OPTAB, TYPE) \ |
1997 CASE_FLT_FN (BUILT_IN_##NAME): return IFN_##NAME; | 2164 CASE_FLT_FN (BUILT_IN_##NAME): return IFN_##NAME; |
2165 #define DEF_INTERNAL_FLT_FLOATN_FN(NAME, FLAGS, OPTAB, TYPE) \ | |
2166 CASE_FLT_FN (BUILT_IN_##NAME): return IFN_##NAME; \ | |
2167 CASE_FLT_FN_FLOATN_NX (BUILT_IN_##NAME): return IFN_##NAME; | |
1998 #define DEF_INTERNAL_INT_FN(NAME, FLAGS, OPTAB, TYPE) \ | 2168 #define DEF_INTERNAL_INT_FN(NAME, FLAGS, OPTAB, TYPE) \ |
1999 CASE_INT_FN (BUILT_IN_##NAME): return IFN_##NAME; | 2169 CASE_INT_FN (BUILT_IN_##NAME): return IFN_##NAME; |
2000 #include "internal-fn.def" | 2170 #include "internal-fn.def" |
2001 | 2171 |
2002 CASE_FLT_FN (BUILT_IN_POW10): | 2172 CASE_FLT_FN (BUILT_IN_POW10): |
2066 arg2 = CALL_EXPR_ARG (exp, 2); | 2236 arg2 = CALL_EXPR_ARG (exp, 2); |
2067 | 2237 |
2068 switch (DECL_FUNCTION_CODE (fndecl)) | 2238 switch (DECL_FUNCTION_CODE (fndecl)) |
2069 { | 2239 { |
2070 CASE_FLT_FN (BUILT_IN_FMA): | 2240 CASE_FLT_FN (BUILT_IN_FMA): |
2241 CASE_FLT_FN_FLOATN_NX (BUILT_IN_FMA): | |
2071 builtin_optab = fma_optab; break; | 2242 builtin_optab = fma_optab; break; |
2072 default: | 2243 default: |
2073 gcc_unreachable (); | 2244 gcc_unreachable (); |
2074 } | 2245 } |
2075 | 2246 |
2774 | 2945 |
2775 return target; | 2946 return target; |
2776 } | 2947 } |
2777 | 2948 |
2778 /* Expand expression EXP which is a call to the strlen builtin. Return | 2949 /* Expand expression EXP which is a call to the strlen builtin. Return |
2779 NULL_RTX if we failed the caller should emit a normal call, otherwise | 2950 NULL_RTX if we failed and the caller should emit a normal call, otherwise |
2780 try to get the result in TARGET, if convenient. */ | 2951 try to get the result in TARGET, if convenient. */ |
2781 | 2952 |
2782 static rtx | 2953 static rtx |
2783 expand_builtin_strlen (tree exp, rtx target, | 2954 expand_builtin_strlen (tree exp, rtx target, |
2784 machine_mode target_mode) | 2955 machine_mode target_mode) |
2785 { | 2956 { |
2786 if (!validate_arglist (exp, POINTER_TYPE, VOID_TYPE)) | 2957 if (!validate_arglist (exp, POINTER_TYPE, VOID_TYPE)) |
2787 return NULL_RTX; | 2958 return NULL_RTX; |
2959 | |
2960 struct expand_operand ops[4]; | |
2961 rtx pat; | |
2962 tree len; | |
2963 tree src = CALL_EXPR_ARG (exp, 0); | |
2964 rtx src_reg; | |
2965 rtx_insn *before_strlen; | |
2966 machine_mode insn_mode; | |
2967 enum insn_code icode = CODE_FOR_nothing; | |
2968 unsigned int align; | |
2969 | |
2970 /* If the length can be computed at compile-time, return it. */ | |
2971 len = c_strlen (src, 0); | |
2972 if (len) | |
2973 return expand_expr (len, target, target_mode, EXPAND_NORMAL); | |
2974 | |
2975 /* If the length can be computed at compile-time and is constant | |
2976 integer, but there are side-effects in src, evaluate | |
2977 src for side-effects, then return len. | |
2978 E.g. x = strlen (i++ ? "xfoo" + 1 : "bar"); | |
2979 can be optimized into: i++; x = 3; */ | |
2980 len = c_strlen (src, 1); | |
2981 if (len && TREE_CODE (len) == INTEGER_CST) | |
2982 { | |
2983 expand_expr (src, const0_rtx, VOIDmode, EXPAND_NORMAL); | |
2984 return expand_expr (len, target, target_mode, EXPAND_NORMAL); | |
2985 } | |
2986 | |
2987 align = get_pointer_alignment (src) / BITS_PER_UNIT; | |
2988 | |
2989 /* If SRC is not a pointer type, don't do this operation inline. */ | |
2990 if (align == 0) | |
2991 return NULL_RTX; | |
2992 | |
2993 /* Bail out if we can't compute strlen in the right mode. */ | |
2994 FOR_EACH_MODE_FROM (insn_mode, target_mode) | |
2995 { | |
2996 icode = optab_handler (strlen_optab, insn_mode); | |
2997 if (icode != CODE_FOR_nothing) | |
2998 break; | |
2999 } | |
3000 if (insn_mode == VOIDmode) | |
3001 return NULL_RTX; | |
3002 | |
3003 /* Make a place to hold the source address. We will not expand | |
3004 the actual source until we are sure that the expansion will | |
3005 not fail -- there are trees that cannot be expanded twice. */ | |
3006 src_reg = gen_reg_rtx (Pmode); | |
3007 | |
3008 /* Mark the beginning of the strlen sequence so we can emit the | |
3009 source operand later. */ | |
3010 before_strlen = get_last_insn (); | |
3011 | |
3012 create_output_operand (&ops[0], target, insn_mode); | |
3013 create_fixed_operand (&ops[1], gen_rtx_MEM (BLKmode, src_reg)); | |
3014 create_integer_operand (&ops[2], 0); | |
3015 create_integer_operand (&ops[3], align); | |
3016 if (!maybe_expand_insn (icode, 4, ops)) | |
3017 return NULL_RTX; | |
3018 | |
3019 /* Check to see if the argument was declared attribute nonstring | |
3020 and if so, issue a warning since at this point it's not known | |
3021 to be nul-terminated. */ | |
3022 maybe_warn_nonstring_arg (get_callee_fndecl (exp), exp); | |
3023 | |
3024 /* Now that we are assured of success, expand the source. */ | |
3025 start_sequence (); | |
3026 pat = expand_expr (src, src_reg, Pmode, EXPAND_NORMAL); | |
3027 if (pat != src_reg) | |
3028 { | |
3029 #ifdef POINTERS_EXTEND_UNSIGNED | |
3030 if (GET_MODE (pat) != Pmode) | |
3031 pat = convert_to_mode (Pmode, pat, | |
3032 POINTERS_EXTEND_UNSIGNED); | |
3033 #endif | |
3034 emit_move_insn (src_reg, pat); | |
3035 } | |
3036 pat = get_insns (); | |
3037 end_sequence (); | |
3038 | |
3039 if (before_strlen) | |
3040 emit_insn_after (pat, before_strlen); | |
2788 else | 3041 else |
2789 { | 3042 emit_insn_before (pat, get_insns ()); |
2790 struct expand_operand ops[4]; | 3043 |
2791 rtx pat; | 3044 /* Return the value in the proper mode for this function. */ |
2792 tree len; | 3045 if (GET_MODE (ops[0].value) == target_mode) |
2793 tree src = CALL_EXPR_ARG (exp, 0); | 3046 target = ops[0].value; |
2794 rtx src_reg; | 3047 else if (target != 0) |
2795 rtx_insn *before_strlen; | 3048 convert_move (target, ops[0].value, 0); |
2796 machine_mode insn_mode; | 3049 else |
2797 enum insn_code icode = CODE_FOR_nothing; | 3050 target = convert_to_mode (target_mode, ops[0].value, 0); |
2798 unsigned int align; | 3051 |
2799 | 3052 return target; |
2800 /* If the length can be computed at compile-time, return it. */ | 3053 } |
2801 len = c_strlen (src, 0); | 3054 |
2802 if (len) | 3055 /* Expand call EXP to the strnlen built-in, returning the result |
2803 return expand_expr (len, target, target_mode, EXPAND_NORMAL); | 3056 and setting it in TARGET. Otherwise return NULL_RTX on failure. */ |
2804 | 3057 |
2805 /* If the length can be computed at compile-time and is constant | 3058 static rtx |
2806 integer, but there are side-effects in src, evaluate | 3059 expand_builtin_strnlen (tree exp, rtx target, machine_mode target_mode) |
2807 src for side-effects, then return len. | 3060 { |
2808 E.g. x = strlen (i++ ? "xfoo" + 1 : "bar"); | 3061 if (!validate_arglist (exp, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE)) |
2809 can be optimized into: i++; x = 3; */ | 3062 return NULL_RTX; |
2810 len = c_strlen (src, 1); | 3063 |
2811 if (len && TREE_CODE (len) == INTEGER_CST) | 3064 tree src = CALL_EXPR_ARG (exp, 0); |
3065 tree bound = CALL_EXPR_ARG (exp, 1); | |
3066 | |
3067 if (!bound) | |
3068 return NULL_RTX; | |
3069 | |
3070 location_t loc = UNKNOWN_LOCATION; | |
3071 if (EXPR_HAS_LOCATION (exp)) | |
3072 loc = EXPR_LOCATION (exp); | |
3073 | |
3074 tree maxobjsize = max_object_size (); | |
3075 tree func = get_callee_fndecl (exp); | |
3076 | |
3077 /* FIXME: Change c_strlen() to return sizetype instead of ssizetype | |
3078 so these conversions aren't necessary. */ | |
3079 c_strlen_data data; | |
3080 memset (&data, 0, sizeof (c_strlen_data)); | |
3081 tree len = c_strlen (src, 0, &data, 1); | |
3082 if (len) | |
3083 len = fold_convert_loc (loc, TREE_TYPE (bound), len); | |
3084 | |
3085 if (TREE_CODE (bound) == INTEGER_CST) | |
3086 { | |
3087 if (!TREE_NO_WARNING (exp) | |
3088 && tree_int_cst_lt (maxobjsize, bound) | |
3089 && warning_at (loc, OPT_Wstringop_overflow_, | |
3090 "%K%qD specified bound %E " | |
3091 "exceeds maximum object size %E", | |
3092 exp, func, bound, maxobjsize)) | |
3093 TREE_NO_WARNING (exp) = true; | |
3094 | |
3095 bool exact = true; | |
3096 if (!len || TREE_CODE (len) != INTEGER_CST) | |
2812 { | 3097 { |
2813 expand_expr (src, const0_rtx, VOIDmode, EXPAND_NORMAL); | 3098 /* Clear EXACT if LEN may be less than SRC suggests, |
2814 return expand_expr (len, target, target_mode, EXPAND_NORMAL); | 3099 such as in |
3100 strnlen (&a[i], sizeof a) | |
3101 where the value of i is unknown. Unless i's value is | |
3102 zero, the call is unsafe because the bound is greater. */ | |
3103 data.decl = unterminated_array (src, &len, &exact); | |
3104 if (!data.decl) | |
3105 return NULL_RTX; | |
2815 } | 3106 } |
2816 | 3107 |
2817 align = get_pointer_alignment (src) / BITS_PER_UNIT; | 3108 if (data.decl |
2818 | 3109 && !TREE_NO_WARNING (exp) |
2819 /* If SRC is not a pointer type, don't do this operation inline. */ | 3110 && ((tree_int_cst_lt (len, bound)) |
2820 if (align == 0) | 3111 || !exact)) |
3112 { | |
3113 location_t warnloc | |
3114 = expansion_point_location_if_in_system_header (loc); | |
3115 | |
3116 if (warning_at (warnloc, OPT_Wstringop_overflow_, | |
3117 exact | |
3118 ? G_("%K%qD specified bound %E exceeds the size %E " | |
3119 "of unterminated array") | |
3120 : G_("%K%qD specified bound %E may exceed the size " | |
3121 "of at most %E of unterminated array"), | |
3122 exp, func, bound, len)) | |
3123 { | |
3124 inform (DECL_SOURCE_LOCATION (data.decl), | |
3125 "referenced argument declared here"); | |
3126 TREE_NO_WARNING (exp) = true; | |
3127 return NULL_RTX; | |
3128 } | |
3129 } | |
3130 | |
3131 if (!len) | |
2821 return NULL_RTX; | 3132 return NULL_RTX; |
2822 | 3133 |
2823 /* Bail out if we can't compute strlen in the right mode. */ | 3134 len = fold_build2_loc (loc, MIN_EXPR, size_type_node, len, bound); |
2824 FOR_EACH_MODE_FROM (insn_mode, target_mode) | 3135 return expand_expr (len, target, target_mode, EXPAND_NORMAL); |
3136 } | |
3137 | |
3138 if (TREE_CODE (bound) != SSA_NAME) | |
3139 return NULL_RTX; | |
3140 | |
3141 wide_int min, max; | |
3142 enum value_range_kind rng = get_range_info (bound, &min, &max); | |
3143 if (rng != VR_RANGE) | |
3144 return NULL_RTX; | |
3145 | |
3146 if (!TREE_NO_WARNING (exp) | |
3147 && wi::ltu_p (wi::to_wide (maxobjsize), min) | |
3148 && warning_at (loc, OPT_Wstringop_overflow_, | |
3149 "%K%qD specified bound [%wu, %wu] " | |
3150 "exceeds maximum object size %E", | |
3151 exp, func, min.to_uhwi (), max.to_uhwi (), maxobjsize)) | |
3152 TREE_NO_WARNING (exp) = true; | |
3153 | |
3154 bool exact = true; | |
3155 if (!len || TREE_CODE (len) != INTEGER_CST) | |
3156 { | |
3157 data.decl = unterminated_array (src, &len, &exact); | |
3158 if (!data.decl) | |
3159 return NULL_RTX; | |
3160 } | |
3161 | |
3162 if (data.decl | |
3163 && !TREE_NO_WARNING (exp) | |
3164 && (wi::ltu_p (wi::to_wide (len), min) | |
3165 || !exact)) | |
3166 { | |
3167 location_t warnloc | |
3168 = expansion_point_location_if_in_system_header (loc); | |
3169 | |
3170 if (warning_at (warnloc, OPT_Wstringop_overflow_, | |
3171 exact | |
3172 ? G_("%K%qD specified bound [%wu, %wu] exceeds " | |
3173 "the size %E of unterminated array") | |
3174 : G_("%K%qD specified bound [%wu, %wu] may exceed " | |
3175 "the size of at most %E of unterminated array"), | |
3176 exp, func, min.to_uhwi (), max.to_uhwi (), len)) | |
2825 { | 3177 { |
2826 icode = optab_handler (strlen_optab, insn_mode); | 3178 inform (DECL_SOURCE_LOCATION (data.decl), |
2827 if (icode != CODE_FOR_nothing) | 3179 "referenced argument declared here"); |
2828 break; | 3180 TREE_NO_WARNING (exp) = true; |
2829 } | 3181 } |
2830 if (insn_mode == VOIDmode) | 3182 } |
2831 return NULL_RTX; | 3183 |
2832 | 3184 if (data.decl) |
2833 /* Make a place to hold the source address. We will not expand | 3185 return NULL_RTX; |
2834 the actual source until we are sure that the expansion will | 3186 |
2835 not fail -- there are trees that cannot be expanded twice. */ | 3187 if (wi::gtu_p (min, wi::to_wide (len))) |
2836 src_reg = gen_reg_rtx (Pmode); | 3188 return expand_expr (len, target, target_mode, EXPAND_NORMAL); |
2837 | 3189 |
2838 /* Mark the beginning of the strlen sequence so we can emit the | 3190 len = fold_build2_loc (loc, MIN_EXPR, TREE_TYPE (len), len, bound); |
2839 source operand later. */ | 3191 return expand_expr (len, target, target_mode, EXPAND_NORMAL); |
2840 before_strlen = get_last_insn (); | |
2841 | |
2842 create_output_operand (&ops[0], target, insn_mode); | |
2843 create_fixed_operand (&ops[1], gen_rtx_MEM (BLKmode, src_reg)); | |
2844 create_integer_operand (&ops[2], 0); | |
2845 create_integer_operand (&ops[3], align); | |
2846 if (!maybe_expand_insn (icode, 4, ops)) | |
2847 return NULL_RTX; | |
2848 | |
2849 /* Now that we are assured of success, expand the source. */ | |
2850 start_sequence (); | |
2851 pat = expand_expr (src, src_reg, Pmode, EXPAND_NORMAL); | |
2852 if (pat != src_reg) | |
2853 { | |
2854 #ifdef POINTERS_EXTEND_UNSIGNED | |
2855 if (GET_MODE (pat) != Pmode) | |
2856 pat = convert_to_mode (Pmode, pat, | |
2857 POINTERS_EXTEND_UNSIGNED); | |
2858 #endif | |
2859 emit_move_insn (src_reg, pat); | |
2860 } | |
2861 pat = get_insns (); | |
2862 end_sequence (); | |
2863 | |
2864 if (before_strlen) | |
2865 emit_insn_after (pat, before_strlen); | |
2866 else | |
2867 emit_insn_before (pat, get_insns ()); | |
2868 | |
2869 /* Return the value in the proper mode for this function. */ | |
2870 if (GET_MODE (ops[0].value) == target_mode) | |
2871 target = ops[0].value; | |
2872 else if (target != 0) | |
2873 convert_move (target, ops[0].value, 0); | |
2874 else | |
2875 target = convert_to_mode (target_mode, ops[0].value, 0); | |
2876 | |
2877 return target; | |
2878 } | |
2879 } | 3192 } |
2880 | 3193 |
2881 /* Callback routine for store_by_pieces. Read GET_MODE_BITSIZE (MODE) | 3194 /* Callback routine for store_by_pieces. Read GET_MODE_BITSIZE (MODE) |
2882 bytes from constant string DATA + OFFSET and return it as target | 3195 bytes from constant string DATA + OFFSET and return it as target |
2883 constant. */ | 3196 constant. */ |
2912 return; | 3225 return; |
2913 } | 3226 } |
2914 else | 3227 else |
2915 { | 3228 { |
2916 wide_int min, max; | 3229 wide_int min, max; |
2917 enum value_range_type range_type = VR_UNDEFINED; | 3230 enum value_range_kind range_type = VR_UNDEFINED; |
2918 | 3231 |
2919 /* Determine bounds from the type. */ | 3232 /* Determine bounds from the type. */ |
2920 if (tree_fits_uhwi_p (TYPE_MIN_VALUE (TREE_TYPE (len)))) | 3233 if (tree_fits_uhwi_p (TYPE_MIN_VALUE (TREE_TYPE (len)))) |
2921 *min_size = tree_to_uhwi (TYPE_MIN_VALUE (TREE_TYPE (len))); | 3234 *min_size = tree_to_uhwi (TYPE_MIN_VALUE (TREE_TYPE (len))); |
2922 else | 3235 else |
2962 GET_MODE_MASK (GET_MODE (len_rtx))); | 3275 GET_MODE_MASK (GET_MODE (len_rtx))); |
2963 } | 3276 } |
2964 | 3277 |
2965 /* Try to verify that the sizes and lengths of the arguments to a string | 3278 /* Try to verify that the sizes and lengths of the arguments to a string |
2966 manipulation function given by EXP are within valid bounds and that | 3279 manipulation function given by EXP are within valid bounds and that |
2967 the operation does not lead to buffer overflow. Arguments other than | 3280 the operation does not lead to buffer overflow or read past the end. |
2968 EXP may be null. When non-null, the arguments have the following | 3281 Arguments other than EXP may be null. When non-null, the arguments |
2969 meaning: | 3282 have the following meaning: |
2970 SIZE is the user-supplied size argument to the function (such as in | 3283 DST is the destination of a copy call or NULL otherwise. |
2971 memcpy(d, s, SIZE) or strncpy(d, s, SIZE). It specifies the exact | 3284 SRC is the source of a copy call or NULL otherwise. |
2972 number of bytes to write. | 3285 DSTWRITE is the number of bytes written into the destination obtained |
2973 MAXLEN is the user-supplied bound on the length of the source sequence | 3286 from the user-supplied size argument to the function (such as in |
3287 memcpy(DST, SRCs, DSTWRITE) or strncpy(DST, DRC, DSTWRITE). | |
3288 MAXREAD is the user-supplied bound on the length of the source sequence | |
2974 (such as in strncat(d, s, N). It specifies the upper limit on the number | 3289 (such as in strncat(d, s, N). It specifies the upper limit on the number |
2975 of bytes to write. | 3290 of bytes to write. If NULL, it's taken to be the same as DSTWRITE. |
2976 SRC is the source string (such as in strcpy(d, s)) when the expression | 3291 SRCSTR is the source string (such as in strcpy(DST, SRC)) when the |
2977 EXP is a string function call (as opposed to a memory call like memcpy). | 3292 expression EXP is a string function call (as opposed to a memory call |
2978 As an exception, SRC can also be an integer denoting the precomputed | 3293 like memcpy). As an exception, SRCSTR can also be an integer denoting |
2979 size of the source string or object (for functions like memcpy). | 3294 the precomputed size of the source string or object (for functions like |
2980 OBJSIZE is the size of the destination object specified by the last | 3295 memcpy). |
3296 DSTSIZE is the size of the destination object specified by the last | |
2981 argument to the _chk builtins, typically resulting from the expansion | 3297 argument to the _chk builtins, typically resulting from the expansion |
2982 of __builtin_object_size (such as in __builtin___strcpy_chk(d, s, | 3298 of __builtin_object_size (such as in __builtin___strcpy_chk(DST, SRC, |
2983 OBJSIZE). | 3299 DSTSIZE). |
2984 | 3300 |
2985 When SIZE is null LEN is checked to verify that it doesn't exceed | 3301 When DSTWRITE is null LEN is checked to verify that it doesn't exceed |
2986 SIZE_MAX. | 3302 SIZE_MAX. |
2987 | 3303 |
2988 If the call is successfully verified as safe from buffer overflow | 3304 If the call is successfully verified as safe return true, otherwise |
2989 the function returns true, otherwise false.. */ | 3305 return false. */ |
2990 | 3306 |
2991 static bool | 3307 static bool |
2992 check_sizes (int opt, tree exp, tree size, tree maxlen, tree src, tree objsize) | 3308 check_access (tree exp, tree, tree, tree dstwrite, |
2993 { | 3309 tree maxread, tree srcstr, tree dstsize) |
3310 { | |
3311 int opt = OPT_Wstringop_overflow_; | |
3312 | |
2994 /* The size of the largest object is half the address space, or | 3313 /* The size of the largest object is half the address space, or |
2995 SSIZE_MAX. (This is way too permissive.) */ | 3314 PTRDIFF_MAX. (This is way too permissive.) */ |
2996 tree maxobjsize = TYPE_MAX_VALUE (ssizetype); | 3315 tree maxobjsize = max_object_size (); |
2997 | 3316 |
3317 /* Either the length of the source string for string functions or | |
3318 the size of the source object for raw memory functions. */ | |
2998 tree slen = NULL_TREE; | 3319 tree slen = NULL_TREE; |
2999 | 3320 |
3000 tree range[2] = { NULL_TREE, NULL_TREE }; | 3321 tree range[2] = { NULL_TREE, NULL_TREE }; |
3001 | 3322 |
3002 /* Set to true when the exact number of bytes written by a string | 3323 /* Set to true when the exact number of bytes written by a string |
3003 function like strcpy is not known and the only thing that is | 3324 function like strcpy is not known and the only thing that is |
3004 known is that it must be at least one (for the terminating nul). */ | 3325 known is that it must be at least one (for the terminating nul). */ |
3005 bool at_least_one = false; | 3326 bool at_least_one = false; |
3006 if (src) | 3327 if (srcstr) |
3007 { | 3328 { |
3008 /* SRC is normally a pointer to string but as a special case | 3329 /* SRCSTR is normally a pointer to string but as a special case |
3009 it can be an integer denoting the length of a string. */ | 3330 it can be an integer denoting the length of a string. */ |
3010 if (POINTER_TYPE_P (TREE_TYPE (src))) | 3331 if (POINTER_TYPE_P (TREE_TYPE (srcstr))) |
3011 { | 3332 { |
3012 /* Try to determine the range of lengths the source string | 3333 /* Try to determine the range of lengths the source string |
3013 refers to. If it can be determined and is less than | 3334 refers to. If it can be determined and is less than |
3014 the upper bound given by MAXLEN add one to it for | 3335 the upper bound given by MAXREAD add one to it for |
3015 the terminating nul. Otherwise, set it to one for | 3336 the terminating nul. Otherwise, set it to one for |
3016 the same reason, or to MAXLEN as appropriate. */ | 3337 the same reason, or to MAXREAD as appropriate. */ |
3017 get_range_strlen (src, range); | 3338 get_range_strlen (srcstr, range); |
3018 if (range[0] && (!maxlen || TREE_CODE (maxlen) == INTEGER_CST)) | 3339 if (range[0] && (!maxread || TREE_CODE (maxread) == INTEGER_CST)) |
3019 { | 3340 { |
3020 if (maxlen && tree_int_cst_le (maxlen, range[0])) | 3341 if (maxread && tree_int_cst_le (maxread, range[0])) |
3021 range[0] = range[1] = maxlen; | 3342 range[0] = range[1] = maxread; |
3022 else | 3343 else |
3023 range[0] = fold_build2 (PLUS_EXPR, size_type_node, | 3344 range[0] = fold_build2 (PLUS_EXPR, size_type_node, |
3024 range[0], size_one_node); | 3345 range[0], size_one_node); |
3025 | 3346 |
3026 if (maxlen && tree_int_cst_le (maxlen, range[1])) | 3347 if (maxread && tree_int_cst_le (maxread, range[1])) |
3027 range[1] = maxlen; | 3348 range[1] = maxread; |
3028 else if (!integer_all_onesp (range[1])) | 3349 else if (!integer_all_onesp (range[1])) |
3029 range[1] = fold_build2 (PLUS_EXPR, size_type_node, | 3350 range[1] = fold_build2 (PLUS_EXPR, size_type_node, |
3030 range[1], size_one_node); | 3351 range[1], size_one_node); |
3031 | 3352 |
3032 slen = range[0]; | 3353 slen = range[0]; |
3036 at_least_one = true; | 3357 at_least_one = true; |
3037 slen = size_one_node; | 3358 slen = size_one_node; |
3038 } | 3359 } |
3039 } | 3360 } |
3040 else | 3361 else |
3041 slen = src; | 3362 slen = srcstr; |
3042 } | 3363 } |
3043 | 3364 |
3044 if (!size && !maxlen) | 3365 if (!dstwrite && !maxread) |
3045 { | 3366 { |
3046 /* When the only available piece of data is the object size | 3367 /* When the only available piece of data is the object size |
3047 there is nothing to do. */ | 3368 there is nothing to do. */ |
3048 if (!slen) | 3369 if (!slen) |
3049 return true; | 3370 return true; |
3050 | 3371 |
3051 /* Otherwise, when the length of the source sequence is known | 3372 /* Otherwise, when the length of the source sequence is known |
3052 (as with with strlen), set SIZE to it. */ | 3373 (as with strlen), set DSTWRITE to it. */ |
3053 if (!range[0]) | 3374 if (!range[0]) |
3054 size = slen; | 3375 dstwrite = slen; |
3055 } | 3376 } |
3056 | 3377 |
3057 if (!objsize) | 3378 if (!dstsize) |
3058 objsize = maxobjsize; | 3379 dstsize = maxobjsize; |
3059 | 3380 |
3060 /* The SIZE is exact if it's non-null, constant, and in range of | 3381 if (dstwrite) |
3061 unsigned HOST_WIDE_INT. */ | 3382 get_size_range (dstwrite, range); |
3062 bool exactsize = size && tree_fits_uhwi_p (size); | 3383 |
3063 | 3384 tree func = get_callee_fndecl (exp); |
3064 if (size) | |
3065 get_size_range (size, range); | |
3066 | 3385 |
3067 /* First check the number of bytes to be written against the maximum | 3386 /* First check the number of bytes to be written against the maximum |
3068 object size. */ | 3387 object size. */ |
3069 if (range[0] && tree_int_cst_lt (maxobjsize, range[0])) | 3388 if (range[0] |
3070 { | 3389 && TREE_CODE (range[0]) == INTEGER_CST |
3390 && tree_int_cst_lt (maxobjsize, range[0])) | |
3391 { | |
3392 if (TREE_NO_WARNING (exp)) | |
3393 return false; | |
3394 | |
3071 location_t loc = tree_nonartificial_location (exp); | 3395 location_t loc = tree_nonartificial_location (exp); |
3072 loc = expansion_point_location_if_in_system_header (loc); | 3396 loc = expansion_point_location_if_in_system_header (loc); |
3073 | 3397 |
3398 bool warned; | |
3074 if (range[0] == range[1]) | 3399 if (range[0] == range[1]) |
3075 warning_at (loc, opt, | 3400 warned = warning_at (loc, opt, |
3076 "%K%qD specified size %E " | 3401 "%K%qD specified size %E " |
3077 "exceeds maximum object size %E", | 3402 "exceeds maximum object size %E", |
3078 exp, get_callee_fndecl (exp), range[0], maxobjsize); | 3403 exp, func, range[0], maxobjsize); |
3079 else | 3404 else |
3080 warning_at (loc, opt, | 3405 warned = warning_at (loc, opt, |
3081 "%K%qD specified size between %E and %E " | 3406 "%K%qD specified size between %E and %E " |
3082 "exceeds maximum object size %E", | 3407 "exceeds maximum object size %E", |
3083 exp, get_callee_fndecl (exp), | 3408 exp, func, |
3084 range[0], range[1], maxobjsize); | 3409 range[0], range[1], maxobjsize); |
3410 if (warned) | |
3411 TREE_NO_WARNING (exp) = true; | |
3412 | |
3085 return false; | 3413 return false; |
3086 } | 3414 } |
3415 | |
3416 /* The number of bytes to write is "exact" if DSTWRITE is non-null, | |
3417 constant, and in range of unsigned HOST_WIDE_INT. */ | |
3418 bool exactwrite = dstwrite && tree_fits_uhwi_p (dstwrite); | |
3087 | 3419 |
3088 /* Next check the number of bytes to be written against the destination | 3420 /* Next check the number of bytes to be written against the destination |
3089 object size. */ | 3421 object size. */ |
3090 if (range[0] || !exactsize || integer_all_onesp (size)) | 3422 if (range[0] || !exactwrite || integer_all_onesp (dstwrite)) |
3091 { | 3423 { |
3092 if (range[0] | 3424 if (range[0] |
3093 && ((tree_fits_uhwi_p (objsize) | 3425 && TREE_CODE (range[0]) == INTEGER_CST |
3094 && tree_int_cst_lt (objsize, range[0])) | 3426 && ((tree_fits_uhwi_p (dstsize) |
3095 || (tree_fits_uhwi_p (size) | 3427 && tree_int_cst_lt (dstsize, range[0])) |
3096 && tree_int_cst_lt (size, range[0])))) | 3428 || (dstwrite |
3429 && tree_fits_uhwi_p (dstwrite) | |
3430 && tree_int_cst_lt (dstwrite, range[0])))) | |
3097 { | 3431 { |
3432 if (TREE_NO_WARNING (exp)) | |
3433 return false; | |
3434 | |
3098 location_t loc = tree_nonartificial_location (exp); | 3435 location_t loc = tree_nonartificial_location (exp); |
3099 loc = expansion_point_location_if_in_system_header (loc); | 3436 loc = expansion_point_location_if_in_system_header (loc); |
3100 | 3437 |
3101 if (size == slen && at_least_one) | 3438 if (dstwrite == slen && at_least_one) |
3102 { | 3439 { |
3103 /* This is a call to strcpy with a destination of 0 size | 3440 /* This is a call to strcpy with a destination of 0 size |
3104 and a source of unknown length. The call will write | 3441 and a source of unknown length. The call will write |
3105 at least one byte past the end of the destination. */ | 3442 at least one byte past the end of the destination. */ |
3106 warning_at (loc, opt, | 3443 warning_at (loc, opt, |
3107 "%K%qD writing %E or more bytes into a region " | 3444 "%K%qD writing %E or more bytes into a region " |
3108 "of size %E overflows the destination", | 3445 "of size %E overflows the destination", |
3109 exp, get_callee_fndecl (exp), range[0], objsize); | 3446 exp, func, range[0], dstsize); |
3110 } | 3447 } |
3111 else if (tree_int_cst_equal (range[0], range[1])) | 3448 else if (tree_int_cst_equal (range[0], range[1])) |
3112 warning_at (loc, opt, | 3449 warning_n (loc, opt, tree_to_uhwi (range[0]), |
3113 (integer_onep (range[0]) | 3450 "%K%qD writing %E byte into a region " |
3114 ? G_("%K%qD writing %E byte into a region " | 3451 "of size %E overflows the destination", |
3115 "of size %E overflows the destination") | 3452 "%K%qD writing %E bytes into a region " |
3116 : G_("%K%qD writing %E bytes into a region " | 3453 "of size %E overflows the destination", |
3117 "of size %E overflows the destination")), | 3454 exp, func, range[0], dstsize); |
3118 exp, get_callee_fndecl (exp), range[0], objsize); | |
3119 else if (tree_int_cst_sign_bit (range[1])) | 3455 else if (tree_int_cst_sign_bit (range[1])) |
3120 { | 3456 { |
3121 /* Avoid printing the upper bound if it's invalid. */ | 3457 /* Avoid printing the upper bound if it's invalid. */ |
3122 warning_at (loc, opt, | 3458 warning_at (loc, opt, |
3123 "%K%qD writing %E or more bytes into a region " | 3459 "%K%qD writing %E or more bytes into a region " |
3124 "of size %E overflows the destination", | 3460 "of size %E overflows the destination", |
3125 exp, get_callee_fndecl (exp), range[0], objsize); | 3461 exp, func, range[0], dstsize); |
3126 } | 3462 } |
3127 else | 3463 else |
3128 warning_at (loc, opt, | 3464 warning_at (loc, opt, |
3129 "%K%qD writing between %E and %E bytes into " | 3465 "%K%qD writing between %E and %E bytes into " |
3130 "a region of size %E overflows the destination", | 3466 "a region of size %E overflows the destination", |
3131 exp, get_callee_fndecl (exp), range[0], range[1], | 3467 exp, func, range[0], range[1], |
3132 objsize); | 3468 dstsize); |
3133 | 3469 |
3134 /* Return error when an overflow has been detected. */ | 3470 /* Return error when an overflow has been detected. */ |
3135 return false; | 3471 return false; |
3136 } | 3472 } |
3137 } | 3473 } |
3138 | 3474 |
3139 /* Check the maximum length of the source sequence against the size | 3475 /* Check the maximum length of the source sequence against the size |
3140 of the destination object if known, or against the maximum size | 3476 of the destination object if known, or against the maximum size |
3141 of an object. */ | 3477 of an object. */ |
3142 if (maxlen) | 3478 if (maxread) |
3143 { | 3479 { |
3144 get_size_range (maxlen, range); | 3480 get_size_range (maxread, range); |
3145 | 3481 |
3146 if (range[0] && objsize && tree_fits_uhwi_p (objsize)) | 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)) | |
3147 { | 3487 { |
3148 location_t loc = tree_nonartificial_location (exp); | 3488 location_t loc = tree_nonartificial_location (exp); |
3149 loc = expansion_point_location_if_in_system_header (loc); | 3489 loc = expansion_point_location_if_in_system_header (loc); |
3150 | 3490 |
3151 if (tree_int_cst_lt (maxobjsize, range[0])) | 3491 if (tree_int_cst_lt (maxobjsize, range[0])) |
3152 { | 3492 { |
3493 if (TREE_NO_WARNING (exp)) | |
3494 return false; | |
3495 | |
3153 /* Warn about crazy big sizes first since that's more | 3496 /* Warn about crazy big sizes first since that's more |
3154 likely to be meaningful than saying that the bound | 3497 likely to be meaningful than saying that the bound |
3155 is greater than the object size if both are big. */ | 3498 is greater than the object size if both are big. */ |
3156 if (range[0] == range[1]) | 3499 if (range[0] == range[1]) |
3157 warning_at (loc, opt, | 3500 warning_at (loc, opt, |
3158 "%K%qD specified bound %E " | 3501 "%K%qD specified bound %E " |
3159 "exceeds maximum object size %E", | 3502 "exceeds maximum object size %E", |
3160 exp, get_callee_fndecl (exp), | 3503 exp, func, |
3161 range[0], maxobjsize); | 3504 range[0], maxobjsize); |
3162 else | 3505 else |
3163 warning_at (loc, opt, | 3506 warning_at (loc, opt, |
3164 "%K%qD specified bound between %E and %E " | 3507 "%K%qD specified bound between %E and %E " |
3165 "exceeds maximum object size %E", | 3508 "exceeds maximum object size %E", |
3166 exp, get_callee_fndecl (exp), | 3509 exp, func, |
3167 range[0], range[1], maxobjsize); | 3510 range[0], range[1], maxobjsize); |
3168 | 3511 |
3169 return false; | 3512 return false; |
3170 } | 3513 } |
3171 | 3514 |
3172 if (objsize != maxobjsize && tree_int_cst_lt (objsize, range[0])) | 3515 if (dstsize != maxobjsize && tree_int_cst_lt (dstsize, range[0])) |
3173 { | 3516 { |
3517 if (TREE_NO_WARNING (exp)) | |
3518 return false; | |
3519 | |
3174 if (tree_int_cst_equal (range[0], range[1])) | 3520 if (tree_int_cst_equal (range[0], range[1])) |
3175 warning_at (loc, opt, | 3521 warning_at (loc, opt, |
3176 "%K%qD specified bound %E " | 3522 "%K%qD specified bound %E " |
3177 "exceeds destination size %E", | 3523 "exceeds destination size %E", |
3178 exp, get_callee_fndecl (exp), | 3524 exp, func, |
3179 range[0], objsize); | 3525 range[0], dstsize); |
3180 else | 3526 else |
3181 warning_at (loc, opt, | 3527 warning_at (loc, opt, |
3182 "%K%qD specified bound between %E and %E " | 3528 "%K%qD specified bound between %E and %E " |
3183 "exceeds destination size %E", | 3529 "exceeds destination size %E", |
3184 exp, get_callee_fndecl (exp), | 3530 exp, func, |
3185 range[0], range[1], objsize); | 3531 range[0], range[1], dstsize); |
3186 return false; | 3532 return false; |
3187 } | 3533 } |
3188 } | 3534 } |
3189 } | 3535 } |
3190 | 3536 |
3537 /* Check for reading past the end of SRC. */ | |
3191 if (slen | 3538 if (slen |
3192 && slen == src | 3539 && slen == srcstr |
3193 && size && range[0] | 3540 && dstwrite && range[0] |
3194 && tree_int_cst_lt (slen, range[0])) | 3541 && tree_int_cst_lt (slen, range[0])) |
3195 { | 3542 { |
3543 if (TREE_NO_WARNING (exp)) | |
3544 return false; | |
3545 | |
3196 location_t loc = tree_nonartificial_location (exp); | 3546 location_t loc = tree_nonartificial_location (exp); |
3197 | 3547 |
3198 if (tree_int_cst_equal (range[0], range[1])) | 3548 if (tree_int_cst_equal (range[0], range[1])) |
3199 warning_at (loc, opt, | 3549 warning_n (loc, opt, tree_to_uhwi (range[0]), |
3200 (tree_int_cst_equal (range[0], integer_one_node) | 3550 "%K%qD reading %E byte from a region of size %E", |
3201 ? G_("%K%qD reading %E byte from a region of size %E") | 3551 "%K%qD reading %E bytes from a region of size %E", |
3202 : G_("%K%qD reading %E bytes from a region of size %E")), | 3552 exp, func, range[0], slen); |
3203 exp, get_callee_fndecl (exp), range[0], slen); | |
3204 else if (tree_int_cst_sign_bit (range[1])) | 3553 else if (tree_int_cst_sign_bit (range[1])) |
3205 { | 3554 { |
3206 /* Avoid printing the upper bound if it's invalid. */ | 3555 /* Avoid printing the upper bound if it's invalid. */ |
3207 warning_at (loc, opt, | 3556 warning_at (loc, opt, |
3208 "%K%qD reading %E or more bytes from a region " | 3557 "%K%qD reading %E or more bytes from a region " |
3209 "of size %E", | 3558 "of size %E", |
3210 exp, get_callee_fndecl (exp), range[0], slen); | 3559 exp, func, range[0], slen); |
3211 } | 3560 } |
3212 else | 3561 else |
3213 warning_at (loc, opt, | 3562 warning_at (loc, opt, |
3214 "%K%qD reading between %E and %E bytes from a region " | 3563 "%K%qD reading between %E and %E bytes from a region " |
3215 "of size %E", | 3564 "of size %E", |
3216 exp, get_callee_fndecl (exp), range[0], range[1], slen); | 3565 exp, func, range[0], range[1], slen); |
3217 return false; | 3566 return false; |
3218 } | 3567 } |
3219 | 3568 |
3220 return true; | 3569 return true; |
3221 } | 3570 } |
3222 | 3571 |
3223 /* Helper to compute the size of the object referenced by the DEST | 3572 /* Helper to compute the size of the object referenced by the DEST |
3224 expression which must of of pointer type, using Object Size type | 3573 expression which must have pointer type, using Object Size type |
3225 OSTYPE (only the least significant 2 bits are used). Return | 3574 OSTYPE (only the least significant 2 bits are used). Return |
3226 the size of the object if successful or NULL when the size cannot | 3575 an estimate of the size of the object if successful or NULL when |
3227 be determined. */ | 3576 the size cannot be determined. When the referenced object involves |
3228 | 3577 a non-constant offset in some range the returned value represents |
3229 static inline tree | 3578 the largest size given the smallest non-negative offset in the |
3579 range. The function is intended for diagnostics and should not | |
3580 be used to influence code generation or optimization. */ | |
3581 | |
3582 tree | |
3230 compute_objsize (tree dest, int ostype) | 3583 compute_objsize (tree dest, int ostype) |
3231 { | 3584 { |
3232 unsigned HOST_WIDE_INT size; | 3585 unsigned HOST_WIDE_INT size; |
3233 if (compute_builtin_object_size (dest, ostype & 3, &size)) | 3586 |
3587 /* Only the two least significant bits are meaningful. */ | |
3588 ostype &= 3; | |
3589 | |
3590 if (compute_builtin_object_size (dest, ostype, &size)) | |
3234 return build_int_cst (sizetype, size); | 3591 return build_int_cst (sizetype, size); |
3592 | |
3593 if (TREE_CODE (dest) == SSA_NAME) | |
3594 { | |
3595 gimple *stmt = SSA_NAME_DEF_STMT (dest); | |
3596 if (!is_gimple_assign (stmt)) | |
3597 return NULL_TREE; | |
3598 | |
3599 dest = gimple_assign_rhs1 (stmt); | |
3600 | |
3601 tree_code code = gimple_assign_rhs_code (stmt); | |
3602 if (code == POINTER_PLUS_EXPR) | |
3603 { | |
3604 /* compute_builtin_object_size fails for addresses with | |
3605 non-constant offsets. Try to determine the range of | |
3606 such an offset here and use it to adjust the constant | |
3607 size. */ | |
3608 tree off = gimple_assign_rhs2 (stmt); | |
3609 if (TREE_CODE (off) == INTEGER_CST) | |
3610 { | |
3611 if (tree size = compute_objsize (dest, ostype)) | |
3612 { | |
3613 wide_int wioff = wi::to_wide (off); | |
3614 wide_int wisiz = wi::to_wide (size); | |
3615 | |
3616 /* Ignore negative offsets for now. For others, | |
3617 use the lower bound as the most optimistic | |
3618 estimate of the (remaining) size. */ | |
3619 if (wi::sign_mask (wioff)) | |
3620 ; | |
3621 else if (wi::ltu_p (wioff, wisiz)) | |
3622 return wide_int_to_tree (TREE_TYPE (size), | |
3623 wi::sub (wisiz, wioff)); | |
3624 else | |
3625 return size_zero_node; | |
3626 } | |
3627 } | |
3628 else if (TREE_CODE (off) == SSA_NAME | |
3629 && INTEGRAL_TYPE_P (TREE_TYPE (off))) | |
3630 { | |
3631 wide_int min, max; | |
3632 enum value_range_kind rng = get_range_info (off, &min, &max); | |
3633 | |
3634 if (rng == VR_RANGE) | |
3635 { | |
3636 if (tree size = compute_objsize (dest, ostype)) | |
3637 { | |
3638 wide_int wisiz = wi::to_wide (size); | |
3639 | |
3640 /* Ignore negative offsets for now. For others, | |
3641 use the lower bound as the most optimistic | |
3642 estimate of the (remaining)size. */ | |
3643 if (wi::sign_mask (min)) | |
3644 ; | |
3645 else if (wi::ltu_p (min, wisiz)) | |
3646 return wide_int_to_tree (TREE_TYPE (size), | |
3647 wi::sub (wisiz, min)); | |
3648 else | |
3649 return size_zero_node; | |
3650 } | |
3651 } | |
3652 } | |
3653 } | |
3654 else if (code != ADDR_EXPR) | |
3655 return NULL_TREE; | |
3656 } | |
3657 | |
3658 /* Unless computing the largest size (for memcpy and other raw memory | |
3659 functions), try to determine the size of the object from its type. */ | |
3660 if (!ostype) | |
3661 return NULL_TREE; | |
3662 | |
3663 if (TREE_CODE (dest) != ADDR_EXPR) | |
3664 return NULL_TREE; | |
3665 | |
3666 tree type = TREE_TYPE (dest); | |
3667 if (TREE_CODE (type) == POINTER_TYPE) | |
3668 type = TREE_TYPE (type); | |
3669 | |
3670 type = TYPE_MAIN_VARIANT (type); | |
3671 | |
3672 if (TREE_CODE (type) == ARRAY_TYPE | |
3673 && !array_at_struct_end_p (TREE_OPERAND (dest, 0))) | |
3674 { | |
3675 /* Return the constant size unless it's zero (that's a zero-length | |
3676 array likely at the end of a struct). */ | |
3677 tree size = TYPE_SIZE_UNIT (type); | |
3678 if (size && TREE_CODE (size) == INTEGER_CST | |
3679 && !integer_zerop (size)) | |
3680 return size; | |
3681 } | |
3235 | 3682 |
3236 return NULL_TREE; | 3683 return NULL_TREE; |
3237 } | 3684 } |
3238 | 3685 |
3239 /* Helper to determine and check the sizes of the source and the destination | 3686 /* Helper to determine and check the sizes of the source and the destination |
3242 argument or null, and LEN is the number of bytes. Use Object Size type-0 | 3689 argument or null, and LEN is the number of bytes. Use Object Size type-0 |
3243 regardless of the OPT_Wstringop_overflow_ setting. Return true on success | 3690 regardless of the OPT_Wstringop_overflow_ setting. Return true on success |
3244 (no overflow or invalid sizes), false otherwise. */ | 3691 (no overflow or invalid sizes), false otherwise. */ |
3245 | 3692 |
3246 static bool | 3693 static bool |
3247 check_memop_sizes (tree exp, tree dest, tree src, tree size) | 3694 check_memop_access (tree exp, tree dest, tree src, tree size) |
3248 { | 3695 { |
3249 if (!warn_stringop_overflow) | |
3250 return true; | |
3251 | |
3252 /* For functions like memset and memcpy that operate on raw memory | 3696 /* For functions like memset and memcpy that operate on raw memory |
3253 try to determine the size of the largest source and destination | 3697 try to determine the size of the largest source and destination |
3254 object using type-0 Object Size regardless of the object size | 3698 object using type-0 Object Size regardless of the object size |
3255 type specified by the option. */ | 3699 type specified by the option. */ |
3256 tree srcsize = src ? compute_objsize (src, 0) : NULL_TREE; | 3700 tree srcsize = src ? compute_objsize (src, 0) : NULL_TREE; |
3257 tree dstsize = compute_objsize (dest, 0); | 3701 tree dstsize = compute_objsize (dest, 0); |
3258 | 3702 |
3259 return check_sizes (OPT_Wstringop_overflow_, exp, | 3703 return check_access (exp, dest, src, size, /*maxread=*/NULL_TREE, |
3260 size, /*maxlen=*/NULL_TREE, srcsize, dstsize); | 3704 srcsize, dstsize); |
3261 } | 3705 } |
3262 | 3706 |
3263 /* Validate memchr arguments without performing any expansion. | 3707 /* Validate memchr arguments without performing any expansion. |
3264 Return NULL_RTX. */ | 3708 Return NULL_RTX. */ |
3265 | 3709 |
3276 /* Diagnose calls where the specified length exceeds the size | 3720 /* Diagnose calls where the specified length exceeds the size |
3277 of the object. */ | 3721 of the object. */ |
3278 if (warn_stringop_overflow) | 3722 if (warn_stringop_overflow) |
3279 { | 3723 { |
3280 tree size = compute_objsize (arg1, 0); | 3724 tree size = compute_objsize (arg1, 0); |
3281 check_sizes (OPT_Wstringop_overflow_, | 3725 check_access (exp, /*dst=*/NULL_TREE, /*src=*/NULL_TREE, len, |
3282 exp, len, /*maxlen=*/NULL_TREE, | 3726 /*maxread=*/NULL_TREE, size, /*objsize=*/NULL_TREE); |
3283 size, /*objsize=*/NULL_TREE); | |
3284 } | 3727 } |
3285 | 3728 |
3286 return NULL_RTX; | 3729 return NULL_RTX; |
3287 } | 3730 } |
3288 | 3731 |
3300 | 3743 |
3301 tree dest = CALL_EXPR_ARG (exp, 0); | 3744 tree dest = CALL_EXPR_ARG (exp, 0); |
3302 tree src = CALL_EXPR_ARG (exp, 1); | 3745 tree src = CALL_EXPR_ARG (exp, 1); |
3303 tree len = CALL_EXPR_ARG (exp, 2); | 3746 tree len = CALL_EXPR_ARG (exp, 2); |
3304 | 3747 |
3305 check_memop_sizes (exp, dest, src, len); | 3748 check_memop_access (exp, dest, src, len); |
3306 | 3749 |
3307 return expand_builtin_memory_copy_args (dest, src, len, target, exp, | 3750 return expand_builtin_memory_copy_args (dest, src, len, target, exp, |
3308 /*endp=*/ 0); | 3751 /*endp=*/ 0); |
3309 } | 3752 } |
3310 | 3753 |
3320 | 3763 |
3321 tree dest = CALL_EXPR_ARG (exp, 0); | 3764 tree dest = CALL_EXPR_ARG (exp, 0); |
3322 tree src = CALL_EXPR_ARG (exp, 1); | 3765 tree src = CALL_EXPR_ARG (exp, 1); |
3323 tree len = CALL_EXPR_ARG (exp, 2); | 3766 tree len = CALL_EXPR_ARG (exp, 2); |
3324 | 3767 |
3325 check_memop_sizes (exp, dest, src, len); | 3768 check_memop_access (exp, dest, src, len); |
3326 | 3769 |
3327 return NULL_RTX; | 3770 return NULL_RTX; |
3328 } | |
3329 | |
3330 /* Expand an instrumented call EXP to the memcpy builtin. | |
3331 Return NULL_RTX if we failed, the caller should emit a normal call, | |
3332 otherwise try to get the result in TARGET, if convenient (and in | |
3333 mode MODE if that's convenient). */ | |
3334 | |
3335 static rtx | |
3336 expand_builtin_memcpy_with_bounds (tree exp, rtx target) | |
3337 { | |
3338 if (!validate_arglist (exp, | |
3339 POINTER_TYPE, POINTER_BOUNDS_TYPE, | |
3340 POINTER_TYPE, POINTER_BOUNDS_TYPE, | |
3341 INTEGER_TYPE, VOID_TYPE)) | |
3342 return NULL_RTX; | |
3343 else | |
3344 { | |
3345 tree dest = CALL_EXPR_ARG (exp, 0); | |
3346 tree src = CALL_EXPR_ARG (exp, 2); | |
3347 tree len = CALL_EXPR_ARG (exp, 4); | |
3348 rtx res = expand_builtin_memory_copy_args (dest, src, len, target, exp, | |
3349 /*end_p=*/ 0); | |
3350 | |
3351 /* Return src bounds with the result. */ | |
3352 if (res) | |
3353 { | |
3354 rtx bnd = force_reg (targetm.chkp_bound_mode (), | |
3355 expand_normal (CALL_EXPR_ARG (exp, 1))); | |
3356 res = chkp_join_splitted_slot (res, bnd); | |
3357 } | |
3358 return res; | |
3359 } | |
3360 } | 3771 } |
3361 | 3772 |
3362 /* Expand a call EXP to the mempcpy builtin. | 3773 /* Expand a call EXP to the mempcpy builtin. |
3363 Return NULL_RTX if we failed; the caller should emit a normal call, | 3774 Return NULL_RTX if we failed; the caller should emit a normal call, |
3364 otherwise try to get the result in TARGET, if convenient (and in | 3775 otherwise try to get the result in TARGET, if convenient (and in |
3376 | 3787 |
3377 tree dest = CALL_EXPR_ARG (exp, 0); | 3788 tree dest = CALL_EXPR_ARG (exp, 0); |
3378 tree src = CALL_EXPR_ARG (exp, 1); | 3789 tree src = CALL_EXPR_ARG (exp, 1); |
3379 tree len = CALL_EXPR_ARG (exp, 2); | 3790 tree len = CALL_EXPR_ARG (exp, 2); |
3380 | 3791 |
3792 /* Policy does not generally allow using compute_objsize (which | |
3793 is used internally by check_memop_size) to change code generation | |
3794 or drive optimization decisions. | |
3795 | |
3796 In this instance it is safe because the code we generate has | |
3797 the same semantics regardless of the return value of | |
3798 check_memop_sizes. Exactly the same amount of data is copied | |
3799 and the return value is exactly the same in both cases. | |
3800 | |
3801 Furthermore, check_memop_size always uses mode 0 for the call to | |
3802 compute_objsize, so the imprecise nature of compute_objsize is | |
3803 avoided. */ | |
3804 | |
3381 /* Avoid expanding mempcpy into memcpy when the call is determined | 3805 /* Avoid expanding mempcpy into memcpy when the call is determined |
3382 to overflow the buffer. This also prevents the same overflow | 3806 to overflow the buffer. This also prevents the same overflow |
3383 from being diagnosed again when expanding memcpy. */ | 3807 from being diagnosed again when expanding memcpy. */ |
3384 if (!check_memop_sizes (exp, dest, src, len)) | 3808 if (!check_memop_access (exp, dest, src, len)) |
3385 return NULL_RTX; | 3809 return NULL_RTX; |
3386 | 3810 |
3387 return expand_builtin_mempcpy_args (dest, src, len, | 3811 return expand_builtin_mempcpy_args (dest, src, len, |
3388 target, exp, /*endp=*/ 1); | 3812 target, exp, /*endp=*/ 1); |
3389 } | |
3390 | |
3391 /* Expand an instrumented call EXP to the mempcpy builtin. | |
3392 Return NULL_RTX if we failed, the caller should emit a normal call, | |
3393 otherwise try to get the result in TARGET, if convenient (and in | |
3394 mode MODE if that's convenient). */ | |
3395 | |
3396 static rtx | |
3397 expand_builtin_mempcpy_with_bounds (tree exp, rtx target) | |
3398 { | |
3399 if (!validate_arglist (exp, | |
3400 POINTER_TYPE, POINTER_BOUNDS_TYPE, | |
3401 POINTER_TYPE, POINTER_BOUNDS_TYPE, | |
3402 INTEGER_TYPE, VOID_TYPE)) | |
3403 return NULL_RTX; | |
3404 else | |
3405 { | |
3406 tree dest = CALL_EXPR_ARG (exp, 0); | |
3407 tree src = CALL_EXPR_ARG (exp, 2); | |
3408 tree len = CALL_EXPR_ARG (exp, 4); | |
3409 rtx res = expand_builtin_mempcpy_args (dest, src, len, target, | |
3410 exp, 1); | |
3411 | |
3412 /* Return src bounds with the result. */ | |
3413 if (res) | |
3414 { | |
3415 rtx bnd = force_reg (targetm.chkp_bound_mode (), | |
3416 expand_normal (CALL_EXPR_ARG (exp, 1))); | |
3417 res = chkp_join_splitted_slot (res, bnd); | |
3418 } | |
3419 return res; | |
3420 } | |
3421 } | 3813 } |
3422 | 3814 |
3423 /* Helper function to do the actual work for expand of memory copy family | 3815 /* Helper function to do the actual work for expand of memory copy family |
3424 functions (memcpy, mempcpy, stpcpy). Expansing should assign LEN bytes | 3816 functions (memcpy, mempcpy, stpcpy). Expansing should assign LEN bytes |
3425 of memory from SRC to DEST and assign to TARGET if convenient. | 3817 of memory from SRC to DEST and assign to TARGET if convenient. |
3485 | 3877 |
3486 src_mem = get_memory_rtx (src, len); | 3878 src_mem = get_memory_rtx (src, len); |
3487 set_mem_align (src_mem, src_align); | 3879 set_mem_align (src_mem, src_align); |
3488 | 3880 |
3489 /* Copy word part most expediently. */ | 3881 /* Copy word part most expediently. */ |
3490 dest_addr = emit_block_move_hints (dest_mem, src_mem, len_rtx, | 3882 enum block_op_methods method = BLOCK_OP_NORMAL; |
3491 CALL_EXPR_TAILCALL (exp) | 3883 if (CALL_EXPR_TAILCALL (exp) && (endp == 0 || target == const0_rtx)) |
3492 && (endp == 0 || target == const0_rtx) | 3884 method = BLOCK_OP_TAILCALL; |
3493 ? BLOCK_OP_TAILCALL : BLOCK_OP_NORMAL, | 3885 if (endp == 1 && target != const0_rtx) |
3886 method = BLOCK_OP_NO_LIBCALL_RET; | |
3887 dest_addr = emit_block_move_hints (dest_mem, src_mem, len_rtx, method, | |
3494 expected_align, expected_size, | 3888 expected_align, expected_size, |
3495 min_size, max_size, probable_max_size); | 3889 min_size, max_size, probable_max_size); |
3890 if (dest_addr == pc_rtx) | |
3891 return NULL_RTX; | |
3496 | 3892 |
3497 if (dest_addr == 0) | 3893 if (dest_addr == 0) |
3498 { | 3894 { |
3499 dest_addr = force_operand (XEXP (dest_mem, 0), target); | 3895 dest_addr = force_operand (XEXP (dest_mem, 0), target); |
3500 dest_addr = convert_memory_address (ptr_mode, dest_addr); | 3896 dest_addr = convert_memory_address (ptr_mode, dest_addr); |
3585 just diagnose cases when the souce string is longer than | 3981 just diagnose cases when the souce string is longer than |
3586 the destination object. */ | 3982 the destination object. */ |
3587 | 3983 |
3588 tree destsize = compute_objsize (dest, warn_stringop_overflow - 1); | 3984 tree destsize = compute_objsize (dest, warn_stringop_overflow - 1); |
3589 | 3985 |
3590 check_sizes (OPT_Wstringop_overflow_, | 3986 check_access (exp, dest, src, /*size=*/NULL_TREE, /*maxread=*/NULL_TREE, src, |
3591 exp, /*size=*/NULL_TREE, /*maxlen=*/NULL_TREE, src, destsize); | 3987 destsize); |
3592 | 3988 |
3593 return NULL_RTX; | 3989 return NULL_RTX; |
3594 } | 3990 } |
3595 | 3991 |
3596 /* Expand expression EXP, which is a call to the strcpy builtin. Return | 3992 /* Expand expression EXP, which is a call to the strcpy builtin. Return |
3608 tree src = CALL_EXPR_ARG (exp, 1); | 4004 tree src = CALL_EXPR_ARG (exp, 1); |
3609 | 4005 |
3610 if (warn_stringop_overflow) | 4006 if (warn_stringop_overflow) |
3611 { | 4007 { |
3612 tree destsize = compute_objsize (dest, warn_stringop_overflow - 1); | 4008 tree destsize = compute_objsize (dest, warn_stringop_overflow - 1); |
3613 check_sizes (OPT_Wstringop_overflow_, | 4009 check_access (exp, dest, src, /*size=*/NULL_TREE, /*maxread=*/NULL_TREE, |
3614 exp, /*size=*/NULL_TREE, /*maxlen=*/NULL_TREE, src, destsize); | 4010 src, destsize); |
3615 } | 4011 } |
3616 | 4012 |
3617 return expand_builtin_strcpy_args (dest, src, target); | 4013 if (rtx ret = expand_builtin_strcpy_args (exp, dest, src, target)) |
4014 { | |
4015 /* Check to see if the argument was declared attribute nonstring | |
4016 and if so, issue a warning since at this point it's not known | |
4017 to be nul-terminated. */ | |
4018 tree fndecl = get_callee_fndecl (exp); | |
4019 maybe_warn_nonstring_arg (fndecl, exp); | |
4020 return ret; | |
4021 } | |
4022 | |
4023 return NULL_RTX; | |
3618 } | 4024 } |
3619 | 4025 |
3620 /* Helper function to do the actual work for expand_builtin_strcpy. The | 4026 /* Helper function to do the actual work for expand_builtin_strcpy. The |
3621 arguments to the builtin_strcpy call DEST and SRC are broken out | 4027 arguments to the builtin_strcpy call DEST and SRC are broken out |
3622 so that this can also be called without constructing an actual CALL_EXPR. | 4028 so that this can also be called without constructing an actual CALL_EXPR. |
3623 The other arguments and return value are the same as for | 4029 The other arguments and return value are the same as for |
3624 expand_builtin_strcpy. */ | 4030 expand_builtin_strcpy. */ |
3625 | 4031 |
3626 static rtx | 4032 static rtx |
3627 expand_builtin_strcpy_args (tree dest, tree src, rtx target) | 4033 expand_builtin_strcpy_args (tree exp, tree dest, tree src, rtx target) |
3628 { | 4034 { |
4035 /* Detect strcpy calls with unterminated arrays.. */ | |
4036 if (tree nonstr = unterminated_array (src)) | |
4037 { | |
4038 /* NONSTR refers to the non-nul terminated constant array. */ | |
4039 if (!TREE_NO_WARNING (exp)) | |
4040 warn_string_no_nul (EXPR_LOCATION (exp), "strcpy", src, nonstr); | |
4041 return NULL_RTX; | |
4042 } | |
4043 | |
3629 return expand_movstr (dest, src, target, /*endp=*/0); | 4044 return expand_movstr (dest, src, target, /*endp=*/0); |
3630 } | 4045 } |
3631 | 4046 |
3632 /* Expand a call EXP to the stpcpy builtin. | 4047 /* Expand a call EXP to the stpcpy builtin. |
3633 Return NULL_RTX if we failed the caller should emit a normal call, | 4048 Return NULL_RTX if we failed the caller should emit a normal call, |
3634 otherwise try to get the result in TARGET, if convenient (and in | 4049 otherwise try to get the result in TARGET, if convenient (and in |
3635 mode MODE if that's convenient). */ | 4050 mode MODE if that's convenient). */ |
3636 | 4051 |
3637 static rtx | 4052 static rtx |
3638 expand_builtin_stpcpy (tree exp, rtx target, machine_mode mode) | 4053 expand_builtin_stpcpy_1 (tree exp, rtx target, machine_mode mode) |
3639 { | 4054 { |
3640 tree dst, src; | 4055 tree dst, src; |
3641 location_t loc = EXPR_LOCATION (exp); | 4056 location_t loc = EXPR_LOCATION (exp); |
3642 | 4057 |
3643 if (!validate_arglist (exp, POINTER_TYPE, POINTER_TYPE, VOID_TYPE)) | 4058 if (!validate_arglist (exp, POINTER_TYPE, POINTER_TYPE, VOID_TYPE)) |
3647 src = CALL_EXPR_ARG (exp, 1); | 4062 src = CALL_EXPR_ARG (exp, 1); |
3648 | 4063 |
3649 if (warn_stringop_overflow) | 4064 if (warn_stringop_overflow) |
3650 { | 4065 { |
3651 tree destsize = compute_objsize (dst, warn_stringop_overflow - 1); | 4066 tree destsize = compute_objsize (dst, warn_stringop_overflow - 1); |
3652 check_sizes (OPT_Wstringop_overflow_, | 4067 check_access (exp, dst, src, /*size=*/NULL_TREE, /*maxread=*/NULL_TREE, |
3653 exp, /*size=*/NULL_TREE, /*maxlen=*/NULL_TREE, src, destsize); | 4068 src, destsize); |
3654 } | 4069 } |
3655 | 4070 |
3656 /* If return value is ignored, transform stpcpy into strcpy. */ | 4071 /* If return value is ignored, transform stpcpy into strcpy. */ |
3657 if (target == const0_rtx && builtin_decl_implicit (BUILT_IN_STRCPY)) | 4072 if (target == const0_rtx && builtin_decl_implicit (BUILT_IN_STRCPY)) |
3658 { | 4073 { |
3667 | 4082 |
3668 /* Ensure we get an actual string whose length can be evaluated at | 4083 /* Ensure we get an actual string whose length can be evaluated at |
3669 compile-time, not an expression containing a string. This is | 4084 compile-time, not an expression containing a string. This is |
3670 because the latter will potentially produce pessimized code | 4085 because the latter will potentially produce pessimized code |
3671 when used to produce the return value. */ | 4086 when used to produce the return value. */ |
3672 if (! c_getstr (src) || ! (len = c_strlen (src, 0))) | 4087 c_strlen_data data; |
4088 memset (&data, 0, sizeof (c_strlen_data)); | |
4089 if (!c_getstr (src, NULL) | |
4090 || !(len = c_strlen (src, 0, &data, 1))) | |
3673 return expand_movstr (dst, src, target, /*endp=*/2); | 4091 return expand_movstr (dst, src, target, /*endp=*/2); |
4092 | |
4093 if (data.decl && !TREE_NO_WARNING (exp)) | |
4094 warn_string_no_nul (EXPR_LOCATION (exp), "stpcpy", src, data.decl); | |
3674 | 4095 |
3675 lenp1 = size_binop_loc (loc, PLUS_EXPR, len, ssize_int (1)); | 4096 lenp1 = size_binop_loc (loc, PLUS_EXPR, len, ssize_int (1)); |
3676 ret = expand_builtin_mempcpy_args (dst, src, lenp1, | 4097 ret = expand_builtin_mempcpy_args (dst, src, lenp1, |
3677 target, exp, /*endp=*/2); | 4098 target, exp, /*endp=*/2); |
3678 | 4099 |
3683 { | 4104 { |
3684 rtx len_rtx = expand_normal (len); | 4105 rtx len_rtx = expand_normal (len); |
3685 | 4106 |
3686 if (CONST_INT_P (len_rtx)) | 4107 if (CONST_INT_P (len_rtx)) |
3687 { | 4108 { |
3688 ret = expand_builtin_strcpy_args (dst, src, target); | 4109 ret = expand_builtin_strcpy_args (exp, dst, src, target); |
3689 | 4110 |
3690 if (ret) | 4111 if (ret) |
3691 { | 4112 { |
3692 if (! target) | 4113 if (! target) |
3693 { | 4114 { |
3710 | 4131 |
3711 return expand_movstr (dst, src, target, /*endp=*/2); | 4132 return expand_movstr (dst, src, target, /*endp=*/2); |
3712 } | 4133 } |
3713 } | 4134 } |
3714 | 4135 |
4136 /* Expand a call EXP to the stpcpy builtin and diagnose uses of nonstring | |
4137 arguments while being careful to avoid duplicate warnings (which could | |
4138 be issued if the expander were to expand the call, resulting in it | |
4139 being emitted in expand_call(). */ | |
4140 | |
4141 static rtx | |
4142 expand_builtin_stpcpy (tree exp, rtx target, machine_mode mode) | |
4143 { | |
4144 if (rtx ret = expand_builtin_stpcpy_1 (exp, target, mode)) | |
4145 { | |
4146 /* The call has been successfully expanded. Check for nonstring | |
4147 arguments and issue warnings as appropriate. */ | |
4148 maybe_warn_nonstring_arg (get_callee_fndecl (exp), exp); | |
4149 return ret; | |
4150 } | |
4151 | |
4152 return NULL_RTX; | |
4153 } | |
4154 | |
3715 /* Check a call EXP to the stpncpy built-in for validity. | 4155 /* Check a call EXP to the stpncpy built-in for validity. |
3716 Return NULL_RTX on both success and failure. */ | 4156 Return NULL_RTX on both success and failure. */ |
3717 | 4157 |
3718 static rtx | 4158 static rtx |
3719 expand_builtin_stpncpy (tree exp, rtx) | 4159 expand_builtin_stpncpy (tree exp, rtx) |
3731 tree len = CALL_EXPR_ARG (exp, 2); | 4171 tree len = CALL_EXPR_ARG (exp, 2); |
3732 | 4172 |
3733 /* The size of the destination object. */ | 4173 /* The size of the destination object. */ |
3734 tree destsize = compute_objsize (dest, warn_stringop_overflow - 1); | 4174 tree destsize = compute_objsize (dest, warn_stringop_overflow - 1); |
3735 | 4175 |
3736 check_sizes (OPT_Wstringop_overflow_, | 4176 check_access (exp, dest, src, len, /*maxread=*/NULL_TREE, src, destsize); |
3737 exp, len, /*maxlen=*/NULL_TREE, src, destsize); | |
3738 | 4177 |
3739 return NULL_RTX; | 4178 return NULL_RTX; |
3740 } | 4179 } |
3741 | 4180 |
3742 /* Callback routine for store_by_pieces. Read GET_MODE_BITSIZE (MODE) | 4181 /* Callback routine for store_by_pieces. Read GET_MODE_BITSIZE (MODE) |
3762 static bool | 4201 static bool |
3763 check_strncat_sizes (tree exp, tree objsize) | 4202 check_strncat_sizes (tree exp, tree objsize) |
3764 { | 4203 { |
3765 tree dest = CALL_EXPR_ARG (exp, 0); | 4204 tree dest = CALL_EXPR_ARG (exp, 0); |
3766 tree src = CALL_EXPR_ARG (exp, 1); | 4205 tree src = CALL_EXPR_ARG (exp, 1); |
3767 tree maxlen = CALL_EXPR_ARG (exp, 2); | 4206 tree maxread = CALL_EXPR_ARG (exp, 2); |
3768 | 4207 |
3769 /* Try to determine the range of lengths that the source expression | 4208 /* Try to determine the range of lengths that the source expression |
3770 refers to. */ | 4209 refers to. */ |
3771 tree lenrange[2]; | 4210 tree lenrange[2]; |
3772 get_range_strlen (src, lenrange); | 4211 get_range_strlen (src, lenrange); |
3786 tree srclen = (lenrange[0] | 4225 tree srclen = (lenrange[0] |
3787 ? fold_build2 (PLUS_EXPR, size_type_node, lenrange[0], | 4226 ? fold_build2 (PLUS_EXPR, size_type_node, lenrange[0], |
3788 size_one_node) | 4227 size_one_node) |
3789 : NULL_TREE); | 4228 : NULL_TREE); |
3790 | 4229 |
3791 /* Strncat copies at most MAXLEN bytes and always appends the terminating | 4230 /* The strncat function copies at most MAXREAD bytes and always appends |
3792 nul so the specified upper bound should never be equal to (or greater | 4231 the terminating nul so the specified upper bound should never be equal |
3793 than) the size of the destination. */ | 4232 to (or greater than) the size of the destination. */ |
3794 if (tree_fits_uhwi_p (maxlen) && tree_fits_uhwi_p (objsize) | 4233 if (tree_fits_uhwi_p (maxread) && tree_fits_uhwi_p (objsize) |
3795 && tree_int_cst_equal (objsize, maxlen)) | 4234 && tree_int_cst_equal (objsize, maxread)) |
3796 { | 4235 { |
3797 location_t loc = tree_nonartificial_location (exp); | 4236 location_t loc = tree_nonartificial_location (exp); |
3798 loc = expansion_point_location_if_in_system_header (loc); | 4237 loc = expansion_point_location_if_in_system_header (loc); |
3799 | 4238 |
3800 warning_at (loc, OPT_Wstringop_overflow_, | 4239 warning_at (loc, OPT_Wstringop_overflow_, |
3801 "%K%qD specified bound %E equals destination size", | 4240 "%K%qD specified bound %E equals destination size", |
3802 exp, get_callee_fndecl (exp), maxlen); | 4241 exp, get_callee_fndecl (exp), maxread); |
3803 | 4242 |
3804 return false; | 4243 return false; |
3805 } | 4244 } |
3806 | 4245 |
3807 if (!srclen | 4246 if (!srclen |
3808 || (maxlen && tree_fits_uhwi_p (maxlen) | 4247 || (maxread && tree_fits_uhwi_p (maxread) |
3809 && tree_fits_uhwi_p (srclen) | 4248 && tree_fits_uhwi_p (srclen) |
3810 && tree_int_cst_lt (maxlen, srclen))) | 4249 && tree_int_cst_lt (maxread, srclen))) |
3811 srclen = maxlen; | 4250 srclen = maxread; |
3812 | 4251 |
3813 /* The number of bytes to write is LEN but check_sizes will also | 4252 /* The number of bytes to write is LEN but check_access will also |
3814 check SRCLEN if LEN's value isn't known. */ | 4253 check SRCLEN if LEN's value isn't known. */ |
3815 return check_sizes (OPT_Wstringop_overflow_, | 4254 return check_access (exp, dest, src, /*size=*/NULL_TREE, maxread, srclen, |
3816 exp, /*size=*/NULL_TREE, maxlen, srclen, objsize); | 4255 objsize); |
3817 } | 4256 } |
3818 | 4257 |
3819 /* Similar to expand_builtin_strcat, do some very basic size validation | 4258 /* Similar to expand_builtin_strcat, do some very basic size validation |
3820 of a call to the strcpy builtin given by EXP. Return NULL_RTX to have | 4259 of a call to the strcpy builtin given by EXP. Return NULL_RTX to have |
3821 the built-in expand to a call to the library function. */ | 4260 the built-in expand to a call to the library function. */ |
3829 return NULL_RTX; | 4268 return NULL_RTX; |
3830 | 4269 |
3831 tree dest = CALL_EXPR_ARG (exp, 0); | 4270 tree dest = CALL_EXPR_ARG (exp, 0); |
3832 tree src = CALL_EXPR_ARG (exp, 1); | 4271 tree src = CALL_EXPR_ARG (exp, 1); |
3833 /* The upper bound on the number of bytes to write. */ | 4272 /* The upper bound on the number of bytes to write. */ |
3834 tree maxlen = CALL_EXPR_ARG (exp, 2); | 4273 tree maxread = CALL_EXPR_ARG (exp, 2); |
3835 /* The length of the source sequence. */ | 4274 /* The length of the source sequence. */ |
3836 tree slen = c_strlen (src, 1); | 4275 tree slen = c_strlen (src, 1); |
3837 | 4276 |
3838 /* Try to determine the range of lengths that the source expression | 4277 /* Try to determine the range of lengths that the source expression |
3839 refers to. */ | 4278 refers to. */ |
3852 tree srclen = (lenrange[0] | 4291 tree srclen = (lenrange[0] |
3853 ? fold_build2 (PLUS_EXPR, size_type_node, lenrange[0], | 4292 ? fold_build2 (PLUS_EXPR, size_type_node, lenrange[0], |
3854 size_one_node) | 4293 size_one_node) |
3855 : NULL_TREE); | 4294 : NULL_TREE); |
3856 | 4295 |
3857 /* Strncat copies at most MAXLEN bytes and always appends the terminating | 4296 /* The strncat function copies at most MAXREAD bytes and always appends |
3858 nul so the specified upper bound should never be equal to (or greater | 4297 the terminating nul so the specified upper bound should never be equal |
3859 than) the size of the destination. */ | 4298 to (or greater than) the size of the destination. */ |
3860 if (tree_fits_uhwi_p (maxlen) && tree_fits_uhwi_p (destsize) | 4299 if (tree_fits_uhwi_p (maxread) && tree_fits_uhwi_p (destsize) |
3861 && tree_int_cst_equal (destsize, maxlen)) | 4300 && tree_int_cst_equal (destsize, maxread)) |
3862 { | 4301 { |
3863 location_t loc = tree_nonartificial_location (exp); | 4302 location_t loc = tree_nonartificial_location (exp); |
3864 loc = expansion_point_location_if_in_system_header (loc); | 4303 loc = expansion_point_location_if_in_system_header (loc); |
3865 | 4304 |
3866 warning_at (loc, OPT_Wstringop_overflow_, | 4305 warning_at (loc, OPT_Wstringop_overflow_, |
3867 "%K%qD specified bound %E equals destination size", | 4306 "%K%qD specified bound %E equals destination size", |
3868 exp, get_callee_fndecl (exp), maxlen); | 4307 exp, get_callee_fndecl (exp), maxread); |
3869 | 4308 |
3870 return NULL_RTX; | 4309 return NULL_RTX; |
3871 } | 4310 } |
3872 | 4311 |
3873 if (!srclen | 4312 if (!srclen |
3874 || (maxlen && tree_fits_uhwi_p (maxlen) | 4313 || (maxread && tree_fits_uhwi_p (maxread) |
3875 && tree_fits_uhwi_p (srclen) | 4314 && tree_fits_uhwi_p (srclen) |
3876 && tree_int_cst_lt (maxlen, srclen))) | 4315 && tree_int_cst_lt (maxread, srclen))) |
3877 srclen = maxlen; | 4316 srclen = maxread; |
3878 | 4317 |
3879 /* The number of bytes to write is LEN but check_sizes will also | 4318 /* The number of bytes to write is SRCLEN. */ |
3880 check SRCLEN if LEN's value isn't known. */ | 4319 check_access (exp, dest, src, NULL_TREE, maxread, srclen, destsize); |
3881 check_sizes (OPT_Wstringop_overflow_, | |
3882 exp, /*size=*/NULL_TREE, maxlen, srclen, destsize); | |
3883 | 4320 |
3884 return NULL_RTX; | 4321 return NULL_RTX; |
3885 } | 4322 } |
3886 | 4323 |
3887 /* Expand expression EXP, which is a call to the strncpy builtin. Return | 4324 /* Expand expression EXP, which is a call to the strncpy builtin. Return |
3905 if (warn_stringop_overflow) | 4342 if (warn_stringop_overflow) |
3906 { | 4343 { |
3907 tree destsize = compute_objsize (dest, | 4344 tree destsize = compute_objsize (dest, |
3908 warn_stringop_overflow - 1); | 4345 warn_stringop_overflow - 1); |
3909 | 4346 |
3910 /* The number of bytes to write is LEN but check_sizes will also | 4347 /* The number of bytes to write is LEN but check_access will also |
3911 check SLEN if LEN's value isn't known. */ | 4348 check SLEN if LEN's value isn't known. */ |
3912 check_sizes (OPT_Wstringop_overflow_, | 4349 check_access (exp, dest, src, len, /*maxread=*/NULL_TREE, src, |
3913 exp, len, /*maxlen=*/NULL_TREE, src, destsize); | 4350 destsize); |
3914 } | 4351 } |
3915 | 4352 |
3916 /* We must be passed a constant len and src parameter. */ | 4353 /* We must be passed a constant len and src parameter. */ |
3917 if (!tree_fits_uhwi_p (len) || !slen || !tree_fits_uhwi_p (slen)) | 4354 if (!tree_fits_uhwi_p (len) || !slen || !tree_fits_uhwi_p (slen)) |
3918 return NULL_RTX; | 4355 return NULL_RTX; |
4003 | 4440 |
4004 tree dest = CALL_EXPR_ARG (exp, 0); | 4441 tree dest = CALL_EXPR_ARG (exp, 0); |
4005 tree val = CALL_EXPR_ARG (exp, 1); | 4442 tree val = CALL_EXPR_ARG (exp, 1); |
4006 tree len = CALL_EXPR_ARG (exp, 2); | 4443 tree len = CALL_EXPR_ARG (exp, 2); |
4007 | 4444 |
4008 check_memop_sizes (exp, dest, NULL_TREE, len); | 4445 check_memop_access (exp, dest, NULL_TREE, len); |
4009 | 4446 |
4010 return expand_builtin_memset_args (dest, val, len, target, mode, exp); | 4447 return expand_builtin_memset_args (dest, val, len, target, mode, exp); |
4011 } | |
4012 | |
4013 /* Expand expression EXP, which is an instrumented call to the memset builtin. | |
4014 Return NULL_RTX if we failed the caller should emit a normal call, otherwise | |
4015 try to get the result in TARGET, if convenient (and in mode MODE if that's | |
4016 convenient). */ | |
4017 | |
4018 static rtx | |
4019 expand_builtin_memset_with_bounds (tree exp, rtx target, machine_mode mode) | |
4020 { | |
4021 if (!validate_arglist (exp, | |
4022 POINTER_TYPE, POINTER_BOUNDS_TYPE, | |
4023 INTEGER_TYPE, INTEGER_TYPE, VOID_TYPE)) | |
4024 return NULL_RTX; | |
4025 else | |
4026 { | |
4027 tree dest = CALL_EXPR_ARG (exp, 0); | |
4028 tree val = CALL_EXPR_ARG (exp, 2); | |
4029 tree len = CALL_EXPR_ARG (exp, 3); | |
4030 rtx res = expand_builtin_memset_args (dest, val, len, target, mode, exp); | |
4031 | |
4032 /* Return src bounds with the result. */ | |
4033 if (res) | |
4034 { | |
4035 rtx bnd = force_reg (targetm.chkp_bound_mode (), | |
4036 expand_normal (CALL_EXPR_ARG (exp, 1))); | |
4037 res = chkp_join_splitted_slot (res, bnd); | |
4038 } | |
4039 return res; | |
4040 } | |
4041 } | 4448 } |
4042 | 4449 |
4043 /* Helper function to do the actual work for expand_builtin_memset. The | 4450 /* Helper function to do the actual work for expand_builtin_memset. The |
4044 arguments to the builtin_memset call DEST, VAL, and LEN are broken out | 4451 arguments to the builtin_memset call DEST, VAL, and LEN are broken out |
4045 so that this can also be called without constructing an actual CALL_EXPR. | 4452 so that this can also be called without constructing an actual CALL_EXPR. |
4166 return dest_addr; | 4573 return dest_addr; |
4167 | 4574 |
4168 do_libcall: | 4575 do_libcall: |
4169 fndecl = get_callee_fndecl (orig_exp); | 4576 fndecl = get_callee_fndecl (orig_exp); |
4170 fcode = DECL_FUNCTION_CODE (fndecl); | 4577 fcode = DECL_FUNCTION_CODE (fndecl); |
4171 if (fcode == BUILT_IN_MEMSET | 4578 if (fcode == BUILT_IN_MEMSET) |
4172 || fcode == BUILT_IN_CHKP_MEMSET_NOBND_NOCHK_CHKP) | |
4173 fn = build_call_nofold_loc (EXPR_LOCATION (orig_exp), fndecl, 3, | 4579 fn = build_call_nofold_loc (EXPR_LOCATION (orig_exp), fndecl, 3, |
4174 dest, val, len); | 4580 dest, val, len); |
4175 else if (fcode == BUILT_IN_BZERO) | 4581 else if (fcode == BUILT_IN_BZERO) |
4176 fn = build_call_nofold_loc (EXPR_LOCATION (orig_exp), fndecl, 2, | 4582 fn = build_call_nofold_loc (EXPR_LOCATION (orig_exp), fndecl, 2, |
4177 dest, len); | 4583 dest, len); |
4192 return NULL_RTX; | 4598 return NULL_RTX; |
4193 | 4599 |
4194 tree dest = CALL_EXPR_ARG (exp, 0); | 4600 tree dest = CALL_EXPR_ARG (exp, 0); |
4195 tree size = CALL_EXPR_ARG (exp, 1); | 4601 tree size = CALL_EXPR_ARG (exp, 1); |
4196 | 4602 |
4197 check_memop_sizes (exp, dest, NULL_TREE, size); | 4603 check_memop_access (exp, dest, NULL_TREE, size); |
4198 | 4604 |
4199 /* New argument list transforming bzero(ptr x, int y) to | 4605 /* New argument list transforming bzero(ptr x, int y) to |
4200 memset(ptr x, int 0, size_t y). This is done this way | 4606 memset(ptr x, int 0, size_t y). This is done this way |
4201 so that if it isn't expanded inline, we fallback to | 4607 so that if it isn't expanded inline, we fallback to |
4202 calling bzero instead of memset. */ | 4608 calling bzero instead of memset. */ |
4245 return NULL_RTX; | 4651 return NULL_RTX; |
4246 | 4652 |
4247 tree arg1 = CALL_EXPR_ARG (exp, 0); | 4653 tree arg1 = CALL_EXPR_ARG (exp, 0); |
4248 tree arg2 = CALL_EXPR_ARG (exp, 1); | 4654 tree arg2 = CALL_EXPR_ARG (exp, 1); |
4249 tree len = CALL_EXPR_ARG (exp, 2); | 4655 tree len = CALL_EXPR_ARG (exp, 2); |
4656 enum built_in_function fcode = DECL_FUNCTION_CODE (get_callee_fndecl (exp)); | |
4657 bool no_overflow = true; | |
4250 | 4658 |
4251 /* Diagnose calls where the specified length exceeds the size of either | 4659 /* Diagnose calls where the specified length exceeds the size of either |
4252 object. */ | 4660 object. */ |
4253 if (warn_stringop_overflow) | 4661 tree size = compute_objsize (arg1, 0); |
4254 { | 4662 no_overflow = check_access (exp, /*dst=*/NULL_TREE, /*src=*/NULL_TREE, |
4255 tree size = compute_objsize (arg1, 0); | 4663 len, /*maxread=*/NULL_TREE, size, |
4256 if (check_sizes (OPT_Wstringop_overflow_, | 4664 /*objsize=*/NULL_TREE); |
4257 exp, len, /*maxlen=*/NULL_TREE, | 4665 if (no_overflow) |
4258 size, /*objsize=*/NULL_TREE)) | 4666 { |
4259 { | 4667 size = compute_objsize (arg2, 0); |
4260 size = compute_objsize (arg2, 0); | 4668 no_overflow = check_access (exp, /*dst=*/NULL_TREE, /*src=*/NULL_TREE, |
4261 check_sizes (OPT_Wstringop_overflow_, | 4669 len, /*maxread=*/NULL_TREE, size, |
4262 exp, len, /*maxlen=*/NULL_TREE, | 4670 /*objsize=*/NULL_TREE); |
4263 size, /*objsize=*/NULL_TREE); | 4671 } |
4264 } | 4672 |
4673 /* If the specified length exceeds the size of either object, | |
4674 call the function. */ | |
4675 if (!no_overflow) | |
4676 return NULL_RTX; | |
4677 | |
4678 /* Due to the performance benefit, always inline the calls first | |
4679 when result_eq is false. */ | |
4680 rtx result = NULL_RTX; | |
4681 | |
4682 if (!result_eq && fcode != BUILT_IN_BCMP) | |
4683 { | |
4684 result = inline_expand_builtin_string_cmp (exp, target); | |
4685 if (result) | |
4686 return result; | |
4265 } | 4687 } |
4266 | 4688 |
4267 machine_mode mode = TYPE_MODE (TREE_TYPE (exp)); | 4689 machine_mode mode = TYPE_MODE (TREE_TYPE (exp)); |
4268 location_t loc = EXPR_LOCATION (exp); | 4690 location_t loc = EXPR_LOCATION (exp); |
4269 | 4691 |
4301 if (src_str | 4723 if (src_str |
4302 && CONST_INT_P (len_rtx) | 4724 && CONST_INT_P (len_rtx) |
4303 && (unsigned HOST_WIDE_INT) INTVAL (len_rtx) <= strlen (src_str) + 1) | 4725 && (unsigned HOST_WIDE_INT) INTVAL (len_rtx) <= strlen (src_str) + 1) |
4304 constfn = builtin_memcpy_read_str; | 4726 constfn = builtin_memcpy_read_str; |
4305 | 4727 |
4306 rtx result = emit_block_cmp_hints (arg1_rtx, arg2_rtx, len_rtx, | 4728 result = emit_block_cmp_hints (arg1_rtx, arg2_rtx, len_rtx, |
4307 TREE_TYPE (len), target, | 4729 TREE_TYPE (len), target, |
4308 result_eq, constfn, | 4730 result_eq, constfn, |
4309 CONST_CAST (char *, src_str)); | 4731 CONST_CAST (char *, src_str)); |
4310 | 4732 |
4311 if (result) | 4733 if (result) |
4312 { | 4734 { |
4313 /* Return the value in the proper mode for this function. */ | 4735 /* Return the value in the proper mode for this function. */ |
4314 if (GET_MODE (result) == mode) | 4736 if (GET_MODE (result) == mode) |
4334 expand_builtin_strcmp (tree exp, ATTRIBUTE_UNUSED rtx target) | 4756 expand_builtin_strcmp (tree exp, ATTRIBUTE_UNUSED rtx target) |
4335 { | 4757 { |
4336 if (!validate_arglist (exp, POINTER_TYPE, POINTER_TYPE, VOID_TYPE)) | 4758 if (!validate_arglist (exp, POINTER_TYPE, POINTER_TYPE, VOID_TYPE)) |
4337 return NULL_RTX; | 4759 return NULL_RTX; |
4338 | 4760 |
4761 /* Due to the performance benefit, always inline the calls first. */ | |
4762 rtx result = NULL_RTX; | |
4763 result = inline_expand_builtin_string_cmp (exp, target); | |
4764 if (result) | |
4765 return result; | |
4766 | |
4339 insn_code cmpstr_icode = direct_optab_handler (cmpstr_optab, SImode); | 4767 insn_code cmpstr_icode = direct_optab_handler (cmpstr_optab, SImode); |
4340 insn_code cmpstrn_icode = direct_optab_handler (cmpstrn_optab, SImode); | 4768 insn_code cmpstrn_icode = direct_optab_handler (cmpstrn_optab, SImode); |
4341 if (cmpstr_icode != CODE_FOR_nothing || cmpstrn_icode != CODE_FOR_nothing) | 4769 if (cmpstr_icode == CODE_FOR_nothing && cmpstrn_icode == CODE_FOR_nothing) |
4342 { | 4770 return NULL_RTX; |
4343 rtx arg1_rtx, arg2_rtx; | 4771 |
4344 tree fndecl, fn; | 4772 tree arg1 = CALL_EXPR_ARG (exp, 0); |
4345 tree arg1 = CALL_EXPR_ARG (exp, 0); | 4773 tree arg2 = CALL_EXPR_ARG (exp, 1); |
4346 tree arg2 = CALL_EXPR_ARG (exp, 1); | 4774 |
4347 rtx result = NULL_RTX; | 4775 unsigned int arg1_align = get_pointer_alignment (arg1) / BITS_PER_UNIT; |
4348 | 4776 unsigned int arg2_align = get_pointer_alignment (arg2) / BITS_PER_UNIT; |
4349 unsigned int arg1_align = get_pointer_alignment (arg1) / BITS_PER_UNIT; | 4777 |
4350 unsigned int arg2_align = get_pointer_alignment (arg2) / BITS_PER_UNIT; | 4778 /* If we don't have POINTER_TYPE, call the function. */ |
4351 | 4779 if (arg1_align == 0 || arg2_align == 0) |
4352 /* If we don't have POINTER_TYPE, call the function. */ | 4780 return NULL_RTX; |
4353 if (arg1_align == 0 || arg2_align == 0) | 4781 |
4354 return NULL_RTX; | 4782 /* Stabilize the arguments in case gen_cmpstr(n)si fail. */ |
4355 | 4783 arg1 = builtin_save_expr (arg1); |
4356 /* Stabilize the arguments in case gen_cmpstr(n)si fail. */ | 4784 arg2 = builtin_save_expr (arg2); |
4357 arg1 = builtin_save_expr (arg1); | 4785 |
4358 arg2 = builtin_save_expr (arg2); | 4786 rtx arg1_rtx = get_memory_rtx (arg1, NULL); |
4359 | 4787 rtx arg2_rtx = get_memory_rtx (arg2, NULL); |
4360 arg1_rtx = get_memory_rtx (arg1, NULL); | 4788 |
4361 arg2_rtx = get_memory_rtx (arg2, NULL); | 4789 /* Try to call cmpstrsi. */ |
4362 | 4790 if (cmpstr_icode != CODE_FOR_nothing) |
4363 /* Try to call cmpstrsi. */ | 4791 result = expand_cmpstr (cmpstr_icode, target, arg1_rtx, arg2_rtx, |
4364 if (cmpstr_icode != CODE_FOR_nothing) | 4792 MIN (arg1_align, arg2_align)); |
4365 result = expand_cmpstr (cmpstr_icode, target, arg1_rtx, arg2_rtx, | 4793 |
4366 MIN (arg1_align, arg2_align)); | 4794 /* Try to determine at least one length and call cmpstrnsi. */ |
4367 | 4795 if (!result && cmpstrn_icode != CODE_FOR_nothing) |
4368 /* Try to determine at least one length and call cmpstrnsi. */ | 4796 { |
4369 if (!result && cmpstrn_icode != CODE_FOR_nothing) | 4797 tree len; |
4798 rtx arg3_rtx; | |
4799 | |
4800 tree len1 = c_strlen (arg1, 1); | |
4801 tree len2 = c_strlen (arg2, 1); | |
4802 | |
4803 if (len1) | |
4804 len1 = size_binop (PLUS_EXPR, ssize_int (1), len1); | |
4805 if (len2) | |
4806 len2 = size_binop (PLUS_EXPR, ssize_int (1), len2); | |
4807 | |
4808 /* If we don't have a constant length for the first, use the length | |
4809 of the second, if we know it. We don't require a constant for | |
4810 this case; some cost analysis could be done if both are available | |
4811 but neither is constant. For now, assume they're equally cheap, | |
4812 unless one has side effects. If both strings have constant lengths, | |
4813 use the smaller. */ | |
4814 | |
4815 if (!len1) | |
4816 len = len2; | |
4817 else if (!len2) | |
4818 len = len1; | |
4819 else if (TREE_SIDE_EFFECTS (len1)) | |
4820 len = len2; | |
4821 else if (TREE_SIDE_EFFECTS (len2)) | |
4822 len = len1; | |
4823 else if (TREE_CODE (len1) != INTEGER_CST) | |
4824 len = len2; | |
4825 else if (TREE_CODE (len2) != INTEGER_CST) | |
4826 len = len1; | |
4827 else if (tree_int_cst_lt (len1, len2)) | |
4828 len = len1; | |
4829 else | |
4830 len = len2; | |
4831 | |
4832 /* If both arguments have side effects, we cannot optimize. */ | |
4833 if (len && !TREE_SIDE_EFFECTS (len)) | |
4370 { | 4834 { |
4371 tree len; | 4835 arg3_rtx = expand_normal (len); |
4372 rtx arg3_rtx; | 4836 result = expand_cmpstrn_or_cmpmem |
4373 | 4837 (cmpstrn_icode, target, arg1_rtx, arg2_rtx, TREE_TYPE (len), |
4374 tree len1 = c_strlen (arg1, 1); | 4838 arg3_rtx, MIN (arg1_align, arg2_align)); |
4375 tree len2 = c_strlen (arg2, 1); | |
4376 | |
4377 if (len1) | |
4378 len1 = size_binop (PLUS_EXPR, ssize_int (1), len1); | |
4379 if (len2) | |
4380 len2 = size_binop (PLUS_EXPR, ssize_int (1), len2); | |
4381 | |
4382 /* If we don't have a constant length for the first, use the length | |
4383 of the second, if we know it. We don't require a constant for | |
4384 this case; some cost analysis could be done if both are available | |
4385 but neither is constant. For now, assume they're equally cheap, | |
4386 unless one has side effects. If both strings have constant lengths, | |
4387 use the smaller. */ | |
4388 | |
4389 if (!len1) | |
4390 len = len2; | |
4391 else if (!len2) | |
4392 len = len1; | |
4393 else if (TREE_SIDE_EFFECTS (len1)) | |
4394 len = len2; | |
4395 else if (TREE_SIDE_EFFECTS (len2)) | |
4396 len = len1; | |
4397 else if (TREE_CODE (len1) != INTEGER_CST) | |
4398 len = len2; | |
4399 else if (TREE_CODE (len2) != INTEGER_CST) | |
4400 len = len1; | |
4401 else if (tree_int_cst_lt (len1, len2)) | |
4402 len = len1; | |
4403 else | |
4404 len = len2; | |
4405 | |
4406 /* If both arguments have side effects, we cannot optimize. */ | |
4407 if (len && !TREE_SIDE_EFFECTS (len)) | |
4408 { | |
4409 arg3_rtx = expand_normal (len); | |
4410 result = expand_cmpstrn_or_cmpmem | |
4411 (cmpstrn_icode, target, arg1_rtx, arg2_rtx, TREE_TYPE (len), | |
4412 arg3_rtx, MIN (arg1_align, arg2_align)); | |
4413 } | |
4414 } | 4839 } |
4415 | 4840 } |
4416 if (result) | 4841 |
4417 { | 4842 tree fndecl = get_callee_fndecl (exp); |
4418 /* Return the value in the proper mode for this function. */ | 4843 if (result) |
4419 machine_mode mode = TYPE_MODE (TREE_TYPE (exp)); | 4844 { |
4420 if (GET_MODE (result) == mode) | 4845 /* Check to see if the argument was declared attribute nonstring |
4421 return result; | 4846 and if so, issue a warning since at this point it's not known |
4422 if (target == 0) | 4847 to be nul-terminated. */ |
4423 return convert_to_mode (mode, result, 0); | 4848 maybe_warn_nonstring_arg (fndecl, exp); |
4424 convert_move (target, result, 0); | 4849 |
4425 return target; | 4850 /* Return the value in the proper mode for this function. */ |
4426 } | 4851 machine_mode mode = TYPE_MODE (TREE_TYPE (exp)); |
4427 | 4852 if (GET_MODE (result) == mode) |
4428 /* Expand the library call ourselves using a stabilized argument | 4853 return result; |
4429 list to avoid re-evaluating the function's arguments twice. */ | 4854 if (target == 0) |
4430 fndecl = get_callee_fndecl (exp); | 4855 return convert_to_mode (mode, result, 0); |
4431 fn = build_call_nofold_loc (EXPR_LOCATION (exp), fndecl, 2, arg1, arg2); | 4856 convert_move (target, result, 0); |
4432 gcc_assert (TREE_CODE (fn) == CALL_EXPR); | 4857 return target; |
4433 CALL_EXPR_TAILCALL (fn) = CALL_EXPR_TAILCALL (exp); | 4858 } |
4434 return expand_call (fn, target, target == const0_rtx); | 4859 |
4435 } | 4860 /* Expand the library call ourselves using a stabilized argument |
4436 return NULL_RTX; | 4861 list to avoid re-evaluating the function's arguments twice. */ |
4862 tree fn = build_call_nofold_loc (EXPR_LOCATION (exp), fndecl, 2, arg1, arg2); | |
4863 gcc_assert (TREE_CODE (fn) == CALL_EXPR); | |
4864 CALL_EXPR_TAILCALL (fn) = CALL_EXPR_TAILCALL (exp); | |
4865 return expand_call (fn, target, target == const0_rtx); | |
4437 } | 4866 } |
4438 | 4867 |
4439 /* Expand expression EXP, which is a call to the strncmp builtin. Return | 4868 /* Expand expression EXP, which is a call to the strncmp builtin. Return |
4440 NULL_RTX if we failed the caller should emit a normal call, otherwise try to get | 4869 NULL_RTX if we failed the caller should emit a normal call, otherwise try to get |
4441 the result in TARGET, if convenient. */ | 4870 the result in TARGET, if convenient. */ |
4442 | 4871 |
4443 static rtx | 4872 static rtx |
4444 expand_builtin_strncmp (tree exp, ATTRIBUTE_UNUSED rtx target, | 4873 expand_builtin_strncmp (tree exp, ATTRIBUTE_UNUSED rtx target, |
4445 ATTRIBUTE_UNUSED machine_mode mode) | 4874 ATTRIBUTE_UNUSED machine_mode mode) |
4446 { | 4875 { |
4447 location_t loc ATTRIBUTE_UNUSED = EXPR_LOCATION (exp); | |
4448 | |
4449 if (!validate_arglist (exp, | 4876 if (!validate_arglist (exp, |
4450 POINTER_TYPE, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE)) | 4877 POINTER_TYPE, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE)) |
4451 return NULL_RTX; | 4878 return NULL_RTX; |
4879 | |
4880 /* Due to the performance benefit, always inline the calls first. */ | |
4881 rtx result = NULL_RTX; | |
4882 result = inline_expand_builtin_string_cmp (exp, target); | |
4883 if (result) | |
4884 return result; | |
4452 | 4885 |
4453 /* If c_strlen can determine an expression for one of the string | 4886 /* If c_strlen can determine an expression for one of the string |
4454 lengths, and it doesn't have side effects, then emit cmpstrnsi | 4887 lengths, and it doesn't have side effects, then emit cmpstrnsi |
4455 using length MIN(strlen(string)+1, arg3). */ | 4888 using length MIN(strlen(string)+1, arg3). */ |
4456 insn_code cmpstrn_icode = direct_optab_handler (cmpstrn_optab, SImode); | 4889 insn_code cmpstrn_icode = direct_optab_handler (cmpstrn_optab, SImode); |
4457 if (cmpstrn_icode != CODE_FOR_nothing) | 4890 if (cmpstrn_icode == CODE_FOR_nothing) |
4458 { | 4891 return NULL_RTX; |
4459 tree len, len1, len2, len3; | 4892 |
4460 rtx arg1_rtx, arg2_rtx, arg3_rtx; | 4893 tree len; |
4461 rtx result; | 4894 |
4462 tree fndecl, fn; | 4895 tree arg1 = CALL_EXPR_ARG (exp, 0); |
4463 tree arg1 = CALL_EXPR_ARG (exp, 0); | 4896 tree arg2 = CALL_EXPR_ARG (exp, 1); |
4464 tree arg2 = CALL_EXPR_ARG (exp, 1); | 4897 tree arg3 = CALL_EXPR_ARG (exp, 2); |
4465 tree arg3 = CALL_EXPR_ARG (exp, 2); | 4898 |
4466 | 4899 unsigned int arg1_align = get_pointer_alignment (arg1) / BITS_PER_UNIT; |
4467 unsigned int arg1_align = get_pointer_alignment (arg1) / BITS_PER_UNIT; | 4900 unsigned int arg2_align = get_pointer_alignment (arg2) / BITS_PER_UNIT; |
4468 unsigned int arg2_align = get_pointer_alignment (arg2) / BITS_PER_UNIT; | 4901 |
4469 | 4902 tree len1 = c_strlen (arg1, 1); |
4470 len1 = c_strlen (arg1, 1); | 4903 tree len2 = c_strlen (arg2, 1); |
4471 len2 = c_strlen (arg2, 1); | 4904 |
4472 | 4905 location_t loc = EXPR_LOCATION (exp); |
4473 if (len1) | 4906 |
4474 len1 = size_binop_loc (loc, PLUS_EXPR, ssize_int (1), len1); | 4907 if (len1) |
4475 if (len2) | 4908 len1 = size_binop_loc (loc, PLUS_EXPR, ssize_int (1), len1); |
4476 len2 = size_binop_loc (loc, PLUS_EXPR, ssize_int (1), len2); | 4909 if (len2) |
4477 | 4910 len2 = size_binop_loc (loc, PLUS_EXPR, ssize_int (1), len2); |
4478 len3 = fold_convert_loc (loc, sizetype, arg3); | 4911 |
4479 | 4912 tree len3 = fold_convert_loc (loc, sizetype, arg3); |
4480 /* If we don't have a constant length for the first, use the length | 4913 |
4481 of the second, if we know it. If neither string is constant length, | 4914 /* If we don't have a constant length for the first, use the length |
4482 use the given length argument. We don't require a constant for | 4915 of the second, if we know it. If neither string is constant length, |
4483 this case; some cost analysis could be done if both are available | 4916 use the given length argument. We don't require a constant for |
4484 but neither is constant. For now, assume they're equally cheap, | 4917 this case; some cost analysis could be done if both are available |
4485 unless one has side effects. If both strings have constant lengths, | 4918 but neither is constant. For now, assume they're equally cheap, |
4486 use the smaller. */ | 4919 unless one has side effects. If both strings have constant lengths, |
4487 | 4920 use the smaller. */ |
4488 if (!len1 && !len2) | 4921 |
4489 len = len3; | 4922 if (!len1 && !len2) |
4490 else if (!len1) | 4923 len = len3; |
4491 len = len2; | 4924 else if (!len1) |
4492 else if (!len2) | 4925 len = len2; |
4493 len = len1; | 4926 else if (!len2) |
4494 else if (TREE_SIDE_EFFECTS (len1)) | 4927 len = len1; |
4495 len = len2; | 4928 else if (TREE_SIDE_EFFECTS (len1)) |
4496 else if (TREE_SIDE_EFFECTS (len2)) | 4929 len = len2; |
4497 len = len1; | 4930 else if (TREE_SIDE_EFFECTS (len2)) |
4498 else if (TREE_CODE (len1) != INTEGER_CST) | 4931 len = len1; |
4499 len = len2; | 4932 else if (TREE_CODE (len1) != INTEGER_CST) |
4500 else if (TREE_CODE (len2) != INTEGER_CST) | 4933 len = len2; |
4501 len = len1; | 4934 else if (TREE_CODE (len2) != INTEGER_CST) |
4502 else if (tree_int_cst_lt (len1, len2)) | 4935 len = len1; |
4503 len = len1; | 4936 else if (tree_int_cst_lt (len1, len2)) |
4504 else | 4937 len = len1; |
4505 len = len2; | 4938 else |
4506 | 4939 len = len2; |
4507 /* If we are not using the given length, we must incorporate it here. | 4940 |
4508 The actual new length parameter will be MIN(len,arg3) in this case. */ | 4941 /* If we are not using the given length, we must incorporate it here. |
4509 if (len != len3) | 4942 The actual new length parameter will be MIN(len,arg3) in this case. */ |
4943 if (len != len3) | |
4944 { | |
4945 len = fold_convert_loc (loc, sizetype, len); | |
4510 len = fold_build2_loc (loc, MIN_EXPR, TREE_TYPE (len), len, len3); | 4946 len = fold_build2_loc (loc, MIN_EXPR, TREE_TYPE (len), len, len3); |
4511 arg1_rtx = get_memory_rtx (arg1, len); | 4947 } |
4512 arg2_rtx = get_memory_rtx (arg2, len); | 4948 rtx arg1_rtx = get_memory_rtx (arg1, len); |
4513 arg3_rtx = expand_normal (len); | 4949 rtx arg2_rtx = get_memory_rtx (arg2, len); |
4514 result = expand_cmpstrn_or_cmpmem (cmpstrn_icode, target, arg1_rtx, | 4950 rtx arg3_rtx = expand_normal (len); |
4515 arg2_rtx, TREE_TYPE (len), arg3_rtx, | 4951 result = expand_cmpstrn_or_cmpmem (cmpstrn_icode, target, arg1_rtx, |
4516 MIN (arg1_align, arg2_align)); | 4952 arg2_rtx, TREE_TYPE (len), arg3_rtx, |
4517 if (result) | 4953 MIN (arg1_align, arg2_align)); |
4518 { | 4954 |
4519 /* Return the value in the proper mode for this function. */ | 4955 tree fndecl = get_callee_fndecl (exp); |
4520 mode = TYPE_MODE (TREE_TYPE (exp)); | 4956 if (result) |
4521 if (GET_MODE (result) == mode) | 4957 { |
4522 return result; | 4958 /* Check to see if the argument was declared attribute nonstring |
4523 if (target == 0) | 4959 and if so, issue a warning since at this point it's not known |
4524 return convert_to_mode (mode, result, 0); | 4960 to be nul-terminated. */ |
4525 convert_move (target, result, 0); | 4961 maybe_warn_nonstring_arg (fndecl, exp); |
4526 return target; | 4962 |
4527 } | 4963 /* Return the value in the proper mode for this function. */ |
4528 | 4964 mode = TYPE_MODE (TREE_TYPE (exp)); |
4529 /* Expand the library call ourselves using a stabilized argument | 4965 if (GET_MODE (result) == mode) |
4530 list to avoid re-evaluating the function's arguments twice. */ | 4966 return result; |
4531 fndecl = get_callee_fndecl (exp); | 4967 if (target == 0) |
4532 fn = build_call_nofold_loc (EXPR_LOCATION (exp), fndecl, 3, | 4968 return convert_to_mode (mode, result, 0); |
4533 arg1, arg2, len); | 4969 convert_move (target, result, 0); |
4534 gcc_assert (TREE_CODE (fn) == CALL_EXPR); | 4970 return target; |
4535 CALL_EXPR_TAILCALL (fn) = CALL_EXPR_TAILCALL (exp); | 4971 } |
4536 return expand_call (fn, target, target == const0_rtx); | 4972 |
4537 } | 4973 /* Expand the library call ourselves using a stabilized argument |
4538 return NULL_RTX; | 4974 list to avoid re-evaluating the function's arguments twice. */ |
4975 tree fn = build_call_nofold_loc (loc, fndecl, 3, arg1, arg2, len); | |
4976 gcc_assert (TREE_CODE (fn) == CALL_EXPR); | |
4977 CALL_EXPR_TAILCALL (fn) = CALL_EXPR_TAILCALL (exp); | |
4978 return expand_call (fn, target, target == const0_rtx); | |
4539 } | 4979 } |
4540 | 4980 |
4541 /* Expand a call to __builtin_saveregs, generating the result in TARGET, | 4981 /* Expand a call to __builtin_saveregs, generating the result in TARGET, |
4542 if that's convenient. */ | 4982 if that's convenient. */ |
4543 | 4983 |
4690 void | 5130 void |
4691 std_expand_builtin_va_start (tree valist, rtx nextarg) | 5131 std_expand_builtin_va_start (tree valist, rtx nextarg) |
4692 { | 5132 { |
4693 rtx va_r = expand_expr (valist, NULL_RTX, VOIDmode, EXPAND_WRITE); | 5133 rtx va_r = expand_expr (valist, NULL_RTX, VOIDmode, EXPAND_WRITE); |
4694 convert_move (va_r, nextarg, 0); | 5134 convert_move (va_r, nextarg, 0); |
4695 | |
4696 /* We do not have any valid bounds for the pointer, so | |
4697 just store zero bounds for it. */ | |
4698 if (chkp_function_instrumented_p (current_function_decl)) | |
4699 chkp_expand_bounds_reset_for_mem (valist, | |
4700 make_tree (TREE_TYPE (valist), | |
4701 nextarg)); | |
4702 } | 5135 } |
4703 | 5136 |
4704 /* Expand EXP, a call to __builtin_va_start. */ | 5137 /* Expand EXP, a call to __builtin_va_start. */ |
4705 | 5138 |
4706 static rtx | 5139 static rtx |
4870 : validate_arglist (exp, INTEGER_TYPE, VOID_TYPE)); | 5303 : validate_arglist (exp, INTEGER_TYPE, VOID_TYPE)); |
4871 | 5304 |
4872 if (!valid_arglist) | 5305 if (!valid_arglist) |
4873 return NULL_RTX; | 5306 return NULL_RTX; |
4874 | 5307 |
4875 if ((alloca_for_var && !warn_vla_limit) | 5308 if ((alloca_for_var |
4876 || (!alloca_for_var && !warn_alloca_limit)) | 5309 && warn_vla_limit >= HOST_WIDE_INT_MAX |
4877 { | 5310 && warn_alloc_size_limit < warn_vla_limit) |
4878 /* -Walloca-larger-than and -Wvla-larger-than settings override | 5311 || (!alloca_for_var |
4879 the more general -Walloc-size-larger-than so unless either of | 5312 && warn_alloca_limit >= HOST_WIDE_INT_MAX |
4880 the former options is specified check the alloca arguments for | 5313 && warn_alloc_size_limit < warn_alloca_limit |
4881 overflow. */ | 5314 )) |
5315 { | |
5316 /* -Walloca-larger-than and -Wvla-larger-than settings of | |
5317 less than HOST_WIDE_INT_MAX override the more general | |
5318 -Walloc-size-larger-than so unless either of the former | |
5319 options is smaller than the last one (wchich would imply | |
5320 that the call was already checked), check the alloca | |
5321 arguments for overflow. */ | |
4882 tree args[] = { CALL_EXPR_ARG (exp, 0), NULL_TREE }; | 5322 tree args[] = { CALL_EXPR_ARG (exp, 0), NULL_TREE }; |
4883 int idx[] = { 0, -1 }; | 5323 int idx[] = { 0, -1 }; |
4884 maybe_warn_alloc_args_overflow (fndecl, exp, args, idx); | 5324 maybe_warn_alloc_args_overflow (fndecl, exp, args, idx); |
4885 } | 5325 } |
4886 | 5326 |
4904 result = convert_memory_address (ptr_mode, result); | 5344 result = convert_memory_address (ptr_mode, result); |
4905 | 5345 |
4906 return result; | 5346 return result; |
4907 } | 5347 } |
4908 | 5348 |
4909 /* Emit a call to __asan_allocas_unpoison call in EXP. Replace second argument | 5349 /* Emit a call to __asan_allocas_unpoison call in EXP. Add to second argument |
4910 of the call with virtual_stack_dynamic_rtx because in asan pass we emit a | 5350 of the call virtual_stack_dynamic_rtx - stack_pointer_rtx, which is the |
4911 dummy value into second parameter relying on this function to perform the | 5351 STACK_DYNAMIC_OFFSET value. See motivation for this in comment to |
4912 change. See motivation for this in comment to handle_builtin_stack_restore | 5352 handle_builtin_stack_restore function. */ |
4913 function. */ | |
4914 | 5353 |
4915 static rtx | 5354 static rtx |
4916 expand_asan_emit_allocas_unpoison (tree exp) | 5355 expand_asan_emit_allocas_unpoison (tree exp) |
4917 { | 5356 { |
4918 tree arg0 = CALL_EXPR_ARG (exp, 0); | 5357 tree arg0 = CALL_EXPR_ARG (exp, 0); |
5358 tree arg1 = CALL_EXPR_ARG (exp, 1); | |
4919 rtx top = expand_expr (arg0, NULL_RTX, ptr_mode, EXPAND_NORMAL); | 5359 rtx top = expand_expr (arg0, NULL_RTX, ptr_mode, EXPAND_NORMAL); |
4920 rtx bot = convert_memory_address (ptr_mode, virtual_stack_dynamic_rtx); | 5360 rtx bot = expand_expr (arg1, NULL_RTX, ptr_mode, EXPAND_NORMAL); |
5361 rtx off = expand_simple_binop (Pmode, MINUS, virtual_stack_dynamic_rtx, | |
5362 stack_pointer_rtx, NULL_RTX, 0, | |
5363 OPTAB_LIB_WIDEN); | |
5364 off = convert_modes (ptr_mode, Pmode, off, 0); | |
5365 bot = expand_simple_binop (ptr_mode, PLUS, bot, off, NULL_RTX, 0, | |
5366 OPTAB_LIB_WIDEN); | |
4921 rtx ret = init_one_libfunc ("__asan_allocas_unpoison"); | 5367 rtx ret = init_one_libfunc ("__asan_allocas_unpoison"); |
4922 ret = emit_library_call_value (ret, NULL_RTX, LCT_NORMAL, ptr_mode, | 5368 ret = emit_library_call_value (ret, NULL_RTX, LCT_NORMAL, ptr_mode, |
4923 top, ptr_mode, bot, ptr_mode); | 5369 top, ptr_mode, bot, ptr_mode); |
4924 return ret; | 5370 return ret; |
4925 } | 5371 } |
5001 gcc_assert (!flag_guess_branch_prob | 5447 gcc_assert (!flag_guess_branch_prob |
5002 || optimize == 0 || seen_error ()); | 5448 || optimize == 0 || seen_error ()); |
5003 return target; | 5449 return target; |
5004 } | 5450 } |
5005 | 5451 |
5452 /* Expand a call to __builtin_expect_with_probability. We just return our | |
5453 argument as the builtin_expect semantic should've been already executed by | |
5454 tree branch prediction pass. */ | |
5455 | |
5456 static rtx | |
5457 expand_builtin_expect_with_probability (tree exp, rtx target) | |
5458 { | |
5459 tree arg; | |
5460 | |
5461 if (call_expr_nargs (exp) < 3) | |
5462 return const0_rtx; | |
5463 arg = CALL_EXPR_ARG (exp, 0); | |
5464 | |
5465 target = expand_expr (arg, target, VOIDmode, EXPAND_NORMAL); | |
5466 /* When guessing was done, the hints should be already stripped away. */ | |
5467 gcc_assert (!flag_guess_branch_prob | |
5468 || optimize == 0 || seen_error ()); | |
5469 return target; | |
5470 } | |
5471 | |
5472 | |
5006 /* Expand a call to __builtin_assume_aligned. We just return our first | 5473 /* Expand a call to __builtin_assume_aligned. We just return our first |
5007 argument as the builtin_assume_aligned semantic should've been already | 5474 argument as the builtin_assume_aligned semantic should've been already |
5008 executed by CCP. */ | 5475 executed by CCP. */ |
5009 | 5476 |
5010 static rtx | 5477 static rtx |
5028 rtx_insn *insn = emit_insn (targetm.gen_trap ()); | 5495 rtx_insn *insn = emit_insn (targetm.gen_trap ()); |
5029 /* For trap insns when not accumulating outgoing args force | 5496 /* For trap insns when not accumulating outgoing args force |
5030 REG_ARGS_SIZE note to prevent crossjumping of calls with | 5497 REG_ARGS_SIZE note to prevent crossjumping of calls with |
5031 different args sizes. */ | 5498 different args sizes. */ |
5032 if (!ACCUMULATE_OUTGOING_ARGS) | 5499 if (!ACCUMULATE_OUTGOING_ARGS) |
5033 add_reg_note (insn, REG_ARGS_SIZE, GEN_INT (stack_pointer_delta)); | 5500 add_args_size_note (insn, stack_pointer_delta); |
5034 } | 5501 } |
5035 else | 5502 else |
5036 { | 5503 { |
5037 tree fn = builtin_decl_implicit (BUILT_IN_ABORT); | 5504 tree fn = builtin_decl_implicit (BUILT_IN_ABORT); |
5038 tree call_expr = build_call_expr (fn, 0); | 5505 tree call_expr = build_call_expr (fn, 0); |
5495 | 5962 |
5496 static rtx | 5963 static rtx |
5497 get_builtin_sync_mem (tree loc, machine_mode mode) | 5964 get_builtin_sync_mem (tree loc, machine_mode mode) |
5498 { | 5965 { |
5499 rtx addr, mem; | 5966 rtx addr, mem; |
5500 | 5967 int addr_space = TYPE_ADDR_SPACE (POINTER_TYPE_P (TREE_TYPE (loc)) |
5501 addr = expand_expr (loc, NULL_RTX, ptr_mode, EXPAND_SUM); | 5968 ? TREE_TYPE (TREE_TYPE (loc)) |
5502 addr = convert_memory_address (Pmode, addr); | 5969 : TREE_TYPE (loc)); |
5970 scalar_int_mode addr_mode = targetm.addr_space.address_mode (addr_space); | |
5971 | |
5972 addr = expand_expr (loc, NULL_RTX, addr_mode, EXPAND_SUM); | |
5973 addr = convert_memory_address (addr_mode, addr); | |
5503 | 5974 |
5504 /* Note that we explicitly do not want any alias information for this | 5975 /* Note that we explicitly do not want any alias information for this |
5505 memory, so that we kill all other live memories. Otherwise we don't | 5976 memory, so that we kill all other live memories. Otherwise we don't |
5506 satisfy the full barrier semantics of the intrinsic. */ | 5977 satisfy the full barrier semantics of the intrinsic. */ |
5507 mem = validize_mem (gen_rtx_MEM (mode, addr)); | 5978 mem = gen_rtx_MEM (mode, addr); |
5979 | |
5980 set_mem_addr_space (mem, addr_space); | |
5981 | |
5982 mem = validize_mem (mem); | |
5508 | 5983 |
5509 /* The alignment needs to be at least according to that of the mode. */ | 5984 /* The alignment needs to be at least according to that of the mode. */ |
5510 set_mem_align (mem, MAX (GET_MODE_ALIGNMENT (mode), | 5985 set_mem_align (mem, MAX (GET_MODE_ALIGNMENT (mode), |
5511 get_pointer_alignment (loc))); | 5986 get_pointer_alignment (loc))); |
5512 set_mem_alias_set (mem, ALIAS_SET_MEMORY_BARRIER); | 5987 set_mem_alias_set (mem, ALIAS_SET_MEMORY_BARRIER); |
5839 build_pointer_type (TREE_TYPE (expected)), v)); | 6314 build_pointer_type (TREE_TYPE (expected)), v)); |
5840 vec->quick_push (gimple_call_arg (call, 2)); | 6315 vec->quick_push (gimple_call_arg (call, 2)); |
5841 /* Skip the boolean weak parameter. */ | 6316 /* Skip the boolean weak parameter. */ |
5842 for (z = 4; z < 6; z++) | 6317 for (z = 4; z < 6; z++) |
5843 vec->quick_push (gimple_call_arg (call, z)); | 6318 vec->quick_push (gimple_call_arg (call, z)); |
6319 /* At present we only have BUILT_IN_ATOMIC_COMPARE_EXCHANGE_{1,2,4,8,16}. */ | |
6320 unsigned int bytes_log2 = exact_log2 (GET_MODE_SIZE (mode).to_constant ()); | |
6321 gcc_assert (bytes_log2 < 5); | |
5844 built_in_function fncode | 6322 built_in_function fncode |
5845 = (built_in_function) ((int) BUILT_IN_ATOMIC_COMPARE_EXCHANGE_1 | 6323 = (built_in_function) ((int) BUILT_IN_ATOMIC_COMPARE_EXCHANGE_1 |
5846 + exact_log2 (GET_MODE_SIZE (mode))); | 6324 + bytes_log2); |
5847 tree fndecl = builtin_decl_explicit (fncode); | 6325 tree fndecl = builtin_decl_explicit (fncode); |
5848 tree fn = build1 (ADDR_EXPR, build_pointer_type (TREE_TYPE (fndecl)), | 6326 tree fn = build1 (ADDR_EXPR, build_pointer_type (TREE_TYPE (fndecl)), |
5849 fndecl); | 6327 fndecl); |
5850 tree exp = build_call_vec (boolean_type_node, fn, vec); | 6328 tree exp = build_call_vec (boolean_type_node, fn, vec); |
5851 tree lhs = gimple_call_lhs (call); | 6329 tree lhs = gimple_call_lhs (call); |
6451 | 6929 |
6452 emit_stack_save (SAVE_BLOCK, &ret); | 6930 emit_stack_save (SAVE_BLOCK, &ret); |
6453 return ret; | 6931 return ret; |
6454 } | 6932 } |
6455 | 6933 |
6934 /* Emit code to get the openacc gang, worker or vector id or size. */ | |
6935 | |
6936 static rtx | |
6937 expand_builtin_goacc_parlevel_id_size (tree exp, rtx target, int ignore) | |
6938 { | |
6939 const char *name; | |
6940 rtx fallback_retval; | |
6941 rtx_insn *(*gen_fn) (rtx, rtx); | |
6942 switch (DECL_FUNCTION_CODE (get_callee_fndecl (exp))) | |
6943 { | |
6944 case BUILT_IN_GOACC_PARLEVEL_ID: | |
6945 name = "__builtin_goacc_parlevel_id"; | |
6946 fallback_retval = const0_rtx; | |
6947 gen_fn = targetm.gen_oacc_dim_pos; | |
6948 break; | |
6949 case BUILT_IN_GOACC_PARLEVEL_SIZE: | |
6950 name = "__builtin_goacc_parlevel_size"; | |
6951 fallback_retval = const1_rtx; | |
6952 gen_fn = targetm.gen_oacc_dim_size; | |
6953 break; | |
6954 default: | |
6955 gcc_unreachable (); | |
6956 } | |
6957 | |
6958 if (oacc_get_fn_attrib (current_function_decl) == NULL_TREE) | |
6959 { | |
6960 error ("%qs only supported in OpenACC code", name); | |
6961 return const0_rtx; | |
6962 } | |
6963 | |
6964 tree arg = CALL_EXPR_ARG (exp, 0); | |
6965 if (TREE_CODE (arg) != INTEGER_CST) | |
6966 { | |
6967 error ("non-constant argument 0 to %qs", name); | |
6968 return const0_rtx; | |
6969 } | |
6970 | |
6971 int dim = TREE_INT_CST_LOW (arg); | |
6972 switch (dim) | |
6973 { | |
6974 case GOMP_DIM_GANG: | |
6975 case GOMP_DIM_WORKER: | |
6976 case GOMP_DIM_VECTOR: | |
6977 break; | |
6978 default: | |
6979 error ("illegal argument 0 to %qs", name); | |
6980 return const0_rtx; | |
6981 } | |
6982 | |
6983 if (ignore) | |
6984 return target; | |
6985 | |
6986 if (target == NULL_RTX) | |
6987 target = gen_reg_rtx (TYPE_MODE (TREE_TYPE (exp))); | |
6988 | |
6989 if (!targetm.have_oacc_dim_size ()) | |
6990 { | |
6991 emit_move_insn (target, fallback_retval); | |
6992 return target; | |
6993 } | |
6994 | |
6995 rtx reg = MEM_P (target) ? gen_reg_rtx (GET_MODE (target)) : target; | |
6996 emit_insn (gen_fn (reg, GEN_INT (dim))); | |
6997 if (reg != target) | |
6998 emit_move_insn (target, reg); | |
6999 | |
7000 return target; | |
7001 } | |
7002 | |
7003 /* Expand a string compare operation using a sequence of char comparison | |
7004 to get rid of the calling overhead, with result going to TARGET if | |
7005 that's convenient. | |
7006 | |
7007 VAR_STR is the variable string source; | |
7008 CONST_STR is the constant string source; | |
7009 LENGTH is the number of chars to compare; | |
7010 CONST_STR_N indicates which source string is the constant string; | |
7011 IS_MEMCMP indicates whether it's a memcmp or strcmp. | |
7012 | |
7013 to: (assume const_str_n is 2, i.e., arg2 is a constant string) | |
7014 | |
7015 target = (int) (unsigned char) var_str[0] | |
7016 - (int) (unsigned char) const_str[0]; | |
7017 if (target != 0) | |
7018 goto ne_label; | |
7019 ... | |
7020 target = (int) (unsigned char) var_str[length - 2] | |
7021 - (int) (unsigned char) const_str[length - 2]; | |
7022 if (target != 0) | |
7023 goto ne_label; | |
7024 target = (int) (unsigned char) var_str[length - 1] | |
7025 - (int) (unsigned char) const_str[length - 1]; | |
7026 ne_label: | |
7027 */ | |
7028 | |
7029 static rtx | |
7030 inline_string_cmp (rtx target, tree var_str, const char *const_str, | |
7031 unsigned HOST_WIDE_INT length, | |
7032 int const_str_n, machine_mode mode) | |
7033 { | |
7034 HOST_WIDE_INT offset = 0; | |
7035 rtx var_rtx_array | |
7036 = get_memory_rtx (var_str, build_int_cst (unsigned_type_node,length)); | |
7037 rtx var_rtx = NULL_RTX; | |
7038 rtx const_rtx = NULL_RTX; | |
7039 rtx result = target ? target : gen_reg_rtx (mode); | |
7040 rtx_code_label *ne_label = gen_label_rtx (); | |
7041 tree unit_type_node = unsigned_char_type_node; | |
7042 scalar_int_mode unit_mode | |
7043 = as_a <scalar_int_mode> TYPE_MODE (unit_type_node); | |
7044 | |
7045 start_sequence (); | |
7046 | |
7047 for (unsigned HOST_WIDE_INT i = 0; i < length; i++) | |
7048 { | |
7049 var_rtx | |
7050 = adjust_address (var_rtx_array, TYPE_MODE (unit_type_node), offset); | |
7051 const_rtx = c_readstr (const_str + offset, unit_mode); | |
7052 rtx op0 = (const_str_n == 1) ? const_rtx : var_rtx; | |
7053 rtx op1 = (const_str_n == 1) ? var_rtx : const_rtx; | |
7054 | |
7055 op0 = convert_modes (mode, unit_mode, op0, 1); | |
7056 op1 = convert_modes (mode, unit_mode, op1, 1); | |
7057 result = expand_simple_binop (mode, MINUS, op0, op1, | |
7058 result, 1, OPTAB_WIDEN); | |
7059 if (i < length - 1) | |
7060 emit_cmp_and_jump_insns (result, CONST0_RTX (mode), NE, NULL_RTX, | |
7061 mode, true, ne_label); | |
7062 offset += GET_MODE_SIZE (unit_mode); | |
7063 } | |
7064 | |
7065 emit_label (ne_label); | |
7066 rtx_insn *insns = get_insns (); | |
7067 end_sequence (); | |
7068 emit_insn (insns); | |
7069 | |
7070 return result; | |
7071 } | |
7072 | |
7073 /* Inline expansion a call to str(n)cmp, with result going to | |
7074 TARGET if that's convenient. | |
7075 If the call is not been inlined, return NULL_RTX. */ | |
7076 static rtx | |
7077 inline_expand_builtin_string_cmp (tree exp, rtx target) | |
7078 { | |
7079 tree fndecl = get_callee_fndecl (exp); | |
7080 enum built_in_function fcode = DECL_FUNCTION_CODE (fndecl); | |
7081 unsigned HOST_WIDE_INT length = 0; | |
7082 bool is_ncmp = (fcode == BUILT_IN_STRNCMP || fcode == BUILT_IN_MEMCMP); | |
7083 | |
7084 /* Do NOT apply this inlining expansion when optimizing for size or | |
7085 optimization level below 2. */ | |
7086 if (optimize < 2 || optimize_insn_for_size_p ()) | |
7087 return NULL_RTX; | |
7088 | |
7089 gcc_checking_assert (fcode == BUILT_IN_STRCMP | |
7090 || fcode == BUILT_IN_STRNCMP | |
7091 || fcode == BUILT_IN_MEMCMP); | |
7092 | |
7093 /* On a target where the type of the call (int) has same or narrower presicion | |
7094 than unsigned char, give up the inlining expansion. */ | |
7095 if (TYPE_PRECISION (unsigned_char_type_node) | |
7096 >= TYPE_PRECISION (TREE_TYPE (exp))) | |
7097 return NULL_RTX; | |
7098 | |
7099 tree arg1 = CALL_EXPR_ARG (exp, 0); | |
7100 tree arg2 = CALL_EXPR_ARG (exp, 1); | |
7101 tree len3_tree = is_ncmp ? CALL_EXPR_ARG (exp, 2) : NULL_TREE; | |
7102 | |
7103 unsigned HOST_WIDE_INT len1 = 0; | |
7104 unsigned HOST_WIDE_INT len2 = 0; | |
7105 unsigned HOST_WIDE_INT len3 = 0; | |
7106 | |
7107 const char *src_str1 = c_getstr (arg1, &len1); | |
7108 const char *src_str2 = c_getstr (arg2, &len2); | |
7109 | |
7110 /* If neither strings is constant string, the call is not qualify. */ | |
7111 if (!src_str1 && !src_str2) | |
7112 return NULL_RTX; | |
7113 | |
7114 /* For strncmp, if the length is not a const, not qualify. */ | |
7115 if (is_ncmp && !tree_fits_uhwi_p (len3_tree)) | |
7116 return NULL_RTX; | |
7117 | |
7118 int const_str_n = 0; | |
7119 if (!len1) | |
7120 const_str_n = 2; | |
7121 else if (!len2) | |
7122 const_str_n = 1; | |
7123 else if (len2 > len1) | |
7124 const_str_n = 1; | |
7125 else | |
7126 const_str_n = 2; | |
7127 | |
7128 gcc_checking_assert (const_str_n > 0); | |
7129 length = (const_str_n == 1) ? len1 : len2; | |
7130 | |
7131 if (is_ncmp && (len3 = tree_to_uhwi (len3_tree)) < length) | |
7132 length = len3; | |
7133 | |
7134 /* If the length of the comparision is larger than the threshold, | |
7135 do nothing. */ | |
7136 if (length > (unsigned HOST_WIDE_INT) | |
7137 PARAM_VALUE (BUILTIN_STRING_CMP_INLINE_LENGTH)) | |
7138 return NULL_RTX; | |
7139 | |
7140 machine_mode mode = TYPE_MODE (TREE_TYPE (exp)); | |
7141 | |
7142 /* Now, start inline expansion the call. */ | |
7143 return inline_string_cmp (target, (const_str_n == 1) ? arg2 : arg1, | |
7144 (const_str_n == 1) ? src_str1 : src_str2, length, | |
7145 const_str_n, mode); | |
7146 } | |
7147 | |
7148 /* Expand a call to __builtin_speculation_safe_value_<N>. MODE | |
7149 represents the size of the first argument to that call, or VOIDmode | |
7150 if the argument is a pointer. IGNORE will be true if the result | |
7151 isn't used. */ | |
7152 static rtx | |
7153 expand_speculation_safe_value (machine_mode mode, tree exp, rtx target, | |
7154 bool ignore) | |
7155 { | |
7156 rtx val, failsafe; | |
7157 unsigned nargs = call_expr_nargs (exp); | |
7158 | |
7159 tree arg0 = CALL_EXPR_ARG (exp, 0); | |
7160 | |
7161 if (mode == VOIDmode) | |
7162 { | |
7163 mode = TYPE_MODE (TREE_TYPE (arg0)); | |
7164 gcc_assert (GET_MODE_CLASS (mode) == MODE_INT); | |
7165 } | |
7166 | |
7167 val = expand_expr (arg0, NULL_RTX, mode, EXPAND_NORMAL); | |
7168 | |
7169 /* An optional second argument can be used as a failsafe value on | |
7170 some machines. If it isn't present, then the failsafe value is | |
7171 assumed to be 0. */ | |
7172 if (nargs > 1) | |
7173 { | |
7174 tree arg1 = CALL_EXPR_ARG (exp, 1); | |
7175 failsafe = expand_expr (arg1, NULL_RTX, mode, EXPAND_NORMAL); | |
7176 } | |
7177 else | |
7178 failsafe = const0_rtx; | |
7179 | |
7180 /* If the result isn't used, the behavior is undefined. It would be | |
7181 nice to emit a warning here, but path splitting means this might | |
7182 happen with legitimate code. So simply drop the builtin | |
7183 expansion in that case; we've handled any side-effects above. */ | |
7184 if (ignore) | |
7185 return const0_rtx; | |
7186 | |
7187 /* If we don't have a suitable target, create one to hold the result. */ | |
7188 if (target == NULL || GET_MODE (target) != mode) | |
7189 target = gen_reg_rtx (mode); | |
7190 | |
7191 if (GET_MODE (val) != mode && GET_MODE (val) != VOIDmode) | |
7192 val = convert_modes (mode, VOIDmode, val, false); | |
7193 | |
7194 return targetm.speculation_safe_value (mode, target, val, failsafe); | |
7195 } | |
6456 | 7196 |
6457 /* Expand an expression EXP that calls a built-in function, | 7197 /* Expand an expression EXP that calls a built-in function, |
6458 with result going to TARGET if that's convenient | 7198 with result going to TARGET if that's convenient |
6459 (and in mode MODE if that's convenient). | 7199 (and in mode MODE if that's convenient). |
6460 SUBTARGET may be used as the target for computing one of EXP's operands. | 7200 SUBTARGET may be used as the target for computing one of EXP's operands. |
6490 && fcode != BUILT_IN_EXECLP | 7230 && fcode != BUILT_IN_EXECLP |
6491 && fcode != BUILT_IN_EXECLE | 7231 && fcode != BUILT_IN_EXECLE |
6492 && fcode != BUILT_IN_EXECVP | 7232 && fcode != BUILT_IN_EXECVP |
6493 && fcode != BUILT_IN_EXECVE | 7233 && fcode != BUILT_IN_EXECVE |
6494 && !ALLOCA_FUNCTION_CODE_P (fcode) | 7234 && !ALLOCA_FUNCTION_CODE_P (fcode) |
6495 && fcode != BUILT_IN_FREE | 7235 && fcode != BUILT_IN_FREE) |
6496 && fcode != BUILT_IN_CHKP_SET_PTR_BOUNDS | |
6497 && fcode != BUILT_IN_CHKP_INIT_PTR_BOUNDS | |
6498 && fcode != BUILT_IN_CHKP_NULL_PTR_BOUNDS | |
6499 && fcode != BUILT_IN_CHKP_COPY_PTR_BOUNDS | |
6500 && fcode != BUILT_IN_CHKP_NARROW_PTR_BOUNDS | |
6501 && fcode != BUILT_IN_CHKP_STORE_PTR_BOUNDS | |
6502 && fcode != BUILT_IN_CHKP_CHECK_PTR_LBOUNDS | |
6503 && fcode != BUILT_IN_CHKP_CHECK_PTR_UBOUNDS | |
6504 && fcode != BUILT_IN_CHKP_CHECK_PTR_BOUNDS | |
6505 && fcode != BUILT_IN_CHKP_GET_PTR_LBOUND | |
6506 && fcode != BUILT_IN_CHKP_GET_PTR_UBOUND | |
6507 && fcode != BUILT_IN_CHKP_BNDRET) | |
6508 return expand_call (exp, target, ignore); | 7236 return expand_call (exp, target, ignore); |
6509 | 7237 |
6510 /* The built-in function expanders test for target == const0_rtx | 7238 /* The built-in function expanders test for target == const0_rtx |
6511 to determine whether the function's result will be ignored. */ | 7239 to determine whether the function's result will be ignored. */ |
6512 if (ignore) | 7240 if (ignore) |
6535 FOR_EACH_CALL_EXPR_ARG (arg, iter, exp) | 7263 FOR_EACH_CALL_EXPR_ARG (arg, iter, exp) |
6536 expand_expr (arg, const0_rtx, VOIDmode, EXPAND_NORMAL); | 7264 expand_expr (arg, const0_rtx, VOIDmode, EXPAND_NORMAL); |
6537 return const0_rtx; | 7265 return const0_rtx; |
6538 } | 7266 } |
6539 } | 7267 } |
6540 | |
6541 /* expand_builtin_with_bounds is supposed to be used for | |
6542 instrumented builtin calls. */ | |
6543 gcc_assert (!CALL_WITH_BOUNDS_P (exp)); | |
6544 | 7268 |
6545 switch (fcode) | 7269 switch (fcode) |
6546 { | 7270 { |
6547 CASE_FLT_FN (BUILT_IN_FABS): | 7271 CASE_FLT_FN (BUILT_IN_FABS): |
6548 CASE_FLT_FN_FLOATN_NX (BUILT_IN_FABS): | 7272 CASE_FLT_FN_FLOATN_NX (BUILT_IN_FABS): |
6565 the values. */ | 7289 the values. */ |
6566 CASE_FLT_FN (BUILT_IN_CABS): | 7290 CASE_FLT_FN (BUILT_IN_CABS): |
6567 break; | 7291 break; |
6568 | 7292 |
6569 CASE_FLT_FN (BUILT_IN_FMA): | 7293 CASE_FLT_FN (BUILT_IN_FMA): |
7294 CASE_FLT_FN_FLOATN_NX (BUILT_IN_FMA): | |
6570 target = expand_builtin_mathfn_ternary (exp, target, subtarget); | 7295 target = expand_builtin_mathfn_ternary (exp, target, subtarget); |
6571 if (target) | 7296 if (target) |
6572 return target; | 7297 return target; |
6573 break; | 7298 break; |
6574 | 7299 |
6790 target = expand_builtin_strlen (exp, target, target_mode); | 7515 target = expand_builtin_strlen (exp, target, target_mode); |
6791 if (target) | 7516 if (target) |
6792 return target; | 7517 return target; |
6793 break; | 7518 break; |
6794 | 7519 |
7520 case BUILT_IN_STRNLEN: | |
7521 target = expand_builtin_strnlen (exp, target, target_mode); | |
7522 if (target) | |
7523 return target; | |
7524 break; | |
7525 | |
6795 case BUILT_IN_STRCAT: | 7526 case BUILT_IN_STRCAT: |
6796 target = expand_builtin_strcat (exp, target); | 7527 target = expand_builtin_strcat (exp, target); |
6797 if (target) | 7528 if (target) |
6798 return target; | 7529 return target; |
6799 break; | 7530 break; |
6862 target = expand_builtin_bzero (exp); | 7593 target = expand_builtin_bzero (exp); |
6863 if (target) | 7594 if (target) |
6864 return target; | 7595 return target; |
6865 break; | 7596 break; |
6866 | 7597 |
7598 /* Expand it as BUILT_IN_MEMCMP_EQ first. If not successful, change it | |
7599 back to a BUILT_IN_STRCMP. Remember to delete the 3rd paramater | |
7600 when changing it to a strcmp call. */ | |
7601 case BUILT_IN_STRCMP_EQ: | |
7602 target = expand_builtin_memcmp (exp, target, true); | |
7603 if (target) | |
7604 return target; | |
7605 | |
7606 /* Change this call back to a BUILT_IN_STRCMP. */ | |
7607 TREE_OPERAND (exp, 1) | |
7608 = build_fold_addr_expr (builtin_decl_explicit (BUILT_IN_STRCMP)); | |
7609 | |
7610 /* Delete the last parameter. */ | |
7611 unsigned int i; | |
7612 vec<tree, va_gc> *arg_vec; | |
7613 vec_alloc (arg_vec, 2); | |
7614 for (i = 0; i < 2; i++) | |
7615 arg_vec->quick_push (CALL_EXPR_ARG (exp, i)); | |
7616 exp = build_call_vec (TREE_TYPE (exp), CALL_EXPR_FN (exp), arg_vec); | |
7617 /* FALLTHROUGH */ | |
7618 | |
6867 case BUILT_IN_STRCMP: | 7619 case BUILT_IN_STRCMP: |
6868 target = expand_builtin_strcmp (exp, target); | 7620 target = expand_builtin_strcmp (exp, target); |
6869 if (target) | 7621 if (target) |
6870 return target; | 7622 return target; |
6871 break; | 7623 break; |
7624 | |
7625 /* Expand it as BUILT_IN_MEMCMP_EQ first. If not successful, change it | |
7626 back to a BUILT_IN_STRNCMP. */ | |
7627 case BUILT_IN_STRNCMP_EQ: | |
7628 target = expand_builtin_memcmp (exp, target, true); | |
7629 if (target) | |
7630 return target; | |
7631 | |
7632 /* Change it back to a BUILT_IN_STRNCMP. */ | |
7633 TREE_OPERAND (exp, 1) | |
7634 = build_fold_addr_expr (builtin_decl_explicit (BUILT_IN_STRNCMP)); | |
7635 /* FALLTHROUGH */ | |
6872 | 7636 |
6873 case BUILT_IN_STRNCMP: | 7637 case BUILT_IN_STRNCMP: |
6874 target = expand_builtin_strncmp (exp, target, mode); | 7638 target = expand_builtin_strncmp (exp, target, mode); |
6875 if (target) | 7639 if (target) |
6876 return target; | 7640 return target; |
7023 return expand_builtin_va_end (exp); | 7787 return expand_builtin_va_end (exp); |
7024 case BUILT_IN_VA_COPY: | 7788 case BUILT_IN_VA_COPY: |
7025 return expand_builtin_va_copy (exp); | 7789 return expand_builtin_va_copy (exp); |
7026 case BUILT_IN_EXPECT: | 7790 case BUILT_IN_EXPECT: |
7027 return expand_builtin_expect (exp, target); | 7791 return expand_builtin_expect (exp, target); |
7792 case BUILT_IN_EXPECT_WITH_PROBABILITY: | |
7793 return expand_builtin_expect_with_probability (exp, target); | |
7028 case BUILT_IN_ASSUME_ALIGNED: | 7794 case BUILT_IN_ASSUME_ALIGNED: |
7029 return expand_builtin_assume_aligned (exp, target); | 7795 return expand_builtin_assume_aligned (exp, target); |
7030 case BUILT_IN_PREFETCH: | 7796 case BUILT_IN_PREFETCH: |
7031 expand_builtin_prefetch (exp); | 7797 expand_builtin_prefetch (exp); |
7032 return const0_rtx; | 7798 return const0_rtx; |
7530 | 8296 |
7531 case BUILT_IN_SET_THREAD_POINTER: | 8297 case BUILT_IN_SET_THREAD_POINTER: |
7532 expand_builtin_set_thread_pointer (exp); | 8298 expand_builtin_set_thread_pointer (exp); |
7533 return const0_rtx; | 8299 return const0_rtx; |
7534 | 8300 |
7535 case BUILT_IN_CILK_DETACH: | |
7536 expand_builtin_cilk_detach (exp); | |
7537 return const0_rtx; | |
7538 | |
7539 case BUILT_IN_CILK_POP_FRAME: | |
7540 expand_builtin_cilk_pop_frame (exp); | |
7541 return const0_rtx; | |
7542 | |
7543 case BUILT_IN_CHKP_INIT_PTR_BOUNDS: | |
7544 case BUILT_IN_CHKP_NULL_PTR_BOUNDS: | |
7545 case BUILT_IN_CHKP_COPY_PTR_BOUNDS: | |
7546 case BUILT_IN_CHKP_CHECK_PTR_LBOUNDS: | |
7547 case BUILT_IN_CHKP_CHECK_PTR_UBOUNDS: | |
7548 case BUILT_IN_CHKP_CHECK_PTR_BOUNDS: | |
7549 case BUILT_IN_CHKP_SET_PTR_BOUNDS: | |
7550 case BUILT_IN_CHKP_NARROW_PTR_BOUNDS: | |
7551 case BUILT_IN_CHKP_STORE_PTR_BOUNDS: | |
7552 case BUILT_IN_CHKP_GET_PTR_LBOUND: | |
7553 case BUILT_IN_CHKP_GET_PTR_UBOUND: | |
7554 /* We allow user CHKP builtins if Pointer Bounds | |
7555 Checker is off. */ | |
7556 if (!chkp_function_instrumented_p (current_function_decl)) | |
7557 { | |
7558 if (fcode == BUILT_IN_CHKP_SET_PTR_BOUNDS | |
7559 || fcode == BUILT_IN_CHKP_NARROW_PTR_BOUNDS | |
7560 || fcode == BUILT_IN_CHKP_INIT_PTR_BOUNDS | |
7561 || fcode == BUILT_IN_CHKP_NULL_PTR_BOUNDS | |
7562 || fcode == BUILT_IN_CHKP_COPY_PTR_BOUNDS) | |
7563 return expand_normal (CALL_EXPR_ARG (exp, 0)); | |
7564 else if (fcode == BUILT_IN_CHKP_GET_PTR_LBOUND) | |
7565 return expand_normal (size_zero_node); | |
7566 else if (fcode == BUILT_IN_CHKP_GET_PTR_UBOUND) | |
7567 return expand_normal (size_int (-1)); | |
7568 else | |
7569 return const0_rtx; | |
7570 } | |
7571 /* FALLTHROUGH */ | |
7572 | |
7573 case BUILT_IN_CHKP_BNDMK: | |
7574 case BUILT_IN_CHKP_BNDSTX: | |
7575 case BUILT_IN_CHKP_BNDCL: | |
7576 case BUILT_IN_CHKP_BNDCU: | |
7577 case BUILT_IN_CHKP_BNDLDX: | |
7578 case BUILT_IN_CHKP_BNDRET: | |
7579 case BUILT_IN_CHKP_INTERSECT: | |
7580 case BUILT_IN_CHKP_NARROW: | |
7581 case BUILT_IN_CHKP_EXTRACT_LOWER: | |
7582 case BUILT_IN_CHKP_EXTRACT_UPPER: | |
7583 /* Software implementation of Pointer Bounds Checker is NYI. | |
7584 Target support is required. */ | |
7585 error ("Your target platform does not support -fcheck-pointer-bounds"); | |
7586 break; | |
7587 | |
7588 case BUILT_IN_ACC_ON_DEVICE: | 8301 case BUILT_IN_ACC_ON_DEVICE: |
7589 /* Do library call, if we failed to expand the builtin when | 8302 /* Do library call, if we failed to expand the builtin when |
7590 folding. */ | 8303 folding. */ |
7591 break; | 8304 break; |
7592 | 8305 |
8306 case BUILT_IN_GOACC_PARLEVEL_ID: | |
8307 case BUILT_IN_GOACC_PARLEVEL_SIZE: | |
8308 return expand_builtin_goacc_parlevel_id_size (exp, target, ignore); | |
8309 | |
8310 case BUILT_IN_SPECULATION_SAFE_VALUE_PTR: | |
8311 return expand_speculation_safe_value (VOIDmode, exp, target, ignore); | |
8312 | |
8313 case BUILT_IN_SPECULATION_SAFE_VALUE_1: | |
8314 case BUILT_IN_SPECULATION_SAFE_VALUE_2: | |
8315 case BUILT_IN_SPECULATION_SAFE_VALUE_4: | |
8316 case BUILT_IN_SPECULATION_SAFE_VALUE_8: | |
8317 case BUILT_IN_SPECULATION_SAFE_VALUE_16: | |
8318 mode = get_builtin_sync_mode (fcode - BUILT_IN_SPECULATION_SAFE_VALUE_1); | |
8319 return expand_speculation_safe_value (mode, exp, target, ignore); | |
8320 | |
7593 default: /* just do library call, if unknown builtin */ | 8321 default: /* just do library call, if unknown builtin */ |
7594 break; | 8322 break; |
7595 } | 8323 } |
7596 | 8324 |
7597 /* The switch statement above can drop through to cause the function | 8325 /* The switch statement above can drop through to cause the function |
7598 to be called normally. */ | 8326 to be called normally. */ |
7599 return expand_call (exp, target, ignore); | 8327 return expand_call (exp, target, ignore); |
7600 } | 8328 } |
7601 | |
7602 /* Similar to expand_builtin but is used for instrumented calls. */ | |
7603 | |
7604 rtx | |
7605 expand_builtin_with_bounds (tree exp, rtx target, | |
7606 rtx subtarget ATTRIBUTE_UNUSED, | |
7607 machine_mode mode, int ignore) | |
7608 { | |
7609 tree fndecl = get_callee_fndecl (exp); | |
7610 enum built_in_function fcode = DECL_FUNCTION_CODE (fndecl); | |
7611 | |
7612 gcc_assert (CALL_WITH_BOUNDS_P (exp)); | |
7613 | |
7614 if (DECL_BUILT_IN_CLASS (fndecl) == BUILT_IN_MD) | |
7615 return targetm.expand_builtin (exp, target, subtarget, mode, ignore); | |
7616 | |
7617 gcc_assert (fcode > BEGIN_CHKP_BUILTINS | |
7618 && fcode < END_CHKP_BUILTINS); | |
7619 | |
7620 switch (fcode) | |
7621 { | |
7622 case BUILT_IN_CHKP_MEMCPY_NOBND_NOCHK_CHKP: | |
7623 target = expand_builtin_memcpy_with_bounds (exp, target); | |
7624 if (target) | |
7625 return target; | |
7626 break; | |
7627 | |
7628 case BUILT_IN_CHKP_MEMPCPY_NOBND_NOCHK_CHKP: | |
7629 target = expand_builtin_mempcpy_with_bounds (exp, target); | |
7630 if (target) | |
7631 return target; | |
7632 break; | |
7633 | |
7634 case BUILT_IN_CHKP_MEMSET_NOBND_NOCHK_CHKP: | |
7635 target = expand_builtin_memset_with_bounds (exp, target, mode); | |
7636 if (target) | |
7637 return target; | |
7638 break; | |
7639 | |
7640 default: | |
7641 break; | |
7642 } | |
7643 | |
7644 /* The switch statement above can drop through to cause the function | |
7645 to be called normally. */ | |
7646 return expand_call (exp, target, ignore); | |
7647 } | |
7648 | 8329 |
7649 /* Determine whether a tree node represents a call to a built-in | 8330 /* Determine whether a tree node represents a call to a built-in |
7650 function. If the tree T is a call to a built-in function with | 8331 function. If the tree T is a call to a built-in function with |
7651 the right number of arguments of the appropriate types, return | 8332 the right number of arguments of the appropriate types, return |
7652 the DECL_FUNCTION_CODE of the call, e.g. BUILT_IN_SQRT. | 8333 the DECL_FUNCTION_CODE of the call, e.g. BUILT_IN_SQRT. |
7657 { | 8338 { |
7658 const_tree fndecl, arg, parmlist; | 8339 const_tree fndecl, arg, parmlist; |
7659 const_tree argtype, parmtype; | 8340 const_tree argtype, parmtype; |
7660 const_call_expr_arg_iterator iter; | 8341 const_call_expr_arg_iterator iter; |
7661 | 8342 |
7662 if (TREE_CODE (t) != CALL_EXPR | 8343 if (TREE_CODE (t) != CALL_EXPR) |
7663 || TREE_CODE (CALL_EXPR_FN (t)) != ADDR_EXPR) | |
7664 return END_BUILTINS; | 8344 return END_BUILTINS; |
7665 | 8345 |
7666 fndecl = get_callee_fndecl (t); | 8346 fndecl = get_callee_fndecl (t); |
7667 if (fndecl == NULL_TREE | 8347 if (fndecl == NULL_TREE || !fndecl_built_in_p (fndecl, BUILT_IN_NORMAL)) |
7668 || TREE_CODE (fndecl) != FUNCTION_DECL | 8348 return END_BUILTINS; |
7669 || ! DECL_BUILT_IN (fndecl) | |
7670 || DECL_BUILT_IN_CLASS (fndecl) == BUILT_IN_MD) | |
7671 return END_BUILTINS; | |
7672 | 8349 |
7673 parmlist = TYPE_ARG_TYPES (TREE_TYPE (fndecl)); | 8350 parmlist = TYPE_ARG_TYPES (TREE_TYPE (fndecl)); |
7674 init_const_call_expr_arg_iterator (t, &iter); | 8351 init_const_call_expr_arg_iterator (t, &iter); |
7675 for (; parmlist; parmlist = TREE_CHAIN (parmlist)) | 8352 for (; parmlist; parmlist = TREE_CHAIN (parmlist)) |
7676 { | 8353 { |
7760 return integer_zero_node; | 8437 return integer_zero_node; |
7761 | 8438 |
7762 return NULL_TREE; | 8439 return NULL_TREE; |
7763 } | 8440 } |
7764 | 8441 |
7765 /* Create builtin_expect with PRED and EXPECTED as its arguments and | 8442 /* Create builtin_expect or builtin_expect_with_probability |
7766 return it as a truthvalue. */ | 8443 with PRED and EXPECTED as its arguments and return it as a truthvalue. |
8444 Fortran FE can also produce builtin_expect with PREDICTOR as third argument. | |
8445 builtin_expect_with_probability instead uses third argument as PROBABILITY | |
8446 value. */ | |
7767 | 8447 |
7768 static tree | 8448 static tree |
7769 build_builtin_expect_predicate (location_t loc, tree pred, tree expected, | 8449 build_builtin_expect_predicate (location_t loc, tree pred, tree expected, |
7770 tree predictor) | 8450 tree predictor, tree probability) |
7771 { | 8451 { |
7772 tree fn, arg_types, pred_type, expected_type, call_expr, ret_type; | 8452 tree fn, arg_types, pred_type, expected_type, call_expr, ret_type; |
7773 | 8453 |
7774 fn = builtin_decl_explicit (BUILT_IN_EXPECT); | 8454 fn = builtin_decl_explicit (probability == NULL_TREE ? BUILT_IN_EXPECT |
8455 : BUILT_IN_EXPECT_WITH_PROBABILITY); | |
7775 arg_types = TYPE_ARG_TYPES (TREE_TYPE (fn)); | 8456 arg_types = TYPE_ARG_TYPES (TREE_TYPE (fn)); |
7776 ret_type = TREE_TYPE (TREE_TYPE (fn)); | 8457 ret_type = TREE_TYPE (TREE_TYPE (fn)); |
7777 pred_type = TREE_VALUE (arg_types); | 8458 pred_type = TREE_VALUE (arg_types); |
7778 expected_type = TREE_VALUE (TREE_CHAIN (arg_types)); | 8459 expected_type = TREE_VALUE (TREE_CHAIN (arg_types)); |
7779 | 8460 |
7780 pred = fold_convert_loc (loc, pred_type, pred); | 8461 pred = fold_convert_loc (loc, pred_type, pred); |
7781 expected = fold_convert_loc (loc, expected_type, expected); | 8462 expected = fold_convert_loc (loc, expected_type, expected); |
7782 call_expr = build_call_expr_loc (loc, fn, predictor ? 3 : 2, pred, expected, | 8463 |
7783 predictor); | 8464 if (probability) |
8465 call_expr = build_call_expr_loc (loc, fn, 3, pred, expected, probability); | |
8466 else | |
8467 call_expr = build_call_expr_loc (loc, fn, predictor ? 3 : 2, pred, expected, | |
8468 predictor); | |
7784 | 8469 |
7785 return build2 (NE_EXPR, TREE_TYPE (pred), call_expr, | 8470 return build2 (NE_EXPR, TREE_TYPE (pred), call_expr, |
7786 build_int_cst (ret_type, 0)); | 8471 build_int_cst (ret_type, 0)); |
7787 } | 8472 } |
7788 | 8473 |
7789 /* Fold a call to builtin_expect with arguments ARG0 and ARG1. Return | 8474 /* Fold a call to builtin_expect with arguments ARG0, ARG1, ARG2, ARG3. Return |
7790 NULL_TREE if no simplification is possible. */ | 8475 NULL_TREE if no simplification is possible. */ |
7791 | 8476 |
7792 tree | 8477 tree |
7793 fold_builtin_expect (location_t loc, tree arg0, tree arg1, tree arg2) | 8478 fold_builtin_expect (location_t loc, tree arg0, tree arg1, tree arg2, |
8479 tree arg3) | |
7794 { | 8480 { |
7795 tree inner, fndecl, inner_arg0; | 8481 tree inner, fndecl, inner_arg0; |
7796 enum tree_code code; | 8482 enum tree_code code; |
7797 | 8483 |
7798 /* Distribute the expected value over short-circuiting operators. | 8484 /* Distribute the expected value over short-circuiting operators. |
7812 && TREE_CODE (TREE_OPERAND (inner, 1)) == INTEGER_CST) | 8498 && TREE_CODE (TREE_OPERAND (inner, 1)) == INTEGER_CST) |
7813 inner = TREE_OPERAND (inner, 0); | 8499 inner = TREE_OPERAND (inner, 0); |
7814 | 8500 |
7815 if (TREE_CODE (inner) == CALL_EXPR | 8501 if (TREE_CODE (inner) == CALL_EXPR |
7816 && (fndecl = get_callee_fndecl (inner)) | 8502 && (fndecl = get_callee_fndecl (inner)) |
7817 && DECL_BUILT_IN_CLASS (fndecl) == BUILT_IN_NORMAL | 8503 && (fndecl_built_in_p (fndecl, BUILT_IN_EXPECT) |
7818 && DECL_FUNCTION_CODE (fndecl) == BUILT_IN_EXPECT) | 8504 || fndecl_built_in_p (fndecl, BUILT_IN_EXPECT_WITH_PROBABILITY))) |
7819 return arg0; | 8505 return arg0; |
7820 | 8506 |
7821 inner = inner_arg0; | 8507 inner = inner_arg0; |
7822 code = TREE_CODE (inner); | 8508 code = TREE_CODE (inner); |
7823 if (code == TRUTH_ANDIF_EXPR || code == TRUTH_ORIF_EXPR) | 8509 if (code == TRUTH_ANDIF_EXPR || code == TRUTH_ORIF_EXPR) |
7824 { | 8510 { |
7825 tree op0 = TREE_OPERAND (inner, 0); | 8511 tree op0 = TREE_OPERAND (inner, 0); |
7826 tree op1 = TREE_OPERAND (inner, 1); | 8512 tree op1 = TREE_OPERAND (inner, 1); |
7827 | 8513 arg1 = save_expr (arg1); |
7828 op0 = build_builtin_expect_predicate (loc, op0, arg1, arg2); | 8514 |
7829 op1 = build_builtin_expect_predicate (loc, op1, arg1, arg2); | 8515 op0 = build_builtin_expect_predicate (loc, op0, arg1, arg2, arg3); |
8516 op1 = build_builtin_expect_predicate (loc, op1, arg1, arg2, arg3); | |
7830 inner = build2 (code, TREE_TYPE (inner), op0, op1); | 8517 inner = build2 (code, TREE_TYPE (inner), op0, op1); |
7831 | 8518 |
7832 return fold_convert_loc (loc, TREE_TYPE (arg0), inner); | 8519 return fold_convert_loc (loc, TREE_TYPE (arg0), inner); |
7833 } | 8520 } |
7834 | 8521 |
7875 { | 8562 { |
7876 if (!validate_arg (arg, POINTER_TYPE)) | 8563 if (!validate_arg (arg, POINTER_TYPE)) |
7877 return NULL_TREE; | 8564 return NULL_TREE; |
7878 else | 8565 else |
7879 { | 8566 { |
7880 tree len = c_strlen (arg, 0); | 8567 c_strlen_data data; |
8568 memset (&data, 0, sizeof (c_strlen_data)); | |
8569 tree len = c_strlen (arg, 0, &data); | |
7881 | 8570 |
7882 if (len) | 8571 if (len) |
7883 return fold_convert_loc (loc, type, len); | 8572 return fold_convert_loc (loc, type, len); |
8573 | |
8574 if (!data.decl) | |
8575 c_strlen (arg, 1, &data); | |
8576 | |
8577 if (data.decl) | |
8578 { | |
8579 if (EXPR_HAS_LOCATION (arg)) | |
8580 loc = EXPR_LOCATION (arg); | |
8581 else if (loc == UNKNOWN_LOCATION) | |
8582 loc = input_location; | |
8583 warn_string_no_nul (loc, "strlen", arg, data.decl); | |
8584 } | |
7884 | 8585 |
7885 return NULL_TREE; | 8586 return NULL_TREE; |
7886 } | 8587 } |
7887 } | 8588 } |
7888 | 8589 |
7943 fndecl = builtin_decl_explicit (fn); | 8644 fndecl = builtin_decl_explicit (fn); |
7944 call = build_call_expr_loc (loc, fndecl, 1, arg0); | 8645 call = build_call_expr_loc (loc, fndecl, 1, arg0); |
7945 call = builtin_save_expr (call); | 8646 call = builtin_save_expr (call); |
7946 } | 8647 } |
7947 | 8648 |
8649 tree ptype = build_pointer_type (type); | |
8650 arg1 = fold_convert (ptype, arg1); | |
8651 arg2 = fold_convert (ptype, arg2); | |
7948 return build2 (COMPOUND_EXPR, void_type_node, | 8652 return build2 (COMPOUND_EXPR, void_type_node, |
7949 build2 (MODIFY_EXPR, void_type_node, | 8653 build2 (MODIFY_EXPR, void_type_node, |
7950 build_fold_indirect_ref_loc (loc, arg1), | 8654 build_fold_indirect_ref_loc (loc, arg1), |
7951 fold_build1_loc (loc, IMAGPART_EXPR, type, call)), | 8655 fold_build1_loc (loc, IMAGPART_EXPR, type, call)), |
7952 build2 (MODIFY_EXPR, void_type_node, | 8656 build2 (MODIFY_EXPR, void_type_node, |
8077 if (!validate_arg (arg, INTEGER_TYPE)) | 8781 if (!validate_arg (arg, INTEGER_TYPE)) |
8078 return NULL_TREE; | 8782 return NULL_TREE; |
8079 | 8783 |
8080 arg = fold_convert_loc (loc, type, arg); | 8784 arg = fold_convert_loc (loc, type, arg); |
8081 return fold_build1_loc (loc, ABS_EXPR, type, arg); | 8785 return fold_build1_loc (loc, ABS_EXPR, type, arg); |
8082 } | |
8083 | |
8084 /* Fold a call to fma, fmaf, or fmal with arguments ARG[012]. */ | |
8085 | |
8086 static tree | |
8087 fold_builtin_fma (location_t loc, tree arg0, tree arg1, tree arg2, tree type) | |
8088 { | |
8089 /* ??? Only expand to FMA_EXPR if it's directly supported. */ | |
8090 if (validate_arg (arg0, REAL_TYPE) | |
8091 && validate_arg (arg1, REAL_TYPE) | |
8092 && validate_arg (arg2, REAL_TYPE) | |
8093 && optab_handler (fma_optab, TYPE_MODE (type)) != CODE_FOR_nothing) | |
8094 return fold_build3_loc (loc, FMA_EXPR, type, arg0, arg1, arg2); | |
8095 | |
8096 return NULL_TREE; | |
8097 } | 8786 } |
8098 | 8787 |
8099 /* Fold a call to builtin carg(a+bi) -> atan2(b,a). */ | 8788 /* Fold a call to builtin carg(a+bi) -> atan2(b,a). */ |
8100 | 8789 |
8101 static tree | 8790 static tree |
8693 | 9382 |
8694 static inline tree | 9383 static inline tree |
8695 fold_builtin_FILE (location_t loc) | 9384 fold_builtin_FILE (location_t loc) |
8696 { | 9385 { |
8697 if (const char *fname = LOCATION_FILE (loc)) | 9386 if (const char *fname = LOCATION_FILE (loc)) |
9387 { | |
9388 /* The documentation says this builtin is equivalent to the preprocessor | |
9389 __FILE__ macro so it appears appropriate to use the same file prefix | |
9390 mappings. */ | |
9391 fname = remap_macro_filename (fname); | |
8698 return build_string_literal (strlen (fname) + 1, fname); | 9392 return build_string_literal (strlen (fname) + 1, fname); |
9393 } | |
8699 | 9394 |
8700 return build_string_literal (1, ""); | 9395 return build_string_literal (1, ""); |
8701 } | 9396 } |
8702 | 9397 |
8703 /* Fold a call to __builtin_FUNCTION to a constant string. */ | 9398 /* Fold a call to __builtin_FUNCTION to a constant string. */ |
8926 | 9621 |
8927 case BUILT_IN_STRPBRK: | 9622 case BUILT_IN_STRPBRK: |
8928 return fold_builtin_strpbrk (loc, arg0, arg1, type); | 9623 return fold_builtin_strpbrk (loc, arg0, arg1, type); |
8929 | 9624 |
8930 case BUILT_IN_EXPECT: | 9625 case BUILT_IN_EXPECT: |
8931 return fold_builtin_expect (loc, arg0, arg1, NULL_TREE); | 9626 return fold_builtin_expect (loc, arg0, arg1, NULL_TREE, NULL_TREE); |
8932 | 9627 |
8933 case BUILT_IN_ISGREATER: | 9628 case BUILT_IN_ISGREATER: |
8934 return fold_builtin_unordered_cmp (loc, fndecl, | 9629 return fold_builtin_unordered_cmp (loc, fndecl, |
8935 arg0, arg1, UNLE_EXPR, LE_EXPR); | 9630 arg0, arg1, UNLE_EXPR, LE_EXPR); |
8936 case BUILT_IN_ISGREATEREQUAL: | 9631 case BUILT_IN_ISGREATEREQUAL: |
8993 { | 9688 { |
8994 | 9689 |
8995 CASE_FLT_FN (BUILT_IN_SINCOS): | 9690 CASE_FLT_FN (BUILT_IN_SINCOS): |
8996 return fold_builtin_sincos (loc, arg0, arg1, arg2); | 9691 return fold_builtin_sincos (loc, arg0, arg1, arg2); |
8997 | 9692 |
8998 CASE_FLT_FN (BUILT_IN_FMA): | |
8999 return fold_builtin_fma (loc, arg0, arg1, arg2, type); | |
9000 | |
9001 CASE_FLT_FN (BUILT_IN_REMQUO): | 9693 CASE_FLT_FN (BUILT_IN_REMQUO): |
9002 if (validate_arg (arg0, REAL_TYPE) | 9694 if (validate_arg (arg0, REAL_TYPE) |
9003 && validate_arg (arg1, REAL_TYPE) | 9695 && validate_arg (arg1, REAL_TYPE) |
9004 && validate_arg (arg2, POINTER_TYPE)) | 9696 && validate_arg (arg2, POINTER_TYPE)) |
9005 return do_mpfr_remquo (arg0, arg1, arg2); | 9697 return do_mpfr_remquo (arg0, arg1, arg2); |
9006 break; | 9698 break; |
9007 | 9699 |
9008 case BUILT_IN_MEMCMP: | 9700 case BUILT_IN_MEMCMP: |
9009 return fold_builtin_memcmp (loc, arg0, arg1, arg2);; | 9701 return fold_builtin_memcmp (loc, arg0, arg1, arg2); |
9010 | 9702 |
9011 case BUILT_IN_EXPECT: | 9703 case BUILT_IN_EXPECT: |
9012 return fold_builtin_expect (loc, arg0, arg1, arg2); | 9704 return fold_builtin_expect (loc, arg0, arg1, arg2, NULL_TREE); |
9705 | |
9706 case BUILT_IN_EXPECT_WITH_PROBABILITY: | |
9707 return fold_builtin_expect (loc, arg0, arg1, NULL_TREE, arg2); | |
9013 | 9708 |
9014 case BUILT_IN_ADD_OVERFLOW: | 9709 case BUILT_IN_ADD_OVERFLOW: |
9015 case BUILT_IN_SUB_OVERFLOW: | 9710 case BUILT_IN_SUB_OVERFLOW: |
9016 case BUILT_IN_MUL_OVERFLOW: | 9711 case BUILT_IN_MUL_OVERFLOW: |
9017 case BUILT_IN_ADD_OVERFLOW_P: | 9712 case BUILT_IN_ADD_OVERFLOW_P: |
9073 } | 9768 } |
9074 if (ret) | 9769 if (ret) |
9075 { | 9770 { |
9076 ret = build1 (NOP_EXPR, TREE_TYPE (ret), ret); | 9771 ret = build1 (NOP_EXPR, TREE_TYPE (ret), ret); |
9077 SET_EXPR_LOCATION (ret, loc); | 9772 SET_EXPR_LOCATION (ret, loc); |
9078 TREE_NO_WARNING (ret) = 1; | |
9079 return ret; | 9773 return ret; |
9080 } | 9774 } |
9081 return NULL_TREE; | 9775 return NULL_TREE; |
9082 } | 9776 } |
9083 | 9777 |
9132 tree | 9826 tree |
9133 fold_call_expr (location_t loc, tree exp, bool ignore) | 9827 fold_call_expr (location_t loc, tree exp, bool ignore) |
9134 { | 9828 { |
9135 tree ret = NULL_TREE; | 9829 tree ret = NULL_TREE; |
9136 tree fndecl = get_callee_fndecl (exp); | 9830 tree fndecl = get_callee_fndecl (exp); |
9137 if (fndecl | 9831 if (fndecl && fndecl_built_in_p (fndecl) |
9138 && TREE_CODE (fndecl) == FUNCTION_DECL | |
9139 && DECL_BUILT_IN (fndecl) | |
9140 /* If CALL_EXPR_VA_ARG_PACK is set, the arguments aren't finalized | 9832 /* If CALL_EXPR_VA_ARG_PACK is set, the arguments aren't finalized |
9141 yet. Defer folding until we see all the arguments | 9833 yet. Defer folding until we see all the arguments |
9142 (after inlining). */ | 9834 (after inlining). */ |
9143 && !CALL_EXPR_VA_ARG_PACK (exp)) | 9835 && !CALL_EXPR_VA_ARG_PACK (exp)) |
9144 { | 9836 { |
9148 instead last argument is __builtin_va_arg_pack (). Defer folding | 9840 instead last argument is __builtin_va_arg_pack (). Defer folding |
9149 even in that case, until arguments are finalized. */ | 9841 even in that case, until arguments are finalized. */ |
9150 if (nargs && TREE_CODE (CALL_EXPR_ARG (exp, nargs - 1)) == CALL_EXPR) | 9842 if (nargs && TREE_CODE (CALL_EXPR_ARG (exp, nargs - 1)) == CALL_EXPR) |
9151 { | 9843 { |
9152 tree fndecl2 = get_callee_fndecl (CALL_EXPR_ARG (exp, nargs - 1)); | 9844 tree fndecl2 = get_callee_fndecl (CALL_EXPR_ARG (exp, nargs - 1)); |
9153 if (fndecl2 | 9845 if (fndecl2 && fndecl_built_in_p (fndecl2, BUILT_IN_VA_ARG_PACK)) |
9154 && TREE_CODE (fndecl2) == FUNCTION_DECL | |
9155 && DECL_BUILT_IN_CLASS (fndecl2) == BUILT_IN_NORMAL | |
9156 && DECL_FUNCTION_CODE (fndecl2) == BUILT_IN_VA_ARG_PACK) | |
9157 return NULL_TREE; | 9846 return NULL_TREE; |
9158 } | 9847 } |
9159 | 9848 |
9160 if (avoid_folding_inline_builtin (fndecl)) | 9849 if (avoid_folding_inline_builtin (fndecl)) |
9161 return NULL_TREE; | 9850 return NULL_TREE; |
9187 if (TREE_CODE (fn) != ADDR_EXPR) | 9876 if (TREE_CODE (fn) != ADDR_EXPR) |
9188 return NULL_TREE; | 9877 return NULL_TREE; |
9189 | 9878 |
9190 tree fndecl = TREE_OPERAND (fn, 0); | 9879 tree fndecl = TREE_OPERAND (fn, 0); |
9191 if (TREE_CODE (fndecl) == FUNCTION_DECL | 9880 if (TREE_CODE (fndecl) == FUNCTION_DECL |
9192 && DECL_BUILT_IN (fndecl)) | 9881 && fndecl_built_in_p (fndecl)) |
9193 { | 9882 { |
9194 /* If last argument is __builtin_va_arg_pack (), arguments to this | 9883 /* If last argument is __builtin_va_arg_pack (), arguments to this |
9195 function are not finalized yet. Defer folding until they are. */ | 9884 function are not finalized yet. Defer folding until they are. */ |
9196 if (n && TREE_CODE (argarray[n - 1]) == CALL_EXPR) | 9885 if (n && TREE_CODE (argarray[n - 1]) == CALL_EXPR) |
9197 { | 9886 { |
9198 tree fndecl2 = get_callee_fndecl (argarray[n - 1]); | 9887 tree fndecl2 = get_callee_fndecl (argarray[n - 1]); |
9199 if (fndecl2 | 9888 if (fndecl2 && fndecl_built_in_p (fndecl2, BUILT_IN_VA_ARG_PACK)) |
9200 && TREE_CODE (fndecl2) == FUNCTION_DECL | |
9201 && DECL_BUILT_IN_CLASS (fndecl2) == BUILT_IN_NORMAL | |
9202 && DECL_FUNCTION_CODE (fndecl2) == BUILT_IN_VA_ARG_PACK) | |
9203 return NULL_TREE; | 9889 return NULL_TREE; |
9204 } | 9890 } |
9205 if (avoid_folding_inline_builtin (fndecl)) | 9891 if (avoid_folding_inline_builtin (fndecl)) |
9206 return NULL_TREE; | 9892 return NULL_TREE; |
9207 if (DECL_BUILT_IN_CLASS (fndecl) == BUILT_IN_MD) | 9893 if (DECL_BUILT_IN_CLASS (fndecl) == BUILT_IN_MD) |
9388 } | 10074 } |
9389 | 10075 |
9390 if (p2[0] == '\0') | 10076 if (p2[0] == '\0') |
9391 /* strpbrk(x, "") == NULL. | 10077 /* strpbrk(x, "") == NULL. |
9392 Evaluate and ignore s1 in case it had side-effects. */ | 10078 Evaluate and ignore s1 in case it had side-effects. */ |
9393 return omit_one_operand_loc (loc, TREE_TYPE (s1), integer_zero_node, s1); | 10079 return omit_one_operand_loc (loc, type, integer_zero_node, s1); |
9394 | 10080 |
9395 if (p2[1] != '\0') | 10081 if (p2[1] != '\0') |
9396 return NULL_TREE; /* Really call strpbrk. */ | 10082 return NULL_TREE; /* Really call strpbrk. */ |
9397 | 10083 |
9398 fn = builtin_decl_implicit (BUILT_IN_STRCHR); | 10084 fn = builtin_decl_implicit (BUILT_IN_STRCHR); |
9651 | 10337 |
9652 static rtx | 10338 static rtx |
9653 expand_builtin_memory_chk (tree exp, rtx target, machine_mode mode, | 10339 expand_builtin_memory_chk (tree exp, rtx target, machine_mode mode, |
9654 enum built_in_function fcode) | 10340 enum built_in_function fcode) |
9655 { | 10341 { |
9656 tree dest, src, len, size; | |
9657 | |
9658 if (!validate_arglist (exp, | 10342 if (!validate_arglist (exp, |
9659 POINTER_TYPE, | 10343 POINTER_TYPE, |
9660 fcode == BUILT_IN_MEMSET_CHK | 10344 fcode == BUILT_IN_MEMSET_CHK |
9661 ? INTEGER_TYPE : POINTER_TYPE, | 10345 ? INTEGER_TYPE : POINTER_TYPE, |
9662 INTEGER_TYPE, INTEGER_TYPE, VOID_TYPE)) | 10346 INTEGER_TYPE, INTEGER_TYPE, VOID_TYPE)) |
9663 return NULL_RTX; | 10347 return NULL_RTX; |
9664 | 10348 |
9665 dest = CALL_EXPR_ARG (exp, 0); | 10349 tree dest = CALL_EXPR_ARG (exp, 0); |
9666 src = CALL_EXPR_ARG (exp, 1); | 10350 tree src = CALL_EXPR_ARG (exp, 1); |
9667 len = CALL_EXPR_ARG (exp, 2); | 10351 tree len = CALL_EXPR_ARG (exp, 2); |
9668 size = CALL_EXPR_ARG (exp, 3); | 10352 tree size = CALL_EXPR_ARG (exp, 3); |
9669 | 10353 |
9670 bool sizes_ok = check_sizes (OPT_Wstringop_overflow_, | 10354 bool sizes_ok = check_access (exp, dest, src, len, /*maxread=*/NULL_TREE, |
9671 exp, len, /*maxlen=*/NULL_TREE, | 10355 /*str=*/NULL_TREE, size); |
9672 /*str=*/NULL_TREE, size); | |
9673 | 10356 |
9674 if (!tree_fits_uhwi_p (size)) | 10357 if (!tree_fits_uhwi_p (size)) |
9675 return NULL_RTX; | 10358 return NULL_RTX; |
9676 | 10359 |
9677 if (tree_fits_uhwi_p (len) || integer_all_onesp (size)) | 10360 if (tree_fits_uhwi_p (len) || integer_all_onesp (size)) |
9776 or null if it isn't. */ | 10459 or null if it isn't. */ |
9777 tree catstr = NULL_TREE; | 10460 tree catstr = NULL_TREE; |
9778 /* The maximum length of the source sequence in a bounded operation | 10461 /* The maximum length of the source sequence in a bounded operation |
9779 (such as __strncat_chk) or null if the operation isn't bounded | 10462 (such as __strncat_chk) or null if the operation isn't bounded |
9780 (such as __strcat_chk). */ | 10463 (such as __strcat_chk). */ |
9781 tree maxlen = NULL_TREE; | 10464 tree maxread = NULL_TREE; |
10465 /* The exact size of the access (such as in __strncpy_chk). */ | |
10466 tree size = NULL_TREE; | |
9782 | 10467 |
9783 switch (fcode) | 10468 switch (fcode) |
9784 { | 10469 { |
9785 case BUILT_IN_STRCPY_CHK: | 10470 case BUILT_IN_STRCPY_CHK: |
9786 case BUILT_IN_STPCPY_CHK: | 10471 case BUILT_IN_STPCPY_CHK: |
9797 break; | 10482 break; |
9798 | 10483 |
9799 case BUILT_IN_STRNCAT_CHK: | 10484 case BUILT_IN_STRNCAT_CHK: |
9800 catstr = CALL_EXPR_ARG (exp, 0); | 10485 catstr = CALL_EXPR_ARG (exp, 0); |
9801 srcstr = CALL_EXPR_ARG (exp, 1); | 10486 srcstr = CALL_EXPR_ARG (exp, 1); |
9802 maxlen = CALL_EXPR_ARG (exp, 2); | 10487 maxread = CALL_EXPR_ARG (exp, 2); |
9803 objsize = CALL_EXPR_ARG (exp, 3); | 10488 objsize = CALL_EXPR_ARG (exp, 3); |
9804 break; | 10489 break; |
9805 | 10490 |
9806 case BUILT_IN_STRNCPY_CHK: | 10491 case BUILT_IN_STRNCPY_CHK: |
9807 case BUILT_IN_STPNCPY_CHK: | 10492 case BUILT_IN_STPNCPY_CHK: |
9808 srcstr = CALL_EXPR_ARG (exp, 1); | 10493 srcstr = CALL_EXPR_ARG (exp, 1); |
9809 maxlen = CALL_EXPR_ARG (exp, 2); | 10494 size = CALL_EXPR_ARG (exp, 2); |
9810 objsize = CALL_EXPR_ARG (exp, 3); | 10495 objsize = CALL_EXPR_ARG (exp, 3); |
9811 break; | 10496 break; |
9812 | 10497 |
9813 case BUILT_IN_SNPRINTF_CHK: | 10498 case BUILT_IN_SNPRINTF_CHK: |
9814 case BUILT_IN_VSNPRINTF_CHK: | 10499 case BUILT_IN_VSNPRINTF_CHK: |
9815 maxlen = CALL_EXPR_ARG (exp, 1); | 10500 maxread = CALL_EXPR_ARG (exp, 1); |
9816 objsize = CALL_EXPR_ARG (exp, 3); | 10501 objsize = CALL_EXPR_ARG (exp, 3); |
9817 break; | 10502 break; |
9818 default: | 10503 default: |
9819 gcc_unreachable (); | 10504 gcc_unreachable (); |
9820 } | 10505 } |
9821 | 10506 |
9822 if (catstr && maxlen) | 10507 if (catstr && maxread) |
9823 { | 10508 { |
9824 /* Check __strncat_chk. There is no way to determine the length | 10509 /* Check __strncat_chk. There is no way to determine the length |
9825 of the string to which the source string is being appended so | 10510 of the string to which the source string is being appended so |
9826 just warn when the length of the source string is not known. */ | 10511 just warn when the length of the source string is not known. */ |
9827 check_strncat_sizes (exp, objsize); | 10512 check_strncat_sizes (exp, objsize); |
9828 return; | 10513 return; |
9829 } | 10514 } |
9830 | 10515 |
9831 check_sizes (OPT_Wstringop_overflow_, exp, | 10516 /* The destination argument is the first one for all built-ins above. */ |
9832 /*size=*/NULL_TREE, maxlen, srcstr, objsize); | 10517 tree dst = CALL_EXPR_ARG (exp, 0); |
10518 | |
10519 check_access (exp, dst, srcstr, size, maxread, srcstr, objsize); | |
9833 } | 10520 } |
9834 | 10521 |
9835 /* Emit warning if a buffer overflow is detected at compile time | 10522 /* Emit warning if a buffer overflow is detected at compile time |
9836 in __sprintf_chk/__vsprintf_chk calls. */ | 10523 in __sprintf_chk/__vsprintf_chk calls. */ |
9837 | 10524 |
9883 else | 10570 else |
9884 return; | 10571 return; |
9885 | 10572 |
9886 /* Add one for the terminating nul. */ | 10573 /* Add one for the terminating nul. */ |
9887 len = fold_build2 (PLUS_EXPR, TREE_TYPE (len), len, size_one_node); | 10574 len = fold_build2 (PLUS_EXPR, TREE_TYPE (len), len, size_one_node); |
9888 check_sizes (OPT_Wstringop_overflow_, | 10575 |
9889 exp, /*size=*/NULL_TREE, /*maxlen=*/NULL_TREE, len, size); | 10576 check_access (exp, /*dst=*/NULL_TREE, /*src=*/NULL_TREE, /*size=*/NULL_TREE, |
10577 /*maxread=*/NULL_TREE, len, size); | |
9890 } | 10578 } |
9891 | 10579 |
9892 /* Emit warning if a free is called with address of a variable. */ | 10580 /* Emit warning if a free is called with address of a variable. */ |
9893 | 10581 |
9894 static void | 10582 static void |
10314 fold_call_stmt (gcall *stmt, bool ignore) | 11002 fold_call_stmt (gcall *stmt, bool ignore) |
10315 { | 11003 { |
10316 tree ret = NULL_TREE; | 11004 tree ret = NULL_TREE; |
10317 tree fndecl = gimple_call_fndecl (stmt); | 11005 tree fndecl = gimple_call_fndecl (stmt); |
10318 location_t loc = gimple_location (stmt); | 11006 location_t loc = gimple_location (stmt); |
10319 if (fndecl | 11007 if (fndecl && fndecl_built_in_p (fndecl) |
10320 && TREE_CODE (fndecl) == FUNCTION_DECL | |
10321 && DECL_BUILT_IN (fndecl) | |
10322 && !gimple_call_va_arg_pack_p (stmt)) | 11008 && !gimple_call_va_arg_pack_p (stmt)) |
10323 { | 11009 { |
10324 int nargs = gimple_call_num_args (stmt); | 11010 int nargs = gimple_call_num_args (stmt); |
10325 tree *args = (nargs > 0 | 11011 tree *args = (nargs > 0 |
10326 ? gimple_call_arg_ptr (stmt, 0) | 11012 ? gimple_call_arg_ptr (stmt, 0) |
10363 function decl that declares a builtin. */ | 11049 function decl that declares a builtin. */ |
10364 | 11050 |
10365 void | 11051 void |
10366 set_builtin_user_assembler_name (tree decl, const char *asmspec) | 11052 set_builtin_user_assembler_name (tree decl, const char *asmspec) |
10367 { | 11053 { |
10368 gcc_assert (TREE_CODE (decl) == FUNCTION_DECL | 11054 gcc_assert (fndecl_built_in_p (decl, BUILT_IN_NORMAL) |
10369 && DECL_BUILT_IN_CLASS (decl) == BUILT_IN_NORMAL | |
10370 && asmspec != 0); | 11055 && asmspec != 0); |
10371 | 11056 |
10372 tree builtin = builtin_decl_explicit (DECL_FUNCTION_CODE (decl)); | 11057 tree builtin = builtin_decl_explicit (DECL_FUNCTION_CODE (decl)); |
10373 set_user_assembler_name (builtin, asmspec); | 11058 set_user_assembler_name (builtin, asmspec); |
10374 | 11059 |
10384 /* Return true if DECL is a builtin that expands to a constant or similarly | 11069 /* Return true if DECL is a builtin that expands to a constant or similarly |
10385 simple code. */ | 11070 simple code. */ |
10386 bool | 11071 bool |
10387 is_simple_builtin (tree decl) | 11072 is_simple_builtin (tree decl) |
10388 { | 11073 { |
10389 if (decl && DECL_BUILT_IN_CLASS (decl) == BUILT_IN_NORMAL) | 11074 if (decl && fndecl_built_in_p (decl, BUILT_IN_NORMAL)) |
10390 switch (DECL_FUNCTION_CODE (decl)) | 11075 switch (DECL_FUNCTION_CODE (decl)) |
10391 { | 11076 { |
10392 /* Builtins that expand to constants. */ | 11077 /* Builtins that expand to constants. */ |
10393 case BUILT_IN_CONSTANT_P: | 11078 case BUILT_IN_CONSTANT_P: |
10394 case BUILT_IN_EXPECT: | 11079 case BUILT_IN_EXPECT: |
10514 return false; | 11199 return false; |
10515 | 11200 |
10516 *p = (char)tree_to_uhwi (t); | 11201 *p = (char)tree_to_uhwi (t); |
10517 return true; | 11202 return true; |
10518 } | 11203 } |
11204 | |
11205 /* Return the maximum object size. */ | |
11206 | |
11207 tree | |
11208 max_object_size (void) | |
11209 { | |
11210 /* To do: Make this a configurable parameter. */ | |
11211 return TYPE_MAX_VALUE (ptrdiff_type_node); | |
11212 } |