aboutsummaryrefslogtreecommitdiff
path: root/gcc/gimple-fold.c
diff options
context:
space:
mode:
authorJakub Jelinek <jakub@redhat.com>2020-11-25 10:37:58 +0100
committerJakub Jelinek <jakub@redhat.com>2020-11-25 10:37:58 +0100
commita7285c8659689e9ade53fcb996b26d874455a4f3 (patch)
tree5db8400816f1cad1b376e8d8f448dfef057be0fa /gcc/gimple-fold.c
parent1e2c9a2761097a6758b6aaaf612d629aa7e9febf (diff)
downloadgcc-a7285c8659689e9ade53fcb996b26d874455a4f3.zip
gcc-a7285c8659689e9ade53fcb996b26d874455a4f3.tar.gz
gcc-a7285c8659689e9ade53fcb996b26d874455a4f3.tar.bz2
middle-end: Reject flexible array members in __builtin_clear_padding [PR97943]
As mentioned in the PR, we currently ICE on flexible array members in structs and unions during __builtin_clear_padding processing. Jason said in the PR he'd prefer an error in these cases over forcefully handling it as [0] arrays (everything is padding then) or consider the arrays to have as many whole elements as would fit into the tail padding. So, this patch implements that. 2020-11-25 Jakub Jelinek <jakub@redhat.com> PR middle-end/97943 * gimple-fold.c (clear_padding_union, clear_padding_type): Error on and ignore flexible array member fields. Ignore fields with error_mark_node type. * c-c++-common/builtin-clear-padding-2.c: New test. * c-c++-common/builtin-clear-padding-3.c: New test. * g++.dg/ext/builtin-clear-padding-1.C: New test. * gcc.dg/builtin-clear-padding-2.c: New test.
Diffstat (limited to 'gcc/gimple-fold.c')
-rw-r--r--gcc/gimple-fold.c24
1 files changed, 23 insertions, 1 deletions
diff --git a/gcc/gimple-fold.c b/gcc/gimple-fold.c
index 905c0a0..1f0a6097 100644
--- a/gcc/gimple-fold.c
+++ b/gcc/gimple-fold.c
@@ -4329,6 +4329,17 @@ clear_padding_union (clear_padding_struct *buf, tree type, HOST_WIDE_INT sz)
for (tree field = TYPE_FIELDS (type); field; field = DECL_CHAIN (field))
if (TREE_CODE (field) == FIELD_DECL)
{
+ if (DECL_SIZE_UNIT (field) == NULL_TREE)
+ {
+ if (TREE_TYPE (field) == error_mark_node)
+ continue;
+ gcc_assert (TREE_CODE (TREE_TYPE (field)) == ARRAY_TYPE
+ && !COMPLETE_TYPE_P (TREE_TYPE (field)));
+ error_at (buf->loc, "flexible array member %qD does not have "
+ "well defined padding bits for %qs",
+ field, "__builtin_clear_padding");
+ continue;
+ }
HOST_WIDE_INT fldsz = tree_to_shwi (DECL_SIZE_UNIT (field));
gcc_assert (union_buf->size == 0);
union_buf->off = start_off;
@@ -4446,11 +4457,12 @@ clear_padding_type (clear_padding_struct *buf, tree type, HOST_WIDE_INT sz)
for (tree field = TYPE_FIELDS (type); field; field = DECL_CHAIN (field))
if (TREE_CODE (field) == FIELD_DECL)
{
+ tree ftype = TREE_TYPE (field);
if (DECL_BIT_FIELD (field))
{
if (DECL_NAME (field) == NULL_TREE)
continue;
- HOST_WIDE_INT fldsz = TYPE_PRECISION (TREE_TYPE (field));
+ HOST_WIDE_INT fldsz = TYPE_PRECISION (ftype);
if (fldsz == 0)
continue;
HOST_WIDE_INT pos = int_byte_position (field);
@@ -4513,6 +4525,16 @@ clear_padding_type (clear_padding_struct *buf, tree type, HOST_WIDE_INT sz)
}
}
}
+ else if (DECL_SIZE_UNIT (field) == NULL_TREE)
+ {
+ if (ftype == error_mark_node)
+ continue;
+ gcc_assert (TREE_CODE (ftype) == ARRAY_TYPE
+ && !COMPLETE_TYPE_P (ftype));
+ error_at (buf->loc, "flexible array member %qD does not have "
+ "well defined padding bits for %qs",
+ field, "__builtin_clear_padding");
+ }
else
{
HOST_WIDE_INT pos = int_byte_position (field);