gimple-fold: Fix up type_has_padding_at_level_p [PR117065]

Message ID Z0mBOJJpY+cva+L/@tucnak
State New
Headers
Series 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

Jakub Jelinek Nov. 29, 2024, 8:54 a.m. UTC
  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

Richard Biener Nov. 29, 2024, 8:58 a.m. UTC | #1
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
> 
>
  

Patch

--- 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;
+}