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
> 

Reply via email to