gimple-fold: Fix up type_has_padding_at_level_p [PR117065]
Checks
Context |
Check |
Description |
linaro-tcwg-bot/tcwg_gcc_build--master-arm |
success
|
Build passed
|
linaro-tcwg-bot/tcwg_gcc_build--master-aarch64 |
fail
|
Patch failed to apply
|
linaro-tcwg-bot/tcwg_gcc_check--master-arm |
success
|
Test passed
|
Commit Message
Hi!
The following testcase used to ICE on the trunk since the clear small
object if it has padding optimization before my r15-5746 change,
now it doesn't just because type_has_padding_at_level_p isn't called
on the testcase.
Though, as the testcase shows, structures/unions which contain erroneous
types of one or more of its members can have TREE_TYPE of the FIELD_DECL
error_mark_node, on which we can crash.
E.g. the __builtin_clear_padding lowering just ignores those:
if (TREE_TYPE (field) == error_mark_node)
continue;
and
if (ftype == error_mark_node)
continue;
It doesn't matter much what exactly we do for those cases, as we are going
to fail the compilation anyway, but we shouldn't crash.
So, the following patch ignores those in type_has_padding_at_level_p.
For RECORD_TYPE, we already return if !DECL_SIZE (f) which I think should
cover already the erroneous fields (and we don't use TYPE_SIZE on those).
Bootstrapped/regtested on x86_64-linux and i686-linux, ok for trunk?
2024-11-29 Jakub Jelinek <jakub@redhat.com>
PR middle-end/117065
* gimple-fold.cc (type_has_padding_at_level_p) <case UNION_TYPE>:
Also continue if f has error_mark_node type.
* gcc.dg/pr117065.c: New test.
Jakub
Comments
On Fri, 29 Nov 2024, Jakub Jelinek wrote:
> Hi!
>
> The following testcase used to ICE on the trunk since the clear small
> object if it has padding optimization before my r15-5746 change,
> now it doesn't just because type_has_padding_at_level_p isn't called
> on the testcase.
>
> Though, as the testcase shows, structures/unions which contain erroneous
> types of one or more of its members can have TREE_TYPE of the FIELD_DECL
> error_mark_node, on which we can crash.
>
> E.g. the __builtin_clear_padding lowering just ignores those:
> if (TREE_TYPE (field) == error_mark_node)
> continue;
> and
> if (ftype == error_mark_node)
> continue;
> It doesn't matter much what exactly we do for those cases, as we are going
> to fail the compilation anyway, but we shouldn't crash.
>
> So, the following patch ignores those in type_has_padding_at_level_p.
> For RECORD_TYPE, we already return if !DECL_SIZE (f) which I think should
> cover already the erroneous fields (and we don't use TYPE_SIZE on those).
>
> Bootstrapped/regtested on x86_64-linux and i686-linux, ok for trunk?
OK.
Richard.
> 2024-11-29 Jakub Jelinek <jakub@redhat.com>
>
> PR middle-end/117065
> * gimple-fold.cc (type_has_padding_at_level_p) <case UNION_TYPE>:
> Also continue if f has error_mark_node type.
>
> * gcc.dg/pr117065.c: New test.
>
> --- gcc/gimple-fold.cc.jj 2024-11-28 11:38:08.545042716 +0100
> +++ gcc/gimple-fold.cc 2024-11-28 18:11:02.613232891 +0100
> @@ -4863,7 +4863,7 @@ type_has_padding_at_level_p (tree type)
> any_fields = false;
> /* If any of the fields is smaller than the whole, there is padding. */
> for (tree f = TYPE_FIELDS (type); f; f = DECL_CHAIN (f))
> - if (TREE_CODE (f) != FIELD_DECL)
> + if (TREE_CODE (f) != FIELD_DECL || TREE_TYPE (f) == error_mark_node)
> continue;
> else if (simple_cst_equal (TYPE_SIZE (TREE_TYPE (f)),
> TYPE_SIZE (type)) != 1)
> --- gcc/testsuite/gcc.dg/pr117065.c.jj 2024-11-28 18:14:33.526291760 +0100
> +++ gcc/testsuite/gcc.dg/pr117065.c 2024-11-28 18:15:15.515706162 +0100
> @@ -0,0 +1,12 @@
> +/* PR middle-end/117065 */
> +/* { dg-do compile } */
> +/* { dg-options "-std=gnu23" } */
> +
> +union U { struct A a; unsigned long long b; }; /* { dg-error "field 'a' has incomplete type" } */
> +
> +union U
> +foo (void)
> +{
> + union U u = { .b = 1 };
> + return u;
> +}
>
> Jakub
>
>
@@ -4863,7 +4863,7 @@ type_has_padding_at_level_p (tree type)
any_fields = false;
/* If any of the fields is smaller than the whole, there is padding. */
for (tree f = TYPE_FIELDS (type); f; f = DECL_CHAIN (f))
- if (TREE_CODE (f) != FIELD_DECL)
+ if (TREE_CODE (f) != FIELD_DECL || TREE_TYPE (f) == error_mark_node)
continue;
else if (simple_cst_equal (TYPE_SIZE (TREE_TYPE (f)),
TYPE_SIZE (type)) != 1)
@@ -0,0 +1,12 @@
+/* PR middle-end/117065 */
+/* { dg-do compile } */
+/* { dg-options "-std=gnu23" } */
+
+union U { struct A a; unsigned long long b; }; /* { dg-error "field 'a' has incomplete type" } */
+
+union U
+foo (void)
+{
+ union U u = { .b = 1 };
+ return u;
+}