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 <[email protected]>
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