Ping.
On Thu, May 22, 2025 at 12:15:34PM +1000, Nathaniel Shead wrote: > This type currently has a DECL_NAME of an IDENTIFIER_DECL. Although the > documentation indicates this is legal, this confuses modules streaming > which expects all RECORD_TYPEs to have a TYPE_DECL, which is used to > determine the context and merge key, etc. > > PR c++/120040 > > gcc/cp/ChangeLog: > > * constexpr.cc (cxx_eval_constant_expression): Handle TYPE_NAME > now being a TYPE_DECL rather than just an IDENTIFIER_NODE. > * init.cc (build_new_constexpr_heap_type): Build a TYPE_DECL for > the returned type; mark the type as artificial. > * module.cc (trees_out::type_node): Add some assertions. > > gcc/testsuite/ChangeLog: > > * g++.dg/modules/pr120040_a.C: New test. > * g++.dg/modules/pr120040_b.C: New test. > > Signed-off-by: Nathaniel Shead <nathanielosh...@gmail.com> > --- > gcc/cp/constexpr.cc | 2 +- > gcc/cp/init.cc | 10 +++++++++- > gcc/cp/module.cc | 3 +++ > gcc/testsuite/g++.dg/modules/pr120040_a.C | 19 +++++++++++++++++++ > gcc/testsuite/g++.dg/modules/pr120040_b.C | 15 +++++++++++++++ > 5 files changed, 47 insertions(+), 2 deletions(-) > create mode 100644 gcc/testsuite/g++.dg/modules/pr120040_a.C > create mode 100644 gcc/testsuite/g++.dg/modules/pr120040_b.C > > diff --git a/gcc/cp/constexpr.cc b/gcc/cp/constexpr.cc > index fa754b9a176..ceb8f04fab4 100644 > --- a/gcc/cp/constexpr.cc > +++ b/gcc/cp/constexpr.cc > @@ -8613,7 +8613,7 @@ cxx_eval_constant_expression (const constexpr_ctx *ctx, > tree t, > tree cookie_size = NULL_TREE; > tree arg_size = NULL_TREE; > if (TREE_CODE (elt_type) == RECORD_TYPE > - && TYPE_NAME (elt_type) == heap_identifier) > + && DECL_NAME (TYPE_NAME (elt_type)) == heap_identifier) > { > tree fld1 = TYPE_FIELDS (elt_type); > tree fld2 = DECL_CHAIN (fld1); > diff --git a/gcc/cp/init.cc b/gcc/cp/init.cc > index 80a37a14a80..0a389fb6ecd 100644 > --- a/gcc/cp/init.cc > +++ b/gcc/cp/init.cc > @@ -3010,7 +3010,6 @@ build_new_constexpr_heap_type (tree elt_type, tree > cookie_size, tree itype2) > tree atype1 = build_cplus_array_type (sizetype, itype1); > tree atype2 = build_cplus_array_type (elt_type, itype2); > tree rtype = cxx_make_type (RECORD_TYPE); > - TYPE_NAME (rtype) = heap_identifier; > tree fld1 = build_decl (UNKNOWN_LOCATION, FIELD_DECL, NULL_TREE, atype1); > tree fld2 = build_decl (UNKNOWN_LOCATION, FIELD_DECL, NULL_TREE, atype2); > DECL_FIELD_CONTEXT (fld1) = rtype; > @@ -3019,7 +3018,16 @@ build_new_constexpr_heap_type (tree elt_type, tree > cookie_size, tree itype2) > DECL_ARTIFICIAL (fld2) = true; > TYPE_FIELDS (rtype) = fld1; > DECL_CHAIN (fld1) = fld2; > + TYPE_ARTIFICIAL (rtype) = true; > layout_type (rtype); > + > + tree decl = build_decl (UNKNOWN_LOCATION, TYPE_DECL, heap_identifier, > rtype); > + TYPE_NAME (rtype) = decl; > + TYPE_STUB_DECL (rtype) = decl; > + DECL_CONTEXT (decl) = NULL_TREE; > + DECL_ARTIFICIAL (decl) = true; > + layout_decl (decl, 0); > + > return rtype; > } > > diff --git a/gcc/cp/module.cc b/gcc/cp/module.cc > index ddb5299b244..765d17935c5 100644 > --- a/gcc/cp/module.cc > +++ b/gcc/cp/module.cc > @@ -9362,6 +9362,7 @@ trees_out::type_node (tree type) > > tree root = (TYPE_NAME (type) > ? TREE_TYPE (TYPE_NAME (type)) : TYPE_MAIN_VARIANT (type)); > + gcc_checking_assert (root); > > if (type != root) > { > @@ -9440,6 +9441,8 @@ trees_out::type_node (tree type) > || TREE_CODE (type) == UNION_TYPE > || TREE_CODE (type) == ENUMERAL_TYPE) > { > + gcc_checking_assert (DECL_P (name)); > + > /* We can meet template parms that we didn't meet in the > tpl_parms walk, because we're referring to a derived type > that was previously constructed from equivalent template > diff --git a/gcc/testsuite/g++.dg/modules/pr120040_a.C > b/gcc/testsuite/g++.dg/modules/pr120040_a.C > new file mode 100644 > index 00000000000..77e16892f4e > --- /dev/null > +++ b/gcc/testsuite/g++.dg/modules/pr120040_a.C > @@ -0,0 +1,19 @@ > +// PR c++/120040 > +// { dg-additional-options "-fmodules -std=c++20" } > +// { dg-module-cmi M } > + > +export module M; > + > +struct S { > + constexpr ~S() {} > +}; > + > +export constexpr bool foo() { > + S* a = new S[3]; > + delete[] a; > + return true; > +} > + > +export constexpr S* bar() { > + return new S[3]; > +} > diff --git a/gcc/testsuite/g++.dg/modules/pr120040_b.C > b/gcc/testsuite/g++.dg/modules/pr120040_b.C > new file mode 100644 > index 00000000000..e4610b07eaf > --- /dev/null > +++ b/gcc/testsuite/g++.dg/modules/pr120040_b.C > @@ -0,0 +1,15 @@ > +// PR c++/120040 > +// { dg-additional-options "-fmodules -std=c++20" } > + > +import M; > + > +constexpr bool qux() { > + auto* s = bar(); > + delete[] s; > + return true; > +} > + > +int main() { > + static_assert(foo()); > + static_assert(qux()); > +} > -- > 2.47.0 >