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).