re PR middle-end/87854 (gcc.c-torture/compile/pr46534.c ICE for 16-bit size_t)
authorJakub Jelinek <jakub@redhat.com>
Fri, 16 Nov 2018 16:41:54 +0000 (17:41 +0100)
committerJakub Jelinek <jakub@gcc.gnu.org>
Fri, 16 Nov 2018 16:41:54 +0000 (17:41 +0100)
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
gcc/c-family/c-common.c

index 057009b9d42406793e24cd4aa96dd1410523c8db..ed700f8decac7e5b1c4b4816d8b2f733794d3f5a 100644 (file)
@@ -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
index 69be3d3b2a0d002277be9426a7ae6c9be2631b55..4034b64bbe2a5f6410863274b291cf172dcf3c94 100644 (file)
@@ -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