public inbox for gcc-bugs@sourceware.org
help / color / mirror / Atom feed
* [Bug c++/102995] New: Template friend class declaration of same class with different template parameters fails to allow private methods access
@ 2021-10-29  7:33 jdapena at igalia dot com
  2021-10-31  2:05 ` [Bug c++/102995] " pinskia at gcc dot gnu.org
                   ` (4 more replies)
  0 siblings, 5 replies; 6+ messages in thread
From: jdapena at igalia dot com @ 2021-10-29  7:33 UTC (permalink / raw)
  To: gcc-bugs

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

            Bug ID: 102995
           Summary: Template friend class declaration of same class with
                    different template parameters fails to allow private
                    methods access
           Product: gcc
           Version: 12.0
            Status: UNCONFIRMED
          Severity: normal
          Priority: P3
         Component: c++
          Assignee: unassigned at gcc dot gnu.org
          Reporter: jdapena at igalia dot com
  Target Milestone: ---

Created attachment 51698
  --> https://gcc.gnu.org/bugzilla/attachment.cgi?id=51698&action=edit
Test case

Declaring a template friend class to the same class fails to resolve the access
to private members in its methods.

The provided example fails with this error:

  $ g++ main.cc 
  main.cc: In instantiation of 'bool operator==(const First<A, B>&, const 
  First<C, B>&) [with C = void*; A = int; B = bool]':
  main.cc:23:15:   required from here
  main.cc:13:61: error: 'int First<A, B>::GetId() const [with A = void*; B = 
  bool]' is private within this context
     13 |                              return lhs.GetId() == rhs.GetId();
        |                                                    ~~~~~~~~~^~
  main.cc:6:9: note: declared private here
      6 |     int GetId() const {
        |         ^~~~~


The same case works in Clang  (verified with Clang 9.0.1).

This issue is exposed in Chromium, compiling base/raw_ptr.h unit tests on GCC.
I created a simplified version of the problem. See:

https://chromium.googlesource.com/chromium/src/base/+/821f1e481ce7c51d31486f26a74d343ffe4cf70e/memory/raw_ptr.h#496
(declaration of the method that should have friend access to rhs private
methods).

https://chromium.googlesource.com/chromium/src/base/+/821f1e481ce7c51d31486f26a74d343ffe4cf70e/memory/raw_ptr.h#584
(the friend class declaration).

https://chromium.googlesource.com/chromium/src/base/+/821f1e481ce7c51d31486f26a74d343ffe4cf70e/memory/raw_ptr_unittest.cc#328
(failing test compilation).

^ permalink raw reply	[flat|nested] 6+ messages in thread

* [Bug c++/102995] Template friend class declaration of same class with different template parameters fails to allow private methods access
  2021-10-29  7:33 [Bug c++/102995] New: Template friend class declaration of same class with different template parameters fails to allow private methods access jdapena at igalia dot com
@ 2021-10-31  2:05 ` pinskia at gcc dot gnu.org
  2021-10-31  2:15 ` pinskia at gcc dot gnu.org
                   ` (3 subsequent siblings)
  4 siblings, 0 replies; 6+ messages in thread
From: pinskia at gcc dot gnu.org @ 2021-10-31  2:05 UTC (permalink / raw)
  To: gcc-bugs

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

--- Comment #1 from Andrew Pinski <pinskia at gcc dot gnu.org> ---
Are you sure this is valid?  Both ICC and MSVC reject it for the same reason as
GCC.

Can a friend of First<A, B> be made a friend of First<B, C> via the friend, I
don't think so?

^ permalink raw reply	[flat|nested] 6+ messages in thread

* [Bug c++/102995] Template friend class declaration of same class with different template parameters fails to allow private methods access
  2021-10-29  7:33 [Bug c++/102995] New: Template friend class declaration of same class with different template parameters fails to allow private methods access jdapena at igalia dot com
  2021-10-31  2:05 ` [Bug c++/102995] " pinskia at gcc dot gnu.org
@ 2021-10-31  2:15 ` pinskia at gcc dot gnu.org
  2021-10-31  2:22 ` pinskia at gcc dot gnu.org
                   ` (2 subsequent siblings)
  4 siblings, 0 replies; 6+ messages in thread
From: pinskia at gcc dot gnu.org @ 2021-10-31  2:15 UTC (permalink / raw)
  To: gcc-bugs

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

--- Comment #2 from Andrew Pinski <pinskia at gcc dot gnu.org> ---
This works correctly on all compilers to do what you want it to do:
template<typename A, typename B> class First {
  public:
    First() = default;

  private:
    int GetId() const {
      return 1;
    }

    template<typename U, typename V, typename D>
    friend bool operator==(const First<U, V>& lhs,
                           const First<D, V>& rhs);
};
template<typename U, typename V, typename D>
bool operator==(const First<U, V>& lhs,
                const First<D, V>& rhs) {
                             return lhs.GetId() == rhs.GetId();
                           }

int main() {
  First<int, bool> a;
  First<void *, bool> b;

  return a == b;
}

Because you need the operator

I suspect the original testcase is invalid code and clang is incorrect in
accepting it.

^ permalink raw reply	[flat|nested] 6+ messages in thread

* [Bug c++/102995] Template friend class declaration of same class with different template parameters fails to allow private methods access
  2021-10-29  7:33 [Bug c++/102995] New: Template friend class declaration of same class with different template parameters fails to allow private methods access jdapena at igalia dot com
  2021-10-31  2:05 ` [Bug c++/102995] " pinskia at gcc dot gnu.org
  2021-10-31  2:15 ` pinskia at gcc dot gnu.org
@ 2021-10-31  2:22 ` pinskia at gcc dot gnu.org
  2021-11-02  9:18 ` jdapena at igalia dot com
  2023-11-16 15:58 ` ppalka at gcc dot gnu.org
  4 siblings, 0 replies; 6+ messages in thread
From: pinskia at gcc dot gnu.org @ 2021-10-31  2:22 UTC (permalink / raw)
  To: gcc-bugs

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

--- Comment #3 from Andrew Pinski <pinskia at gcc dot gnu.org> ---
(In reply to Andrew Pinski from comment #2)
> I suspect the original testcase is invalid code and clang is incorrect in
> accepting it.

You can limit the friendship to only the operator== that have the same second
template operand if you need to limit the friendship slightly more:
template<typename A, typename B> class First {
  public:
    First() = default;

  private:
    int GetId() const {
      return 1;
    }
    template<typename U, typename D>
    friend bool operator==(const First<U, B>& lhs,
                           const First<D, B>& rhs);
};
template<typename U, typename D, typename V>
bool operator==(const First<U, V>& lhs,
                const First<D, V>& rhs) {
                             return lhs.GetId() == rhs.GetId();
                           }
int main() {
  First<int, bool> a;
  First<void *, bool> b;

  return a == b;
}

^ permalink raw reply	[flat|nested] 6+ messages in thread

* [Bug c++/102995] Template friend class declaration of same class with different template parameters fails to allow private methods access
  2021-10-29  7:33 [Bug c++/102995] New: Template friend class declaration of same class with different template parameters fails to allow private methods access jdapena at igalia dot com
                   ` (2 preceding siblings ...)
  2021-10-31  2:22 ` pinskia at gcc dot gnu.org
@ 2021-11-02  9:18 ` jdapena at igalia dot com
  2023-11-16 15:58 ` ppalka at gcc dot gnu.org
  4 siblings, 0 replies; 6+ messages in thread
From: jdapena at igalia dot com @ 2021-11-02  9:18 UTC (permalink / raw)
  To: gcc-bugs

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

--- Comment #4 from Jose Dapena Paz <jdapena at igalia dot com> ---
Definitely the proposed approach fixes the issue in GCC. And it looks to me it
makes more sense (it looks to me the code in Chromium is reversing the expected
meaning of friend there).

I will propose a fix to Chromium to use same approach (just verified it works).

Before closing this ticket... Could anybody with more knowledge of the applying
rules in standard give me the reference? It would improve the commit to
actually refer to the standard reason why we will replace the code.

^ permalink raw reply	[flat|nested] 6+ messages in thread

* [Bug c++/102995] Template friend class declaration of same class with different template parameters fails to allow private methods access
  2021-10-29  7:33 [Bug c++/102995] New: Template friend class declaration of same class with different template parameters fails to allow private methods access jdapena at igalia dot com
                   ` (3 preceding siblings ...)
  2021-11-02  9:18 ` jdapena at igalia dot com
@ 2023-11-16 15:58 ` ppalka at gcc dot gnu.org
  4 siblings, 0 replies; 6+ messages in thread
From: ppalka at gcc dot gnu.org @ 2023-11-16 15:58 UTC (permalink / raw)
  To: gcc-bugs

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

Patrick Palka <ppalka at gcc dot gnu.org> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
                 CC|                            |ppalka at gcc dot gnu.org
   Target Milestone|---                         |13.0
             Status|UNCONFIRMED                 |RESOLVED
         Resolution|---                         |FIXED

--- Comment #5 from Patrick Palka <ppalka at gcc dot gnu.org> ---
Note GCC accepts the original testcase after r13-465-g4df735e01e3199 which
implements the proposed resolution of CWG1699 (which hasn't yet been formally
adopted AFAICT).

^ permalink raw reply	[flat|nested] 6+ messages in thread

end of thread, other threads:[~2023-11-16 15:58 UTC | newest]

Thread overview: 6+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2021-10-29  7:33 [Bug c++/102995] New: Template friend class declaration of same class with different template parameters fails to allow private methods access jdapena at igalia dot com
2021-10-31  2:05 ` [Bug c++/102995] " pinskia at gcc dot gnu.org
2021-10-31  2:15 ` pinskia at gcc dot gnu.org
2021-10-31  2:22 ` pinskia at gcc dot gnu.org
2021-11-02  9:18 ` jdapena at igalia dot com
2023-11-16 15:58 ` ppalka at gcc dot gnu.org

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).