Hi! 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. Bootstrapped/regtested on x86_64-linux and i686-linux, ok for trunk? 2024-11-01 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. --- gcc/gimplify.cc.jj 2024-10-25 10:00:29.471767814 +0200 +++ gcc/gimplify.cc 2024-10-31 16:29:00.431732531 +0100 @@ -5420,6 +5420,8 @@ gimplify_init_ctor_eval (tree object, ve 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, --- gcc/testsuite/c-c++-common/init-7.c.jj 2024-10-31 16:52:59.845548100 +0100 +++ gcc/testsuite/c-c++-common/init-7.c 2024-10-31 16:58:20.050068483 +0100 @@ -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); +} Jakub