https://gcc.gnu.org/g:0b58219fe112c01ff335edf699c4fc69e718c75b
commit r15-7069-g0b58219fe112c01ff335edf699c4fc69e718c75b Author: Jakub Jelinek <ja...@redhat.com> Date: Mon Jan 20 18:00:43 2025 +0100 c++: Handle RAW_DATA_CST in make_tree_vector_from_ctor [PR118528] 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. 2025-01-20 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. Diff: --- gcc/c-family/c-common.cc | 19 ++++++++++++++++++- gcc/testsuite/g++.dg/cpp/embed-21.C | 22 ++++++++++++++++++++++ .../g++.dg/cpp2a/class-deduction-aggr16.C | 17 +++++++++++++++++ 3 files changed, 57 insertions(+), 1 deletion(-) diff --git a/gcc/c-family/c-common.cc b/gcc/c-family/c-common.cc index 81ca5d34df86..91d90725152a 100644 --- a/gcc/c-family/c-common.cc +++ b/gcc/c-family/c-common.cc @@ -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) - 1; + vec_safe_reserve (ret, nelts - ret->length ()); + 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; } diff --git a/gcc/testsuite/g++.dg/cpp/embed-21.C b/gcc/testsuite/g++.dg/cpp/embed-21.C new file mode 100644 index 000000000000..67c9993f1693 --- /dev/null +++ b/gcc/testsuite/g++.dg/cpp/embed-21.C @@ -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) +} } }; diff --git a/gcc/testsuite/g++.dg/cpp2a/class-deduction-aggr16.C b/gcc/testsuite/g++.dg/cpp2a/class-deduction-aggr16.C new file mode 100644 index 000000000000..7598efdb0b0b --- /dev/null +++ b/gcc/testsuite/g++.dg/cpp2a/class-deduction-aggr16.C @@ -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 } } };