aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJakub Jelinek <jakub@redhat.com>2025-03-12 08:01:09 +0100
committerJakub Jelinek <jakub@gcc.gnu.org>2025-03-12 08:01:09 +0100
commit28b05e4317a6eade2ba46076ef17f9e138c57a34 (patch)
tree5ad5e895745152e6f11aecd224172def28768abc
parent2fa031afe4ea78f490f06e487c48089d7376827c (diff)
downloadgcc-28b05e4317a6eade2ba46076ef17f9e138c57a34.zip
gcc-28b05e4317a6eade2ba46076ef17f9e138c57a34.tar.gz
gcc-28b05e4317a6eade2ba46076ef17f9e138c57a34.tar.bz2
c++: Handle RAW_DATA_CST in modules.cc [PR119076]
The following testcases (one with #embed, one with large initializer turned into RAW_DATA_CST) show that I forgot to handle RAW_DATA_CST in module streaming. Similar to the PCH case we need to stream out RAW_DATA_CST with NULL RAW_DATA_OWNER (i.e. a tree which has data owned by libcpp buffer) so that it will be streamed back in as STRING_CST which owns the data, but because the data can be really large (hopefully not so much for header modules though), without actually trying to build a STRING_CST on the module writing side because that would mean another large allocation and copying of the large data. RAW_DATA_CST with RAW_DATA_OWNER then needs to be streamed out and in by streaming the owner and offset from owner's data and length. 2025-03-12 Jakub Jelinek <jakub@redhat.com> PR c++/119076 * module.cc (trees_out::start): Handle RAW_DATA_CST. (trees_in::start): Likewise. (trees_out::core_vals): Likewise. (trees_in::core_vals): Likewise. * g++.dg/modules/pr119076-1_a.H: New test. * g++.dg/modules/pr119076-1_b.C: New test. * g++.dg/modules/pr119076-2_a.H: New test. * g++.dg/modules/pr119076-2_b.C: New test.
-rw-r--r--gcc/cp/module.cc65
-rw-r--r--gcc/testsuite/g++.dg/modules/pr119076-1_a.H41
-rw-r--r--gcc/testsuite/g++.dg/modules/pr119076-1_b.C12
-rw-r--r--gcc/testsuite/g++.dg/modules/pr119076-2_a.H65
-rw-r--r--gcc/testsuite/g++.dg/modules/pr119076-2_b.C12
5 files changed, 195 insertions, 0 deletions
diff --git a/gcc/cp/module.cc b/gcc/cp/module.cc
index 97c3549..9a1cd52 100644
--- a/gcc/cp/module.cc
+++ b/gcc/cp/module.cc
@@ -5379,6 +5379,30 @@ trees_out::start (tree t, bool code_streamed)
str (TREE_STRING_POINTER (t), TREE_STRING_LENGTH (t));
break;
+ case RAW_DATA_CST:
+ if (RAW_DATA_OWNER (t) == NULL_TREE)
+ {
+ /* Stream RAW_DATA_CST with no owner (i.e. data pointing
+ into libcpp buffers) as something we can stream in as
+ STRING_CST which owns the data. */
+ u (0);
+ /* Can't use str (RAW_DATA_POINTER (t), RAW_DATA_LENGTH (t));
+ here as there isn't a null termination after it. */
+ z (RAW_DATA_LENGTH (t));
+ if (RAW_DATA_LENGTH (t))
+ if (void *ptr = buf (RAW_DATA_LENGTH (t) + 1))
+ {
+ memcpy (ptr, RAW_DATA_POINTER (t), RAW_DATA_LENGTH (t));
+ ((char *) ptr)[RAW_DATA_LENGTH (t)] = '\0';
+ }
+ }
+ else
+ {
+ gcc_assert (RAW_DATA_LENGTH (t));
+ u (RAW_DATA_LENGTH (t));
+ }
+ break;
+
case VECTOR_CST:
u (VECTOR_CST_LOG2_NPATTERNS (t));
u (VECTOR_CST_NELTS_PER_PATTERN (t));
@@ -5472,6 +5496,24 @@ trees_in::start (unsigned code)
}
break;
+ case RAW_DATA_CST:
+ {
+ size_t l = u ();
+ if (l == 0)
+ {
+ /* Stream in RAW_DATA_CST with no owner as STRING_CST
+ which owns the data. */
+ const char *chars = str (&l);
+ t = build_string (l, chars);
+ }
+ else
+ {
+ t = make_node (RAW_DATA_CST);
+ RAW_DATA_LENGTH (t) = l;
+ }
+ }
+ break;
+
case VECTOR_CST:
{
unsigned log2_npats = u ();
@@ -6383,6 +6425,22 @@ trees_out::core_vals (tree t)
/* Streamed during start. */
break;
+ case RAW_DATA_CST:
+ if (RAW_DATA_OWNER (t) == NULL_TREE)
+ break; /* Streamed as STRING_CST during start. */
+ WT (RAW_DATA_OWNER (t));
+ if (streaming_p ())
+ {
+ if (TREE_CODE (RAW_DATA_OWNER (t)) == RAW_DATA_CST)
+ z (RAW_DATA_POINTER (t) - RAW_DATA_POINTER (RAW_DATA_OWNER (t)));
+ else if (TREE_CODE (RAW_DATA_OWNER (t)) == STRING_CST)
+ z (RAW_DATA_POINTER (t)
+ - TREE_STRING_POINTER (RAW_DATA_OWNER (t)));
+ else
+ gcc_unreachable ();
+ }
+ break;
+
case VECTOR_CST:
for (unsigned ix = vector_cst_encoded_nelts (t); ix--;)
WT (VECTOR_CST_ENCODED_ELT (t, ix));
@@ -6917,6 +6975,13 @@ trees_in::core_vals (tree t)
/* Streamed during start. */
break;
+ case RAW_DATA_CST:
+ RT (RAW_DATA_OWNER (t));
+ gcc_assert (TREE_CODE (RAW_DATA_OWNER (t)) == STRING_CST
+ && TREE_STRING_LENGTH (RAW_DATA_OWNER (t)));
+ RAW_DATA_POINTER (t) = TREE_STRING_POINTER (RAW_DATA_OWNER (t)) + z ();
+ break;
+
case VECTOR_CST:
for (unsigned ix = vector_cst_encoded_nelts (t); ix--;)
RT (VECTOR_CST_ENCODED_ELT (t, ix));
diff --git a/gcc/testsuite/g++.dg/modules/pr119076-1_a.H b/gcc/testsuite/g++.dg/modules/pr119076-1_a.H
new file mode 100644
index 0000000..17eb756
--- /dev/null
+++ b/gcc/testsuite/g++.dg/modules/pr119076-1_a.H
@@ -0,0 +1,41 @@
+// { dg-additional-options "-fmodule-header -Wno-pedantic" }
+// { dg-module-cmi {} }
+
+constexpr unsigned char a[] = {
+#embed __FILE__
+};
+
+constexpr int
+foo (const unsigned char *p, int s)
+{
+ int r = 0;
+ for (int i = 0; i < s; ++i)
+ r += p[i];
+ return r;
+}
+
+constexpr int b = foo (a, sizeof a);
+
+inline int
+bar ()
+{
+ const unsigned char b[] = {
+ #embed __FILE__
+ };
+ int r = 0;
+ for (int i = 0; i < sizeof b; ++i)
+ r += b[i];
+ return r;
+}
+
+inline int
+baz ()
+{
+ const long int c[] = {
+ #embed __FILE__
+ };
+ int r = 0;
+ for (int i = 0; i < sizeof (c) / sizeof (c[0]); ++i)
+ r += c[i];
+ return r;
+}
diff --git a/gcc/testsuite/g++.dg/modules/pr119076-1_b.C b/gcc/testsuite/g++.dg/modules/pr119076-1_b.C
new file mode 100644
index 0000000..e6528d1
--- /dev/null
+++ b/gcc/testsuite/g++.dg/modules/pr119076-1_b.C
@@ -0,0 +1,12 @@
+// PR c++/119076
+// { dg-do run }
+// { dg-additional-options "-fmodules-ts" }
+
+import "pr119076-1_a.H";
+
+int
+main ()
+{
+ if (bar () != b || baz () != b)
+ __builtin_abort ();
+}
diff --git a/gcc/testsuite/g++.dg/modules/pr119076-2_a.H b/gcc/testsuite/g++.dg/modules/pr119076-2_a.H
new file mode 100644
index 0000000..7c139fd
--- /dev/null
+++ b/gcc/testsuite/g++.dg/modules/pr119076-2_a.H
@@ -0,0 +1,65 @@
+// { dg-additional-options "-fmodule-header" }
+// { dg-module-cmi {} }
+
+constexpr unsigned char a[] = {
+ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15,
+ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15,
+ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15,
+ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15,
+ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15,
+ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15,
+ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15,
+ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15,
+ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15,
+};
+
+constexpr int
+foo (const unsigned char *p, int s)
+{
+ int r = 0;
+ for (int i = 0; i < s; ++i)
+ r += p[i];
+ return r;
+}
+
+constexpr int b = foo (a, sizeof a);
+
+inline int
+bar ()
+{
+ const unsigned char b[] = {
+ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15,
+ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15,
+ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15,
+ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15,
+ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15,
+ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15,
+ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15,
+ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15,
+ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15,
+ };
+ int r = 0;
+ for (int i = 0; i < sizeof b; ++i)
+ r += b[i];
+ return r;
+}
+
+inline int
+baz ()
+{
+ const long int c[] = {
+ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15,
+ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15,
+ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15,
+ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15,
+ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15,
+ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15,
+ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15,
+ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15,
+ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15,
+ };
+ int r = 0;
+ for (int i = 0; i < sizeof (c) / sizeof (c[0]); ++i)
+ r += c[i];
+ return r;
+}
diff --git a/gcc/testsuite/g++.dg/modules/pr119076-2_b.C b/gcc/testsuite/g++.dg/modules/pr119076-2_b.C
new file mode 100644
index 0000000..3dba75f
--- /dev/null
+++ b/gcc/testsuite/g++.dg/modules/pr119076-2_b.C
@@ -0,0 +1,12 @@
+// PR c++/119076
+// { dg-do run }
+// { dg-additional-options "-fmodules-ts" }
+
+import "pr119076-2_a.H";
+
+int
+main ()
+{
+ if (bar () != b || baz () != b)
+ __builtin_abort ();
+}