Thanks, this looks right. Sigh templates can mess up ones mental invariants!

The test case should really be a foo_[ab].C kind, to test both sides of the
streaming. Bonus points for using the template after importing.  And you
need the dg-module-cmi annotation to check /and then delete/ the gcm file
produced.

nathan

On Thu, Sep 15, 2022, 22:16 Patrick Palka <ppa...@redhat.com> wrote:

> A couple of xtreme-header-* modules tests began ICEing in C++23 mode
> ever since r13-2650-g5d84a4418aa962 introduced into <ranges> the
> dependently scoped friend declaration
>
>   friend /* typename */ _OuterIter::value_type;
>
> ultimately because the streaming code assumes a TYPE_P friend must
> be a class type, but here it's a TYPENAME_TYPE, which doesn't have
> a TEMPLATE_INFO or CLASSTYPE_BEFRIENDING_CLASSES.  This patch tries
> to correct this in a minimal way.
>
> Tested on x86_64-pc-linux-gnu, does this look OK for trunk?
>
> gcc/cp/ChangeLog:
>
>         * module.cc (friend_from_decl_list): Don't consider
>         CLASSTYPE_TEMPLATE_INFO for a TYPENAME_TYPE friend.
>         (trees_in::read_class_def): Don't add to
>         CLASSTYPE_BEFRIENDING_CLASSES for a TYPENAME_TYPE friend.
>
> gcc/testsuite/ChangeLog:
>
>         * g++.dg/modules/typename-friend.C: New test.
> ---
>  gcc/cp/module.cc                               | 5 +++--
>  gcc/testsuite/g++.dg/modules/typename-friend.C | 9 +++++++++
>  2 files changed, 12 insertions(+), 2 deletions(-)
>  create mode 100644 gcc/testsuite/g++.dg/modules/typename-friend.C
>
> diff --git a/gcc/cp/module.cc b/gcc/cp/module.cc
> index f27f4d091e5..1a1ff5be574 100644
> --- a/gcc/cp/module.cc
> +++ b/gcc/cp/module.cc
> @@ -4734,7 +4734,8 @@ friend_from_decl_list (tree frnd)
>        if (TYPE_P (frnd))
>         {
>           res = TYPE_NAME (frnd);
> -         if (CLASSTYPE_TEMPLATE_INFO (frnd))
> +         if (CLASS_TYPE_P (frnd)
> +             && CLASSTYPE_TEMPLATE_INFO (frnd))
>             tmpl = CLASSTYPE_TI_TEMPLATE (frnd);
>         }
>        else if (DECL_TEMPLATE_INFO (frnd))
> @@ -12121,7 +12122,7 @@ trees_in::read_class_def (tree defn, tree
> maybe_template)
>             {
>               tree f = TREE_VALUE (friend_classes);
>
> -             if (TYPE_P (f))
> +             if (CLASS_TYPE_P (f))
>                 {
>                   CLASSTYPE_BEFRIENDING_CLASSES (f)
>                     = tree_cons (NULL_TREE, type,
> diff --git a/gcc/testsuite/g++.dg/modules/typename-friend.C
> b/gcc/testsuite/g++.dg/modules/typename-friend.C
> new file mode 100644
> index 00000000000..d8faf7955c3
> --- /dev/null
> +++ b/gcc/testsuite/g++.dg/modules/typename-friend.C
> @@ -0,0 +1,9 @@
> +// { dg-additional-options "-fmodules-ts" }
> +
> +export module x;
> +
> +template<class T>
> +struct A {
> +  friend typename T::type;
> +  friend void f(A) { }
> +};
> --
> 2.37.3.662.g36f8e7ed7d
>
>

Reply via email to