From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: by sourceware.org (Postfix, from userid 1059) id A72503858C50; Fri, 20 Oct 2023 20:25:08 +0000 (GMT) DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org A72503858C50 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gcc.gnu.org; s=default; t=1697833508; bh=o7Wq3WpM67LhGYnGi1bV0L+WkSx8HMdPckFUGvCzivA=; h=From:To:Subject:Date:From; b=u9wlkFH3HPTK/N5qMLNWiS+2cSf1yflUpvdPn7i1AxfaB5IiWJWJH4xMLO0VvqOLE G89ZjVBb//el+mGwghj67ivFkSECT+4udVLtaVruAZsHhOaIVOn5Q61xNiBqilPdCf 1VhCW5ZArmLRCO7ezbSxuOQ+507A3uGRny3YpRTs= MIME-Version: 1.0 Content-Transfer-Encoding: 7bit Content-Type: text/plain; charset="utf-8" From: Nathan Sidwell To: gcc-cvs@gcc.gnu.org Subject: [gcc r14-4806] c++: Constructor streaming [PR105322] X-Act-Checkin: gcc X-Git-Author: Nathan Sidwell X-Git-Refname: refs/heads/master X-Git-Oldrev: 7069ea909f5292a17d22e5e68218373186820d29 X-Git-Newrev: 084addf8a700fab9222d4127ab8524920d0ca481 Message-Id: <20231020202508.A72503858C50@sourceware.org> Date: Fri, 20 Oct 2023 20:25:08 +0000 (GMT) List-Id: https://gcc.gnu.org/g:084addf8a700fab9222d4127ab8524920d0ca481 commit r14-4806-g084addf8a700fab9222d4127ab8524920d0ca481 Author: Nathan Sidwell 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 +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(); +}