[PATCH] Reject too large string literals (PR middle-end/87854)
Jakub Jelinek
jakub@redhat.com
Fri Nov 16 08:43:00 GMT 2018
Hi!
Both C and C++ FE diagnose arrays larger than half of the address space:
/tmp/1.c:1:6: error: size of array âaâ is too large
char a[__SIZE_MAX__ / 2 + 1];
^
because one can't do pointer arithmetics on them. But we don't have
anything similar for string literals. As internally we use host int
as TREE_STRING_LENGTH, this is relevant to targets that have < 32-bit
size_t only.
The following patch adds that diagnostics and truncates the string literals.
Bootstrapped/regtested on x86_64-linux and i686-linux and tested with
a cross to avr. I'll defer adjusting testcases to the maintainers of 16-bit
ports. From the PR it seems gcc.dg/concat2.c, g++.dg/parse/concat1.C and
pr46534.c tests are affected.
Ok for trunk?
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.
--- gcc/c-family/c-common.c.jj 2018-11-14 13:37:46.921050615 +0100
+++ gcc/c-family/c-common.c 2018-11-15 15:20:31.138056115 +0100
@@ -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
Jakub
More information about the Gcc-patches
mailing list