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