https://gcc.gnu.org/g:1fb467dbcc2cdd3bb89fa860a1f86b7e334e0ce3

commit r15-4863-g1fb467dbcc2cdd3bb89fa860a1f86b7e334e0ce3
Author: Jakub Jelinek <ja...@redhat.com>
Date:   Sat Nov 2 18:47:27 2024 +0100

    gimplify: Fix up RAW_DATA_CST related ICE [PR117384]
    
    Apparently tree_output_constant_def doesn't strictly guarantee that the
    returned VAR_DECL will have the same or uselessly convertible type as
    the type of the constant passed to it, compare_constants says:
     /* For arrays, check that mode, size and storage order match.  */
     /* For record and union constructors, require exact type equality.  */
    The older use of tree_output_constant_def in gimplify.cc was already
    handling this right:
                   ctor = tree_output_constant_def (ctor);
                   if (!useless_type_conversion_p (type, TREE_TYPE (ctor)))
                     ctor = build1 (VIEW_CONVERT_EXPR, type, ctor);
    but the spot I've added for RAW_DATA_CST missed this.
    
    So, the following patch adds that.
    
    2024-11-02  Jakub Jelinek  <ja...@redhat.com>
    
            PR middle-end/117384
            * gimplify.cc (gimplify_init_ctor_eval): Add VIEW_CONVERT_EXPR 
around
            rctor if it doesn't have expected type.
    
            * c-c++-common/init-7.c: New test.

Diff:
---
 gcc/gimplify.cc                     |  2 ++
 gcc/testsuite/c-c++-common/init-7.c | 39 +++++++++++++++++++++++++++++++++++++
 2 files changed, 41 insertions(+)

diff --git a/gcc/gimplify.cc b/gcc/gimplify.cc
index fd18d8be4e66..827941b24db2 100644
--- a/gcc/gimplify.cc
+++ b/gcc/gimplify.cc
@@ -5420,6 +5420,8 @@ gimplify_init_ctor_eval (tree object, 
vec<constructor_elt, va_gc> *elts,
              cref = build2 (MEM_REF, rtype, addr,
                             build_int_cst (ptr_type_node, 0));
              rctor = tree_output_constant_def (rctor);
+             if (!useless_type_conversion_p (rtype, TREE_TYPE (rctor)))
+               rctor = build1 (VIEW_CONVERT_EXPR, rtype, rctor);
              if (gimplify_expr (&cref, pre_p, NULL, is_gimple_lvalue,
                                 fb_lvalue) != GS_ERROR)
                gimplify_seq_add_stmt (pre_p,
diff --git a/gcc/testsuite/c-c++-common/init-7.c 
b/gcc/testsuite/c-c++-common/init-7.c
new file mode 100644
index 000000000000..8df387c91764
--- /dev/null
+++ b/gcc/testsuite/c-c++-common/init-7.c
@@ -0,0 +1,39 @@
+/* PR middle-end/117384 */
+/* { dg-do compile } */
+/* { dg-options "-O2" } */
+
+void baz (signed char *, unsigned char *);
+
+void
+foo (void)
+{
+  signed char b[] = {
+    44, 28, 12, 96, 80, 64, 48, 32, 1, 2, 3, 4, 5, 6, 7, 8,
+    9, 24, 39, 54, 69, 84, 99, 114, 17, 34, 51, 68, 85, 102, 19, 36,
+    53, 36, 19, 102, 85, 68, 51, 34, 17, 34, 51, 68, 85, 102, 19, 36,
+    53, 36, 19, 102, 85, 68, 51, 34, 17, 34, 51, 68, 85, 102, 19, 36,
+    53, 36, 19, 102, 85, 68, 51, 34, 17, 34, 51, 68, 85, 102, 19, 36,
+    53, 36, 19, 102, 85, 68, 51, 34, 17, 34, 51, 68, 85, 102, 19, 36,
+    53, 36, 19, 102, 85, 68, 51, 34, 17, 34, 51, 68, 85, 102, 19, 36,
+    53, 36, 19, 102, 85, 68, 51, 34, 17, 34, 51, 68, 85, 102, 19, 36,
+    53, 36, 19, 102, 85, 68, 51, 34, 17, 34, 51, 68, 85, 102, 19, 36
+  };
+  baz (b, 0);
+}
+
+void
+bar (void)
+{
+  unsigned char b[] = {
+    44, 28, 12, 96, 80, 64, 48, 32, 1, 2, 3, 4, 5, 6, 7, 8,
+    9, 24, 39, 54, 69, 84, 99, 114, 17, 34, 51, 68, 85, 102, 19, 36,
+    53, 36, 19, 102, 85, 68, 51, 34, 17, 34, 51, 68, 85, 102, 19, 36,
+    53, 36, 19, 102, 85, 68, 51, 34, 17, 34, 51, 68, 85, 102, 19, 36,
+    53, 36, 19, 102, 85, 68, 51, 34, 17, 34, 51, 68, 85, 102, 19, 36,
+    53, 36, 19, 102, 85, 68, 51, 34, 17, 34, 51, 68, 85, 102, 19, 36,
+    53, 36, 19, 102, 85, 68, 51, 34, 17, 34, 51, 68, 85, 102, 19, 36,
+    53, 36, 19, 102, 85, 68, 51, 34, 17, 34, 51, 68, 85, 102, 19, 36,
+    53, 36, 19, 102, 85, 68, 51, 34, 17, 34, 51, 68, 85, 102, 19, 36
+  };
+  baz (0, b);
+}

Reply via email to