]> git.ipfire.org Git - thirdparty/gcc.git/commitdiff
c++/modules: Support streaming new size cookie for constexpr [PR120040]
authorNathaniel Shead <nathanieloshead@gmail.com>
Tue, 20 May 2025 13:09:07 +0000 (23:09 +1000)
committerNathaniel Shead <nathanieloshead@gmail.com>
Fri, 27 Jun 2025 14:34:59 +0000 (00:34 +1000)
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 <nathanieloshead@gmail.com>
Reviewed-by: Jason Merrill <jason@redhat.com>
gcc/cp/constexpr.cc
gcc/cp/init.cc
gcc/cp/module.cc
gcc/testsuite/g++.dg/modules/pr120040_a.C [new file with mode: 0644]
gcc/testsuite/g++.dg/modules/pr120040_b.C [new file with mode: 0644]

index 707883955b10a65871aab4f5ab977a6146487dc2..1dd8371de2514d1f177c324872bd12d8a2fa0e70 100644 (file)
@@ -8618,7 +8618,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)
+               && TYPE_IDENTIFIER (elt_type) == heap_identifier)
              {
                tree fld1 = TYPE_FIELDS (elt_type);
                tree fld2 = DECL_CHAIN (fld1);
index 80a37a14a80668acfc19028fba5273aeff340bbf..0a389fb6ecde43f0255110fe9e01f577b5bfaa59 100644 (file)
@@ -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;
 }
 
index 3e77d6ffde52c35ffcb86d29932e42438d0fa46d..e5fb1c36e9d283eb31e2556c257aeed147b0f567 100644 (file)
@@ -9366,6 +9366,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)
     {
@@ -9444,6 +9445,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 (file)
index 0000000..77e1689
--- /dev/null
@@ -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 (file)
index 0000000..e4610b0
--- /dev/null
@@ -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());
+}