Hi!

This is the first bug discovered today with the
https://gcc.gnu.org/pipermail/gcc-patches/2025-January/673945.html
hack but then turned into proper testcases where embed-21.C FAILed
since introduction of optimized #embed support and the other when
optimizing large C++ initializers using RAW_DATA_CST.

The problem is that the C++ FE calls make_tree_vector_from_ctor
and uses that as arguments vector for deduction guide handling.
The call.cc code isn't prepared to handle RAW_DATA_CST just about
everywhere, so I think it is safer to make sure RAW_DATA_CST only
appears in CONSTRUCTOR_ELTS and nowhere else.
Thus, the following patch expands the RAW_DATA_CSTs from initializers
into multiple INTEGER_CSTs in the returned vector.

Bootstrapped on x86_64-linux and i686-linux, regtests pending, ok
for trunk if it passes?

2025-01-17  Jakub Jelinek  <ja...@redhat.com>

        PR c++/118528
        * c-common.cc (make_tree_vector_from_ctor): Expand RAW_DATA_CST
        elements from the CONSTRUCTOR to individual INTEGER_CSTs.

        * g++.dg/cpp/embed-21.C: New test.
        * g++.dg/cpp2a/class-deduction-aggr16.C: New test.

--- gcc/c-family/c-common.cc.jj 2025-01-02 11:47:29.803228077 +0100
+++ gcc/c-family/c-common.cc    2025-01-17 13:32:53.512294482 +0100
@@ -9016,9 +9016,26 @@ vec<tree, va_gc> *
 make_tree_vector_from_ctor (tree ctor)
 {
   vec<tree,va_gc> *ret = make_tree_vector ();
+  unsigned nelts = CONSTRUCTOR_NELTS (ctor);
   vec_safe_reserve (ret, CONSTRUCTOR_NELTS (ctor));
   for (unsigned i = 0; i < CONSTRUCTOR_NELTS (ctor); ++i)
-    ret->quick_push (CONSTRUCTOR_ELT (ctor, i)->value);
+    if (TREE_CODE (CONSTRUCTOR_ELT (ctor, i)->value) == RAW_DATA_CST)
+      {
+       tree raw_data = CONSTRUCTOR_ELT (ctor, i)->value;
+       nelts += RAW_DATA_LENGTH (raw_data);
+       vec_safe_reserve (ret, nelts);
+       if (TYPE_PRECISION (TREE_TYPE (raw_data)) > CHAR_BIT
+           || TYPE_UNSIGNED (TREE_TYPE (raw_data)))
+         for (unsigned j = 0; j < (unsigned) RAW_DATA_LENGTH (raw_data); ++j)
+           ret->quick_push (build_int_cst (TREE_TYPE (raw_data),
+                                           RAW_DATA_UCHAR_ELT (raw_data, j)));
+       else
+         for (unsigned j = 0; j < (unsigned) RAW_DATA_LENGTH (raw_data); ++j)
+           ret->quick_push (build_int_cst (TREE_TYPE (raw_data),
+                                           RAW_DATA_SCHAR_ELT (raw_data, j)));
+      }
+    else
+      ret->quick_push (CONSTRUCTOR_ELT (ctor, i)->value);
   return ret;
 }
 
--- gcc/testsuite/g++.dg/cpp/embed-21.C.jj      2025-01-17 12:18:00.571912195 
+0100
+++ gcc/testsuite/g++.dg/cpp/embed-21.C 2025-01-17 13:37:31.478489868 +0100
@@ -0,0 +1,22 @@
+// PR c++/118528
+// { dg-do compile { target c++20 } }
+// { dg-options "" }
+
+template<class T>
+struct E { T t[130][2]; };
+
+E e1 {
+#embed __FILE__ limit (260)
+};
+
+template<class T>
+struct F { T t[2][130]; };
+
+F f1 {
+#embed __FILE__ limit (260)
+};
+F f2 { { {
+#embed __FILE__ limit (130)
+}, {
+#embed __FILE__ limit (130)
+} } };
--- gcc/testsuite/g++.dg/cpp2a/class-deduction-aggr16.C.jj      2025-01-17 
12:17:23.715424611 +0100
+++ gcc/testsuite/g++.dg/cpp2a/class-deduction-aggr16.C 2025-01-17 
12:17:43.717146527 +0100
@@ -0,0 +1,17 @@
+// PR c++/118528
+// { dg-do compile { target c++20 } }
+
+template<class T>
+struct E { T t[130][2]; };
+
+#define P 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16
+#define Q { 1, 2 }, { 3, 4 }, { 5, 6 }, { 7, 8 }, { 9, 10 }, { 11, 12 }, \
+         { 13, 14 }, { 15, 16 }
+E e1 { P, P, P, P, P, P, P, P, P, P, P, P, P, P, P, P, 1, 2, 3, 4 };
+E e2 { { Q, Q, Q, Q, Q, Q, Q, Q, Q, Q, Q, Q, Q, Q, Q, Q, { 1, 2 }, { 3, 4 } } 
};
+
+template<class T>
+struct F { T t[2][130]; };
+
+F f1 { P, P, P, P, P, P, P, P, P, P, P, P, P, P, P, P, 1, 2, 3, 4 };
+F f2 { { { P, P, P, P, P, P, P, P, 1, 2 }, { P, P, P, P, P, P, P, P, 3, 4 } } 
};

        Jakub

Reply via email to