From 258b3854633d78954f9f9aba5cc433c992a5010e Mon Sep 17 00:00:00 2001 From: Jakub Jelinek Date: Fri, 16 Nov 2018 17:41:54 +0100 Subject: [PATCH] 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 --- gcc/c-family/ChangeLog | 6 ++++++ 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 057009b9d42..ed700f8deca 100644 --- a/gcc/c-family/ChangeLog +++ b/gcc/c-family/ChangeLog @@ -1,3 +1,9 @@ +2018-11-16 Jakub Jelinek + + 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 PR c++/87541 diff --git a/gcc/c-family/c-common.c b/gcc/c-family/c-common.c index 69be3d3b2a0..4034b64bbe2 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 -- 2.30.2