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