https://gcc.gnu.org/g:60ad1e40649244aa219b411c1a1ef5e00ec6a87b

commit r15-4376-g60ad1e40649244aa219b411c1a1ef5e00ec6a87b
Author: Jakub Jelinek <ja...@redhat.com>
Date:   Wed Oct 16 10:20:00 2024 +0200

    gimplify: Small RAW_DATA_CST gimplification fix
    
    I've noticed the following testcase hangs during gimplification.
    
    While it is gimplifying an assignment from a VAR_DECL .LCNNN to MEM_REF,
    because the VAR_DECL is TREE_READONLY, it will happily pick its initializer
    and try to gimplify that, which means recursing to the exact same code.
    
    The following patch fixes that by just gimplifying the lhs and building
    assignment, because the code decided that it should use copying from
    a static var.
    
    2024-10-16  Jakub Jelinek  <ja...@redhat.com>
    
            * gimplify.cc (gimplify_init_ctor_eval): For larger RAW_DATA_CST,
            just gimplify cref as lvalue and add gimple assignment of rctor
            to cref instead of going through gimplification of INIT_EXPR, as
            the latter can suffer from infinite recursion.
    
            * c-c++-common/cpp/embed-24.c: New test.

Diff:
---
 gcc/gimplify.cc                           |  7 +++--
 gcc/testsuite/c-c++-common/cpp/embed-24.c | 52 +++++++++++++++++++++++++++++++
 2 files changed, 56 insertions(+), 3 deletions(-)

diff --git a/gcc/gimplify.cc b/gcc/gimplify.cc
index 9284fffe137f..769b880cce58 100644
--- a/gcc/gimplify.cc
+++ b/gcc/gimplify.cc
@@ -5419,9 +5419,10 @@ 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);
-             tree init = build2 (INIT_EXPR, rtype, cref, rctor);
-             gimplify_and_add (init, pre_p);
-             ggc_free (init);
+             if (gimplify_expr (&cref, pre_p, NULL, is_gimple_lvalue,
+                                fb_lvalue) != GS_ERROR)
+               gimplify_seq_add_stmt (pre_p,
+                                      gimple_build_assign (cref, rctor));
            }
        }
       else
diff --git a/gcc/testsuite/c-c++-common/cpp/embed-24.c 
b/gcc/testsuite/c-c++-common/cpp/embed-24.c
new file mode 100644
index 000000000000..d59a7e55cec5
--- /dev/null
+++ b/gcc/testsuite/c-c++-common/cpp/embed-24.c
@@ -0,0 +1,52 @@
+/* { dg-do run } */
+/* { dg-options "-O2" } */
+/* { dg-additional-options "-std=c23" { target c } } */
+
+static unsigned char a[] = {
+#embed __FILE__ limit (125)
+};
+
+void
+foo (unsigned char *p)
+{
+  for (int i = 0; i < 128; ++i)
+    if (p[i] != ((i < 64 || i == 127) ? (unsigned char) -1 : i - 64 + 33))
+      __builtin_abort ();
+  if (__builtin_memcmp (p + 128, a, 125))
+    __builtin_abort ();
+  for (int i = 253; i < 256; ++i)
+    if (p[i] != (unsigned char) -1)
+      __builtin_abort ();
+}
+
+#ifdef __cplusplus
+#define M1 (unsigned char) -1
+#else
+#define M1 -1
+#endif
+
+int
+main ()
+{
+  unsigned char res[256] = {
+    M1, M1, M1, M1, M1, M1, M1, M1, 
+    M1, M1, M1, M1, M1, M1, M1, M1, 
+    M1, M1, M1, M1, M1, M1, M1, M1, 
+    M1, M1, M1, M1, M1, M1, M1, M1, 
+    M1, M1, M1, M1, M1, M1, M1, M1, 
+    M1, M1, M1, M1, M1, M1, M1, M1, 
+    M1, M1, M1, M1, M1, M1, M1, M1, 
+    M1, M1, M1, M1, M1, M1, M1, M1, 
+    33, 34, 35, 36, 37, 38, 39, 40, 
+    41, 42, 43, 44, 45, 46, 47, 48, 
+    49, 50, 51, 52, 53, 54, 55, 56, 
+    57, 58, 59, 60, 61, 62, 63, 64, 
+    65, 66, 67, 68, 69, 70, 71, 72, 
+    73, 74, 75, 76, 77, 78, 79, 80, 
+    81, 82, 83, 84, 85, 86, 87, 88, 
+    89, 90, 91, 92, 93, 94, 95, M1,
+  #embed __FILE__ limit (125) suffix (,)
+    M1, M1, M1
+  };
+  foo (res);
+}

Reply via email to