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

            Bug ID: 90925
           Summary: gcc allows calling private overridden operators
           Product: gcc
           Version: 10.0
            Status: UNCONFIRMED
          Severity: normal
          Priority: P3
         Component: c++
          Assignee: unassigned at gcc dot gnu.org
          Reporter: zhonghao at pku dot org.cn
  Target Milestone: ---

My gcc is 10.0.0, and my code is:

class a {
 private: template <typename b> a &operator<<(b);
};
a c();
template <typename> a fn2() {
 int d;
 return c() << d;
}

gcc accepts the code, but clang rejects it:

 error: 'operator<<' is a private member of 'a'
  return c() << d;
         ~~~ ^  ~
 note: implicitly declared private here
  template <typename b> a &operator<<(b);
                           ^
1 error generated.

BTW, I constructed a related code sample:

#include<iostream>
using namespace std;
class A
{
public:
    A():value(0){cout<<"i am gouzao"<<endl;}
    A(A&):value(0){cout<<"i am gouzao"<<endl;};
    ~A(){cout<<"xigou"<<endl;}
    A& operator++()
    {
    cout<<"++A"<<endl;
    ++value;
    return *this;
    }  
    void show()
    {
    cout<<"value:"<<value<<endl;
    }
private:
  const template <typename b>  &operator++(int)
    {
    cout<<"A++"<<endl;
    A tmp=*this;
    value++;
    return tmp;
    }
private:
    int value;
};
int main()
{
    A a;
    a<<1;
    a.show();

    a.show();
    return 0;
}

The error message of gcc contains some internal messages, which can be removed:

In file included from /usr/include/c++/7/string:52:0,
                 from /usr/include/c++/7/bits/locale_classes.h:40,
                 from /usr/include/c++/7/bits/ios_base.h:41,
                 from /usr/include/c++/7/ios:42,
                 from /usr/include/c++/7/ostream:38,
                 from /usr/include/c++/7/iostream:39,
                 from test.cpp:1:
/usr/include/c++/7/bits/basic_string.h:6284:5: note: candidate: template<class
_CharT, class _Traits, class _Alloc> std::basic_ostream<_CharT, _Traits>&
std::operator<<(std::basic_ostream<_CharT, _Traits>&, const
std::__cxx11::basic_string<_CharT, _Traits, _Alloc>&)
     operator<<(basic_ostream<_CharT, _Traits>& __os,
     ^~~~~~~~
/usr/include/c++/7/bits/basic_string.h:6284:5: note:   template argument
deduction/substitution failed:
test.cpp:33:8: note:   ‘A’ is not derived from ‘std::basic_ostream<_CharT,
_Traits>’
     a<<1;
        ^
In file included from /usr/include/c++/7/bits/ios_base.h:46:0,
                 from /usr/include/c++/7/ios:42,
                 from /usr/include/c++/7/ostream:38,
                 from /usr/include/c++/7/iostream:39,
                 from test.cpp:1:
/usr/include/c++/7/system_error:217:5: note: candidate: template<class _CharT,
class _Traits> std::basic_ostream<_CharT, _Traits>&
std::operator<<(std::basic_ostream<_CharT, _Traits>&, const std::error_code&)
     operator<<(basic_ostream<_CharT, _Traits>& __os, const error_code& __e)
     ^~~~~~~~
/usr/include/c++/7/system_error:217:5: note:   template argument
deduction/substitution failed:
test.cpp:33:8: note:   ‘A’ is not derived from ‘std::basic_ostream<_CharT,
_Traits>’
     a<<1;
        ^
In file included from /usr/include/c++/7/iostream:39:0,
                 from test.cpp:1:
/usr/include/c++/7/ostream:497:5: note: candidate: template<class _CharT, class
_Traits> std::basic_ostream<_CharT, _Traits>&
std::operator<<(std::basic_ostream<_CharT, _Traits>&, _CharT)
     operator<<(basic_ostream<_CharT, _Traits>& __out, _CharT __c)
     ^~~~~~~~
/usr/include/c++/7/ostream:497:5: note:   template argument
deduction/substitution failed:
test.cpp:33:8: note:   ‘A’ is not derived from ‘std::basic_ostream<_CharT,
_Traits>’
     a<<1;
        ^
In file included from /usr/include/c++/7/iostream:39:0,
                 from test.cpp:1:
/usr/include/c++/7/ostream:502:5: note: candidate: template<class _CharT, class
_Traits> std::basic_ostream<_CharT, _Traits>&
std::operator<<(std::basic_ostream<_CharT, _Traits>&, char)
     operator<<(basic_ostream<_CharT, _Traits>& __out, char __c)
     ^~~~~~~~
/usr/include/c++/7/ostream:502:5: note:   template argument
deduction/substitution failed:
test.cpp:33:8: note:   ‘A’ is not derived from ‘std::basic_ostream<_CharT,
_Traits>’
     a<<1;
        ^
In file included from /usr/include/c++/7/iostream:39:0,
                 from test.cpp:1:
/usr/include/c++/7/ostream:508:5: note: candidate: template<class _Traits>
std::basic_ostream<char, _Traits>& std::operator<<(std::basic_ostream<char,
_Traits>&, char)
     operator<<(basic_ostream<char, _Traits>& __out, char __c)
     ^~~~~~~~
/usr/include/c++/7/ostream:508:5: note:   template argument
deduction/substitution failed:
test.cpp:33:8: note:   ‘A’ is not derived from ‘std::basic_ostream<char,
_Traits>’
     a<<1;
        ^
In file included from /usr/include/c++/7/iostream:39:0,
                 from test.cpp:1:
/usr/include/c++/7/ostream:514:5: note: candidate: template<class _Traits>
std::basic_ostream<char, _Traits>& std::operator<<(std::basic_ostream<char,
_Traits>&, signed char)
     operator<<(basic_ostream<char, _Traits>& __out, signed char __c)
     ^~~~~~~~
/usr/include/c++/7/ostream:514:5: note:   template argument
deduction/substitution failed:
test.cpp:33:8: note:   ‘A’ is not derived from ‘std::basic_ostream<char,
_Traits>’
     a<<1;
        ^
In file included from /usr/include/c++/7/iostream:39:0,
                 from test.cpp:1:
/usr/include/c++/7/ostream:519:5: note: candidate: template<class _Traits>
std::basic_ostream<char, _Traits>& std::operator<<(std::basic_ostream<char,
_Traits>&, unsigned char)
     operator<<(basic_ostream<char, _Traits>& __out, unsigned char __c)
     ^~~~~~~~
/usr/include/c++/7/ostream:519:5: note:   template argument
deduction/substitution failed:
test.cpp:33:8: note:   ‘A’ is not derived from ‘std::basic_ostream<char,
_Traits>’
     a<<1;
        ^
In file included from /usr/include/c++/7/iostream:39:0,
                 from test.cpp:1:
/usr/include/c++/7/ostream:539:5: note: candidate: template<class _CharT, class
_Traits> std::basic_ostream<_CharT, _Traits>&
std::operator<<(std::basic_ostream<_CharT, _Traits>&, const _CharT*)
     operator<<(basic_ostream<_CharT, _Traits>& __out, const _CharT* __s)
     ^~~~~~~~
/usr/include/c++/7/ostream:539:5: note:   template argument
deduction/substitution failed:
test.cpp:33:8: note:   ‘A’ is not derived from ‘std::basic_ostream<_CharT,
_Traits>’
     a<<1;
        ^
In file included from /usr/include/c++/7/ostream:693:0,
                 from /usr/include/c++/7/iostream:39,
                 from test.cpp:1:
/usr/include/c++/7/bits/ostream.tcc:321:5: note: candidate: template<class
_CharT, class _Traits> std::basic_ostream<_CharT, _Traits>&
std::operator<<(std::basic_ostream<_CharT, _Traits>&, const char*)
     operator<<(basic_ostream<_CharT, _Traits>& __out, const char* __s)
     ^~~~~~~~
/usr/include/c++/7/bits/ostream.tcc:321:5: note:   template argument
deduction/substitution failed:
test.cpp:33:8: note:   ‘A’ is not derived from ‘std::basic_ostream<_CharT,
_Traits>’
     a<<1;
        ^
In file included from /usr/include/c++/7/iostream:39:0,
                 from test.cpp:1:
/usr/include/c++/7/ostream:556:5: note: candidate: template<class _Traits>
std::basic_ostream<char, _Traits>& std::operator<<(std::basic_ostream<char,
_Traits>&, const char*)
     operator<<(basic_ostream<char, _Traits>& __out, const char* __s)
     ^~~~~~~~
/usr/include/c++/7/ostream:556:5: note:   template argument
deduction/substitution failed:
test.cpp:33:8: note:   ‘A’ is not derived from ‘std::basic_ostream<char,
_Traits>’
     a<<1;
        ^
In file included from /usr/include/c++/7/iostream:39:0,
                 from test.cpp:1:
/usr/include/c++/7/ostream:569:5: note: candidate: template<class _Traits>
std::basic_ostream<char, _Traits>& std::operator<<(std::basic_ostream<char,
_Traits>&, const signed char*)
     operator<<(basic_ostream<char, _Traits>& __out, const signed char* __s)
     ^~~~~~~~
/usr/include/c++/7/ostream:569:5: note:   template argument
deduction/substitution failed:
test.cpp:33:8: note:   ‘A’ is not derived from ‘std::basic_ostream<char,
_Traits>’
     a<<1;
        ^
In file included from /usr/include/c++/7/iostream:39:0,
                 from test.cpp:1:
/usr/include/c++/7/ostream:574:5: note: candidate: template<class _Traits>
std::basic_ostream<char, _Traits>& std::operator<<(std::basic_ostream<char,
_Traits>&, const unsigned char*)
     operator<<(basic_ostream<char, _Traits>& __out, const unsigned char* __s)
     ^~~~~~~~
/usr/include/c++/7/ostream:574:5: note:   template argument
deduction/substitution failed:
test.cpp:33:8: note:   ‘A’ is not derived from ‘std::basic_ostream<char,
_Traits>’
     a<<1;
        ^
In file included from /usr/include/c++/7/iostream:39:0,
                 from test.cpp:1:
/usr/include/c++/7/ostream:682:5: note: candidate: template<class _Ostream,
class _Tp> typename
std::enable_if<std::__and_<std::__not_<std::is_lvalue_reference<_Tp> >,
std::__is_convertible_to_basic_ostream<_Ostream>, std::__is_insertable<typename
std::__is_convertible_to_basic_ostream<_Tp>::__ostream_type, const _Tp&, void>
>::value, typename
std::__is_convertible_to_basic_ostream<_Tp>::__ostream_type>::type
std::operator<<(_Ostream&&, const _Tp&)
     operator<<(_Ostream&& __os, const _Tp& __x)
     ^~~~~~~~
/usr/include/c++/7/ostream:682:5: note:   template argument
deduction/substitution failed:
/usr/include/c++/7/ostream: In substitution of ‘template<class _Ostream, class
_Tp> typename
std::enable_if<std::__and_<std::__not_<std::is_lvalue_reference<_Tp> >,
std::__is_convertible_to_basic_ostream<_Ostream>, std::__is_insertable<typename
std::__is_convertible_to_basic_ostream<_Tp>::__ostream_type, const _Tp&, void>
>::value, typename
std::__is_convertible_to_basic_ostream<_Tp>::__ostream_type>::type
std::operator<<(_Ostream&&, const _Tp&) [with _Ostream = A&; _Tp = int]’:

Reply via email to