aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJakub Jelinek <jakub@redhat.com>2025-01-20 18:00:43 +0100
committerJakub Jelinek <jakub@gcc.gnu.org>2025-01-20 18:00:43 +0100
commit0b58219fe112c01ff335edf699c4fc69e718c75b (patch)
treee35f578105679db7c150be92a233820267212ceb
parent9d869296f095a02c37d3721f546ce99663e5417c (diff)
downloadgcc-0b58219fe112c01ff335edf699c4fc69e718c75b.zip
gcc-0b58219fe112c01ff335edf699c4fc69e718c75b.tar.gz
gcc-0b58219fe112c01ff335edf699c4fc69e718c75b.tar.bz2
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 <jakub@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.
-rw-r--r--gcc/c-family/c-common.cc19
-rw-r--r--gcc/testsuite/g++.dg/cpp/embed-21.C22
-rw-r--r--gcc/testsuite/g++.dg/cpp2a/class-deduction-aggr16.C17
3 files changed, 57 insertions, 1 deletions
diff --git a/gcc/c-family/c-common.cc b/gcc/c-family/c-common.cc
index 81ca5d3..91d9072 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 0000000..67c9993
--- /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 0000000..7598efdb
--- /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 } } };