https://gcc.gnu.org/bugzilla/show_bug.cgi?id=87571

            Bug ID: 87571
           Summary: [8/9 Regression] ICE in friend_accessible_p, accessing
                    protected member of template friend inside template
                    class
           Product: gcc
           Version: 9.0
            Status: UNCONFIRMED
          Severity: normal
          Priority: P3
         Component: c++
          Assignee: unassigned at gcc dot gnu.org
          Reporter: Francois-R.Boyer at PolyMtl dot ca
  Target Milestone: ---

The following code fails to compile with g++ 8.1, 8.2 and 9.0.0 20181007 on
godbolt, but compiles with g++ 7.3, clang, MSVC, etc.:

template <class> struct A {
  template <class> struct B {
    template <class> friend class B;
  protected:
    int protected_member_;
  public:
    template <class T> int method(const B<T>& other) const {
      return other.protected_member_;
    }
  };
};

int main() {
  A<int>::B<int> a;
  A<int>::B<char> b;
  a.method(b);
}

The error message is:
<source>: In instantiation of 'int A< <template-parameter-1-1> >::B<
<template-parameter-2-1> >::method(const A< <template-parameter-1-1> >::B<T>&)
const [with T = char; <template-parameter-2-1> = int; <template-parameter-1-1>
= int]':
<source>:16:13:   required from here
<source>:8:20: internal compiler error: in friend_accessible_p, at
cp/search.c:719
8 |       return other.protected_member_;
  |              ~~~~~~^~~~~~~~~~~~~~~~~


Note that it compiles if we change any of these:
- the member is private instead of protected,
- struct A is not a template, or
- we explicitly 'friend class B<int>;' instead or in addition of the template
friend.

Reply via email to