public inbox for gcc-cvs@sourceware.org
help / color / mirror / Atom feed
* [gcc r14-4806] c++: Constructor streaming [PR105322]
@ 2023-10-20 20:25 Nathan Sidwell
0 siblings, 0 replies; only message in thread
From: Nathan Sidwell @ 2023-10-20 20:25 UTC (permalink / raw)
To: gcc-cvs
https://gcc.gnu.org/g:084addf8a700fab9222d4127ab8524920d0ca481
commit r14-4806-g084addf8a700fab9222d4127ab8524920d0ca481
Author: Nathan Sidwell <nathan@acm.org>
Date: Fri Oct 20 12:20:37 2023 -0400
c++: Constructor streaming [PR105322]
An expresion node's type is streamed after the expression's operands,
because the type can come from some aspect of an operand (for instance
decltype and noexcept). There's a comment in the code explaining that.
But that doesn't work for constructors, which can directly reference
components of their type (eg FIELD_DECLS). If this is a
type-introducing CONSTRUCTOR, we need to ensure the type has been
streamed first. So move CONSTRUCTOR stream to after the type streaming.
The reason things like COMPONENT_REF work is that they stream their
first operand first, and that introduces the type that their second
operand looks up a field in.
gcc/cp/
PR c++/105322
* module.cc (trees_out::core_vals): Stream CONSTRUCTOR operands
after the type.
(trees_in::core_vals): Likewise.
gcc/testsuite/
* g++.dg/modules/decltype-1_a.C: New.
* g++.dg/modules/decltype-1_b.C: New.
* g++.dg/modules/lambda-5_a.C: New.
* g++.dg/modules/lambda-5_b.C: New.
Diff:
---
gcc/cp/module.cc | 58 ++++++++++++++++-------------
gcc/testsuite/g++.dg/modules/decltype-1_a.C | 28 ++++++++++++++
gcc/testsuite/g++.dg/modules/decltype-1_b.C | 10 +++++
gcc/testsuite/g++.dg/modules/lambda-5_a.C | 24 ++++++++++++
gcc/testsuite/g++.dg/modules/lambda-5_b.C | 10 +++++
5 files changed, 105 insertions(+), 25 deletions(-)
diff --git a/gcc/cp/module.cc b/gcc/cp/module.cc
index bbb1e20b55b4..539518d79234 100644
--- a/gcc/cp/module.cc
+++ b/gcc/cp/module.cc
@@ -6212,19 +6212,9 @@ trees_out::core_vals (tree t)
break;
case CONSTRUCTOR:
- {
- unsigned len = vec_safe_length (t->constructor.elts);
- if (streaming_p ())
- WU (len);
- if (len)
- for (unsigned ix = 0; ix != len; ix++)
- {
- const constructor_elt &elt = (*t->constructor.elts)[ix];
-
- WT (elt.index);
- WT (elt.value);
- }
- }
+ // This must be streamed /after/ we've streamed the type,
+ // because it can directly refer to elements of the type. Eg,
+ // FIELD_DECLs of a RECORD_TYPE.
break;
case OMP_CLAUSE:
@@ -6458,6 +6448,21 @@ trees_out::core_vals (tree t)
WU (prec);
}
+ if (TREE_CODE (t) == CONSTRUCTOR)
+ {
+ unsigned len = vec_safe_length (t->constructor.elts);
+ if (streaming_p ())
+ WU (len);
+ if (len)
+ for (unsigned ix = 0; ix != len; ix++)
+ {
+ const constructor_elt &elt = (*t->constructor.elts)[ix];
+
+ WT (elt.index);
+ WT (elt.value);
+ }
+ }
+
#undef WT
#undef WU
}
@@ -6717,18 +6722,7 @@ trees_in::core_vals (tree t)
break;
case CONSTRUCTOR:
- if (unsigned len = u ())
- {
- vec_alloc (t->constructor.elts, len);
- for (unsigned ix = 0; ix != len; ix++)
- {
- constructor_elt elt;
-
- RT (elt.index);
- RTU (elt.value);
- t->constructor.elts->quick_push (elt);
- }
- }
+ // Streamed after the node's type.
break;
case OMP_CLAUSE:
@@ -6901,6 +6895,20 @@ trees_in::core_vals (tree t)
t->typed.type = type;
}
+ if (TREE_CODE (t) == CONSTRUCTOR)
+ if (unsigned len = u ())
+ {
+ vec_alloc (t->constructor.elts, len);
+ for (unsigned ix = 0; ix != len; ix++)
+ {
+ constructor_elt elt;
+
+ RT (elt.index);
+ RTU (elt.value);
+ t->constructor.elts->quick_push (elt);
+ }
+ }
+
#undef RT
#undef RM
#undef RU
diff --git a/gcc/testsuite/g++.dg/modules/decltype-1_a.C b/gcc/testsuite/g++.dg/modules/decltype-1_a.C
new file mode 100644
index 000000000000..ca66e8b598a7
--- /dev/null
+++ b/gcc/testsuite/g++.dg/modules/decltype-1_a.C
@@ -0,0 +1,28 @@
+// PR c++/105322
+// { dg-module-do link
+// { dg-additional-options -fmodules-ts }
+// { dg-module-cmi pr105322.Decltype }
+
+export module pr105322.Decltype;
+
+auto f() {
+ struct A { int m;
+ int get () { return m; }
+ };
+ return A{};
+}
+
+export
+inline void g1() {
+ auto r = decltype(f()){0};
+}
+
+export
+inline void g2() {
+ auto r = f().m;
+}
+
+export
+inline void g3() {
+ auto r = f().get();
+}
diff --git a/gcc/testsuite/g++.dg/modules/decltype-1_b.C b/gcc/testsuite/g++.dg/modules/decltype-1_b.C
new file mode 100644
index 000000000000..6bebe13604f6
--- /dev/null
+++ b/gcc/testsuite/g++.dg/modules/decltype-1_b.C
@@ -0,0 +1,10 @@
+// PR c++/105322
+// { dg-additional-options -fmodules-ts }
+
+import pr105322.Decltype;
+
+int main() {
+ g1();
+ g2();
+ g3();
+}
diff --git a/gcc/testsuite/g++.dg/modules/lambda-5_a.C b/gcc/testsuite/g++.dg/modules/lambda-5_a.C
new file mode 100644
index 000000000000..6b589d4965cf
--- /dev/null
+++ b/gcc/testsuite/g++.dg/modules/lambda-5_a.C
@@ -0,0 +1,24 @@
+// PR c++/105322
+// { dg-module-do link
+// { dg-additional-options -fmodules-ts }
+// { dg-module-cmi pr105322.Lambda }
+
+export module pr105322.Lambda;
+
+struct A { };
+
+export
+inline void f1() {
+ A a;
+ auto g1 = [a] { }; // used to ICE here during stream out
+}
+
+export
+template<class...>
+void f2() {
+ A a;
+ auto g2 = [a] { };
+}
+
+export
+inline auto g3 = [a=A{}] { };
diff --git a/gcc/testsuite/g++.dg/modules/lambda-5_b.C b/gcc/testsuite/g++.dg/modules/lambda-5_b.C
new file mode 100644
index 000000000000..a7ce70988352
--- /dev/null
+++ b/gcc/testsuite/g++.dg/modules/lambda-5_b.C
@@ -0,0 +1,10 @@
+// PR c++/105322
+// { dg-additional-options -fmodules-ts }
+
+import pr105322.Lambda;
+
+int main() {
+ f1();
+ f2();
+ g3();
+}
^ permalink raw reply [flat|nested] only message in thread
only message in thread, other threads:[~2023-10-20 20:25 UTC | newest]
Thread overview: (only message) (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2023-10-20 20:25 [gcc r14-4806] c++: Constructor streaming [PR105322] Nathan Sidwell
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).