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

            Bug ID: 111018
           Summary: lexical interpretation of friendship rules depends on
                    whether the friend function has a definition
           Product: gcc
           Version: 14.0
            Status: UNCONFIRMED
          Severity: normal
          Priority: P3
         Component: c++
          Assignee: unassigned at gcc dot gnu.org
          Reporter: eric.niebler at gmail dot com
  Target Milestone: ---

Starting in gcc 12, transitive friendship is extended to friend functions that
are defined lexically within the body of the friend class. E.g.:


struct S;

struct T {
  friend struct S;
private:
  template <class T>
  static void foo(T) {}
};

struct S {
  template <class Self>
  friend auto bar(Self s) -> decltype(::T::foo(s)) { // (1)
    return ::T::foo(s);
  }
};

Prior to gcc-12, the commented line would have been rejected, but now it is
accepted. Great, it brings gcc in line with clang and is arguably more
sensible.

HOWEVER, it does NOT work if the friend function is merely declared but not
defined. For instance, this is still an error:

struct S;

struct T {
  friend struct S;
private:
  template <class T>
  static void foo(T) {}
};

struct S {
  template <class Self>
  friend auto bar(Self s) -> decltype(::T::foo(s)); // NO FN DEFINITION
};

int main() {
  S s;
  using T = decltype(bar(s)); // ERROR: T::foo is private
}


This is very confusing and inconsistent behavior.

See: https://godbolt.org/z/WT9P37Wba

Reply via email to