diff options
author | Jakub Jelinek <jakub@redhat.com> | 2018-11-16 17:41:54 +0100 |
---|---|---|
committer | Jakub Jelinek <jakub@gcc.gnu.org> | 2018-11-16 17:41:54 +0100 |
commit | 258b3854633d78954f9f9aba5cc433c992a5010e (patch) | |
tree | f908eaeb33bb5702b4ae09cf8c2f344702a08fc0 | |
parent | 7f46559c8282d7e6e9b2b8d67cd390b7775ce1bc (diff) | |
download | gcc-258b3854633d78954f9f9aba5cc433c992a5010e.zip gcc-258b3854633d78954f9f9aba5cc433c992a5010e.tar.gz gcc-258b3854633d78954f9f9aba5cc433c992a5010e.tar.bz2 |
re PR middle-end/87854 (gcc.c-torture/compile/pr46534.c ICE for 16-bit size_t)
PR middle-end/87854
* c-common.c (fix_string_type): Reject string literals larger than
TYPE_MAX_VALUE (ssizetype) bytes.
From-SVN: r266217
-rw-r--r-- | gcc/c-family/ChangeLog | 6 | ||||
-rw-r--r-- | gcc/c-family/c-common.c | 23 |
2 files changed, 24 insertions, 5 deletions
diff --git a/gcc/c-family/ChangeLog b/gcc/c-family/ChangeLog index 057009b..ed700f8 100644 --- a/gcc/c-family/ChangeLog +++ b/gcc/c-family/ChangeLog @@ -1,3 +1,9 @@ +2018-11-16 Jakub Jelinek <jakub@redhat.com> + + PR middle-end/87854 + * c-common.c (fix_string_type): Reject string literals larger than + TYPE_MAX_VALUE (ssizetype) bytes. + 2018-11-15 Martin Sebor <msebor@redhat.com> PR c++/87541 diff --git a/gcc/c-family/c-common.c b/gcc/c-family/c-common.c index 69be3d3..4034b64 100644 --- a/gcc/c-family/c-common.c +++ b/gcc/c-family/c-common.c @@ -737,31 +737,44 @@ tree fix_string_type (tree value) { int length = TREE_STRING_LENGTH (value); - int nchars; + int nchars, charsz; tree e_type, i_type, a_type; /* Compute the number of elements, for the array type. */ if (TREE_TYPE (value) == char_array_type_node || !TREE_TYPE (value)) { - nchars = length; + charsz = 1; e_type = char_type_node; } else if (TREE_TYPE (value) == char16_array_type_node) { - nchars = length / (TYPE_PRECISION (char16_type_node) / BITS_PER_UNIT); + charsz = TYPE_PRECISION (char16_type_node) / BITS_PER_UNIT; e_type = char16_type_node; } else if (TREE_TYPE (value) == char32_array_type_node) { - nchars = length / (TYPE_PRECISION (char32_type_node) / BITS_PER_UNIT); + charsz = TYPE_PRECISION (char32_type_node) / BITS_PER_UNIT; e_type = char32_type_node; } else { - nchars = length / (TYPE_PRECISION (wchar_type_node) / BITS_PER_UNIT); + charsz = TYPE_PRECISION (wchar_type_node) / BITS_PER_UNIT; e_type = wchar_type_node; } + /* This matters only for targets where ssizetype has smaller precision + than 32 bits. */ + if (wi::lts_p (wi::to_wide (TYPE_MAX_VALUE (ssizetype)), length)) + { + error ("size of string literal is too large"); + length = tree_to_shwi (TYPE_MAX_VALUE (ssizetype)) / charsz * charsz; + char *str = CONST_CAST (char *, TREE_STRING_POINTER (value)); + memset (str + length, '\0', + MIN (TREE_STRING_LENGTH (value) - length, charsz)); + TREE_STRING_LENGTH (value) = length; + } + nchars = length / charsz; + /* C89 2.2.4.1, C99 5.2.4.1 (Translation limits). The analogous limit in C++98 Annex B is very large (65536) and is not normative, so we do not diagnose it (warn_overlength_strings is forced off |