https://gcc.gnu.org/g:f93059c82e61d67bc550ba0e3bf915ab763b02c7

commit r15-5772-gf93059c82e61d67bc550ba0e3bf915ab763b02c7
Author: Jakub Jelinek <ja...@redhat.com>
Date:   Fri Nov 29 10:19:08 2024 +0100

    gimple-fold: Fix up type_has_padding_at_level_p [PR117065]
    
    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).
    
    2024-11-29  Jakub Jelinek  <ja...@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.

Diff:
---
 gcc/gimple-fold.cc              |  2 +-
 gcc/testsuite/gcc.dg/pr117065.c | 12 ++++++++++++
 2 files changed, 13 insertions(+), 1 deletion(-)

diff --git a/gcc/gimple-fold.cc b/gcc/gimple-fold.cc
index e85744651d08..ba2c94794de0 100644
--- a/gcc/gimple-fold.cc
+++ b/gcc/gimple-fold.cc
@@ -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)
diff --git a/gcc/testsuite/gcc.dg/pr117065.c b/gcc/testsuite/gcc.dg/pr117065.c
new file mode 100644
index 000000000000..322cf4de1ae7
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/pr117065.c
@@ -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;
+}

Reply via email to