aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
authorBernd Edlinger <bernd.edlinger@hotmail.de>2018-09-13 21:43:16 +0000
committerJeff Law <law@gcc.gnu.org>2018-09-13 15:43:16 -0600
commit5ec9f8cff333bbe9ef6b3767bfcc334961927a03 (patch)
tree0bc6a7c631c48975d524bc8e12bae897b2bae1e9 /gcc
parent4a426e366eccf4a8806175a18be5a13da66e0983 (diff)
downloadgcc-5ec9f8cff333bbe9ef6b3767bfcc334961927a03.zip
gcc-5ec9f8cff333bbe9ef6b3767bfcc334961927a03.tar.gz
gcc-5ec9f8cff333bbe9ef6b3767bfcc334961927a03.tar.bz2
varasm.c (compare_constant): Compare type size of STRING_CSTs.
* varasm.c (compare_constant): Compare type size of STRING_CSTs. (get_constant_size): Don't make STRING_CSTs larger than they are. (check_string_literal): New check function for STRING_CSTs. (output_constant): Use it. From-SVN: r264292
Diffstat (limited to 'gcc')
-rw-r--r--gcc/ChangeLog7
-rw-r--r--gcc/varasm.c34
2 files changed, 38 insertions, 3 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index a7585bb..7dfcd97 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,3 +1,10 @@
+2018-09-13 Bernd Edlinger <bernd.edlinger@hotmail.de>
+
+ * varasm.c (compare_constant): Compare type size of STRING_CSTs.
+ (get_constant_size): Don't make STRING_CSTs larger than they are.
+ (check_string_literal): New check function for STRING_CSTs.
+ (output_constant): Use it.
+
2018-09-13 Eric Botcazou <ebotcazou@adacore.com>
PR target/86812
diff --git a/gcc/varasm.c b/gcc/varasm.c
index 27d878f..e46bc59 100644
--- a/gcc/varasm.c
+++ b/gcc/varasm.c
@@ -3146,7 +3146,9 @@ compare_constant (const tree t1, const tree t2)
return FIXED_VALUES_IDENTICAL (TREE_FIXED_CST (t1), TREE_FIXED_CST (t2));
case STRING_CST:
- if (TYPE_MODE (TREE_TYPE (t1)) != TYPE_MODE (TREE_TYPE (t2)))
+ if (TYPE_MODE (TREE_TYPE (t1)) != TYPE_MODE (TREE_TYPE (t2))
+ || int_size_in_bytes (TREE_TYPE (t1))
+ != int_size_in_bytes (TREE_TYPE (t2)))
return 0;
return (TREE_STRING_LENGTH (t1) == TREE_STRING_LENGTH (t2)
@@ -3303,8 +3305,9 @@ get_constant_size (tree exp)
HOST_WIDE_INT size;
size = int_size_in_bytes (TREE_TYPE (exp));
- if (TREE_CODE (exp) == STRING_CST)
- size = MAX (TREE_STRING_LENGTH (exp), size);
+ gcc_checking_assert (size >= 0);
+ gcc_checking_assert (TREE_CODE (exp) != STRING_CST
+ || size >= TREE_STRING_LENGTH (exp));
return size;
}
@@ -4773,6 +4776,30 @@ initializer_constant_valid_for_bitfield_p (tree value)
return false;
}
+/* Check if a STRING_CST fits into the field.
+ Tolerate only the case when the NUL termination
+ does not fit into the field. */
+
+static bool
+check_string_literal (tree string, unsigned HOST_WIDE_INT size)
+{
+ tree type = TREE_TYPE (string);
+ tree eltype = TREE_TYPE (type);
+ unsigned HOST_WIDE_INT elts = tree_to_uhwi (TYPE_SIZE_UNIT (eltype));
+ unsigned HOST_WIDE_INT mem_size = tree_to_uhwi (TYPE_SIZE_UNIT (type));
+ int len = TREE_STRING_LENGTH (string);
+
+ if (elts != 1 && elts != 2 && elts != 4)
+ return false;
+ if (len < 0 || len % elts != 0)
+ return false;
+ if (size < (unsigned)len)
+ return false;
+ if (mem_size != size)
+ return false;
+ return true;
+}
+
/* output_constructor outer state of relevance in recursive calls, typically
for nested aggregate bitfields. */
@@ -4941,6 +4968,7 @@ output_constant (tree exp, unsigned HOST_WIDE_INT size, unsigned int align,
case STRING_CST:
thissize
= MIN ((unsigned HOST_WIDE_INT)TREE_STRING_LENGTH (exp), size);
+ gcc_checking_assert (check_string_literal (exp, size));
assemble_string (TREE_STRING_POINTER (exp), thissize);
break;
case VECTOR_CST: