On 5/21/25 10:15 PM, 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)
This could be TYPE_IDENTIFIER. OK either way.
{
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());
+}