mirror of
git://gcc.gnu.org/git/gcc.git
synced 2025-03-23 18:11:15 +08:00
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.
This commit is contained in:
parent
1e2c9a2761
commit
a7285c8659
@ -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);
|
||||
|
17
gcc/testsuite/c-c++-common/builtin-clear-padding-2.c
Normal file
17
gcc/testsuite/c-c++-common/builtin-clear-padding-2.c
Normal file
@ -0,0 +1,17 @@
|
||||
/* PR middle-end/97943 */
|
||||
/* { dg-do compile } */
|
||||
/* { dg-options "" } */
|
||||
|
||||
struct S { int a; char b[] __attribute__((aligned (2 * sizeof (int)))); };
|
||||
struct T { int a; struct S b; };
|
||||
union U { int a; struct S b; };
|
||||
struct V { int a; union U b; };
|
||||
|
||||
void
|
||||
foo (struct S *s, struct T *t, union U *u, struct V *v)
|
||||
{
|
||||
__builtin_clear_padding (s); /* { dg-error "flexible array member '(S::)?b' does not have well defined padding bits for '__builtin_clear_padding'" } */
|
||||
__builtin_clear_padding (t); /* { dg-error "flexible array member '(S::)?b' does not have well defined padding bits for '__builtin_clear_padding'" } */
|
||||
__builtin_clear_padding (u); /* { dg-error "flexible array member '(S::)?b' does not have well defined padding bits for '__builtin_clear_padding'" } */
|
||||
__builtin_clear_padding (v); /* { dg-error "flexible array member '(S::)?b' does not have well defined padding bits for '__builtin_clear_padding'" } */
|
||||
}
|
15
gcc/testsuite/c-c++-common/builtin-clear-padding-3.c
Normal file
15
gcc/testsuite/c-c++-common/builtin-clear-padding-3.c
Normal file
@ -0,0 +1,15 @@
|
||||
/* PR middle-end/97943 */
|
||||
/* { dg-do compile } */
|
||||
/* { dg-options "" } */
|
||||
|
||||
union U { int a; char b[] __attribute__((aligned (2 * sizeof (int)))); }; /* { dg-error "flexible array member in union" } */
|
||||
struct V { int a; union U b; };
|
||||
struct W { int a; union U b; int c; };
|
||||
|
||||
void
|
||||
foo (union U *u, struct V *v, struct W *w)
|
||||
{
|
||||
__builtin_clear_padding (u);
|
||||
__builtin_clear_padding (v);
|
||||
__builtin_clear_padding (w);
|
||||
}
|
15
gcc/testsuite/g++.dg/ext/builtin-clear-padding-1.C
Normal file
15
gcc/testsuite/g++.dg/ext/builtin-clear-padding-1.C
Normal file
@ -0,0 +1,15 @@
|
||||
// PR middle-end/97943
|
||||
// { dg-do compile }
|
||||
// { dg-options "" }
|
||||
|
||||
struct S { int a; char b[] __attribute__((aligned (2 * sizeof (int)))); }; // { dg-error "flexible array member 'S::b' not at end of 'struct \[TV]'" }
|
||||
struct T { int a; struct S b; int c; }; // { dg-message "next member 'int T::c' declared here|in the definition of 'struct T'" }
|
||||
union U { int a; struct S b; };
|
||||
struct V { int a; union U b; int : 15; int c; }; // { dg-message "next member 'int V::c' declared here|in the definition of 'struct V'" }
|
||||
|
||||
void
|
||||
foo (struct T *t, struct V *v)
|
||||
{
|
||||
__builtin_clear_padding (t); // { dg-error "flexible array member 'S::b' does not have well defined padding bits for '__builtin_clear_padding'" }
|
||||
__builtin_clear_padding (v); // { dg-error "flexible array member 'S::b' does not have well defined padding bits for '__builtin_clear_padding'" }
|
||||
}
|
15
gcc/testsuite/gcc.dg/builtin-clear-padding-2.c
Normal file
15
gcc/testsuite/gcc.dg/builtin-clear-padding-2.c
Normal file
@ -0,0 +1,15 @@
|
||||
/* PR middle-end/97943 */
|
||||
/* { dg-do compile } */
|
||||
/* { dg-options "" } */
|
||||
|
||||
struct S { int a; char b[] __attribute__((aligned (2 * sizeof (int)))); };
|
||||
struct T { int a; struct S b; int c; };
|
||||
union U { int a; struct S b; };
|
||||
struct V { int a; union U b; int : 15; int c; };
|
||||
|
||||
void
|
||||
foo (struct T *t, struct V *v)
|
||||
{
|
||||
__builtin_clear_padding (t); /* { dg-error "flexible array member 'b' does not have well defined padding bits for '__builtin_clear_padding'" } */
|
||||
__builtin_clear_padding (v); /* { dg-error "flexible array member 'b' does not have well defined padding bits for '__builtin_clear_padding'" } */
|
||||
}
|
Loading…
x
Reference in New Issue
Block a user