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