aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJakub Jelinek <jakub@redhat.com>2018-11-16 17:41:54 +0100
committerJakub Jelinek <jakub@gcc.gnu.org>2018-11-16 17:41:54 +0100
commit258b3854633d78954f9f9aba5cc433c992a5010e (patch)
treef908eaeb33bb5702b4ae09cf8c2f344702a08fc0
parent7f46559c8282d7e6e9b2b8d67cd390b7775ce1bc (diff)
downloadgcc-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/ChangeLog6
-rw-r--r--gcc/c-family/c-common.c23
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