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

            Bug ID: 64816
           Summary: gcc claims that constructor is private when it should
                    be accessible
           Product: gcc
           Version: unknown
            Status: UNCONFIRMED
          Severity: normal
          Priority: P3
         Component: c++
          Assignee: unassigned at gcc dot gnu.org
          Reporter: thakis at chromium dot org

I came across this while trying to build chromium for android with libc++ and
gcc. Here's an attempt at a reduction:


$ cat repro2.cc
namespace std {

template <class _Iter> class __wrap_iter {
private:
  __wrap_iter(_Iter __x) {}

  template <class _CharT> friend class basic_string;
  template <class _Tp> friend class vector;
};

template <class _CharT> class basic_string {
public:
  typedef const char *const_pointer;
  typedef __wrap_iter<const_pointer> const_iterator;

  const_iterator begin() const {return const_iterator(const_pointer(0));}
};
typedef basic_string<char> string;

template <class _Tp> class vector {
public:
  typedef const _Tp *const_pointer;
  typedef __wrap_iter<const_pointer> const_iterator;

  const_iterator begin() const {return const_iterator(const_pointer(0));}
};

} // namespace std

void g(const std::vector<char> &v) { v.begin(); }

# gcc doesn't like this (also broken in 4.4 and 4.9):
$ gcc-4.8.1 -c repro2.cc 
gcc-4.8.1: warning: couldn’t understand kern.osversion ‘14.0.0
repro2.cc: In instantiation of ‘std::vector<_Tp>::const_iterator
std::vector<_Tp>::begin() const [with _Tp = char;
std::vector<_Tp>::const_iterator = std::__wrap_iter<const char*>]’:
repro2.cc:30:46:   required from here
repro2.cc:5:3: error: ‘std::__wrap_iter<_Iter>::__wrap_iter(_Iter) [with _Iter
= const char*]’ is private
   __wrap_iter(_Iter __x) {}
   ^
repro2.cc:25:71: error: within this context
   const_iterator begin() const {return const_iterator(const_pointer(0));}
                                                                       ^

It's true that the constructor is private, but vector is also a friend.

clang likes it (icc too):

$ bin/clang -c repro2.cc


To make this more mysterious, gcc stops rejecting the problem if:

1.) I change `typedef const char *const_pointer;` to `typedef const _CharT
*const_pointer;`

2.) or I declare `template <class _Tp> class vector;` before class __wrap_iter

3.) or I remove class basic_string (and typedef string) -- even though they
aren't referenced anywhere.

Reply via email to