Bug 87652 - [8 Regression] inner class template of outer class template can't access friend's protected data member
Summary: [8 Regression] inner class template of outer class template can't access frie...
Status: RESOLVED FIXED
Alias: None
Product: gcc
Classification: Unclassified
Component: c++ (show other bugs)
Version: 8.2.0
: P2 normal
Target Milestone: 8.4
Assignee: Not yet assigned to anyone
URL:
Keywords: ice-on-valid-code, rejects-valid
Depends on: 86747
Blocks:
  Show dependency treegraph
 
Reported: 2018-10-19 05:04 UTC by Ryan R Haining
Modified: 2020-02-26 18:24 UTC (History)
3 users (show)

See Also:
Host:
Target:
Build:
Known to work: 7.3.0, 9.0
Known to fail: 8.1.0, 8.2.0, 8.2.1, 9.0
Last reconfirmed: 2018-10-19 00:00:00


Attachments

Note You need to log in before you can comment on or make changes to this bug.
Description Ryan R Haining 2018-10-19 05:04:51 UTC
#### Example program ####

template <typename>
struct Outer {
  template <typename>
  class Inner {
    template <typename>
    friend class Inner; // All Inners should be friends

   public:
     template <typename T>
     void use_other_x(const Inner<T>& other) const {
       (void)other.x; // should be fine, we're all friends
     }
   private: // no error if private instead
     int x;
  };
};

int main() {
  Outer<int>::Inner<void> i1;
  Outer<int>::Inner<char> i2;
  i1.use_other_x(i2);
}

#### Error message ####

prog.cc: In instantiation of 'void Outer< <template-parameter-1-1> >::Inner< <template-parameter-2-1> >::use_other_x(const Outer< <template-parameter-1-1> >::Inner<T>&) const [with T = char; <template-parameter-2-1> = void; <template-parameter-1-1> = int]':
prog.cc:21:20:   required from here
prog.cc:11:20: error: 'int Outer<int>::Inner<char>::x' is protected within this context
        (void)other.x;
              ~~~~~~^
prog.cc:14:10: note: declared protected here
      int x;


#### Notes ####

No problems observed when using private: instead of protected:
Comment 1 Ryan R Haining 2018-10-19 05:07:46 UTC
ugh, very sorry, I copied the version with private: instead of protected. The example program should be:

template <typename>
struct Outer {
  template <typename>
  class Inner {
    template <typename>
    friend class Inner; // All Inners should be friends

   public:
     template <typename T>
     void use_other_x(const Inner<T>& other) const {
       (void)other.x;
     }
   protected: // no error if private instead
     int x;
  };
};

int main() {
  Outer<int>::Inner<void> i1;
  Outer<int>::Inner<char> i2;
  i1.use_other_x(i2);
}
Comment 2 Jonathan Wakely 2018-10-19 12:18:43 UTC
Compiled OK with r255779, started to ICE with r255780. The ICE seems to be fixed on gcc-8-branch but not on trunk.
Comment 3 Jonathan Wakely 2018-10-19 12:21:11 UTC
(In reply to Jonathan Wakely from comment #2)
> The ICE seems to be fixed on gcc-8-branch

But is rejects-valid on the branch, instead of ice-on-valid-code on trunk.
Comment 4 Ryan R Haining 2019-01-06 21:54:13 UTC
working on head: https://wandbox.org/permlink/4dCLIfaIPWij81Vi
Comment 5 Jonathan Wakely 2019-01-06 22:51:36 UTC
But not fixed on gcc-8-branch, so it should be kept open until the regression is fixed.

Started to compile with r266875, which fixed:

    [PR86747] tsubst friend tpl ctxt before looking it up for dupes

Possibly a dup of that one. It might get fixed when that is backported to gcc-8-branch.
Comment 6 Jakub Jelinek 2019-02-22 15:20:10 UTC
GCC 8.3 has been released.
Comment 7 Ryan R Haining 2019-04-18 19:50:01 UTC
Still fails in 8.3.0 https://wandbox.org/permlink/69kAYkUWgFD5TTxs
Comment 8 Jason Merrill 2020-02-26 18:24:18 UTC
Fixed for 8.4.