Package: g++-11
Version: 11.2.0-19
Severity: normal

Contrary to clang++, g++ does not honor "friend" statement when evaluating
template specialization

Here is a short example:
$ cat toto6.cpp 
#include <iostream>

struct X {
  template <class T, class U = void> struct check_is_map {
      static constexpr bool value = false;
  };
  
  template <class T>
  struct check_is_map<T, typename T::is_map> {
      static constexpr bool value = true;
  };
};

template <class T, class U = void> struct check_is_map {
    static constexpr bool value = false;
};

template <class T>
struct check_is_map<T, typename T::is_map> {
    static constexpr bool value = true;
};

struct Config {
    using is_map=void;
};

struct ConfigBis {
  private:
    template <typename T1, typename U1>
    friend struct check_is_map; // friend of the template
    friend struct X; // friend of the surrounding class
    using is_map=void;
};

int main()
{
        std::cerr << "VALUE (public): "
            << check_is_map<Config>::value
                  << std::endl;
        std::cerr << "VALUE (private+friend): "
            << check_is_map<ConfigBis>::value
                  << std::endl;
        std::cerr << "X::VALUE (public): "
            << X::check_is_map<Config>::value
                  << std::endl;
        std::cerr << "X::VALUE (private+friend): "
            << X::check_is_map<ConfigBis>::value
                  << std::endl;
}

$ clang++ -std=gnu++17 -Wall -Wextra toto6.cpp 
$ ./a.out 
VALUE (public): 1
VALUE (private+friend): 1
X::VALUE (public): 1
X::VALUE (private+friend): 1
$ g++ -std=gnu++17 -Wall -Wextra toto6.cpp 
$ ./a.out 
VALUE (public): 1
VALUE (private+friend): 0
X::VALUE (public): 1
X::VALUE (private+friend): 0

  Regards,
    Vincent


-- System Information:
Debian Release: bookworm/sid
  APT prefers stable-updates
  APT policy: (500, 'stable-updates'), (500, 'stable-security'), (500, 
'oldstable-updates'), (500, 'unstable'), (500, 'testing'), (500, 'stable'), 
(500, 'oldstable'), (1, 'experimental')
Architecture: amd64 (x86_64)
Foreign Architectures: i386, armel, mipsel

Kernel: Linux 5.16.0-6-amd64 (SMP w/4 CPU threads; PREEMPT)
Kernel taint flags: TAINT_OOT_MODULE
Locale: LANG=fr_FR.utf8, LC_CTYPE=fr_FR.utf8 (charmap=UTF-8), LANGUAGE not set
Shell: /bin/sh linked to /bin/dash
Init: systemd (via /run/systemd/system)

Versions of packages g++-11 depends on:
ii  gcc-11            11.2.0-19
ii  gcc-11-base       11.2.0-19
ii  libc6             2.33-7
ii  libgmp10          2:6.2.1+dfsg-3
ii  libisl23          0.24-2
ii  libmpc3           1.2.1-2
ii  libmpfr6          4.1.0-3
ii  libstdc++-11-dev  11.2.0-19
ii  libzstd1          1.4.10+dfsg-1
ii  zlib1g            1:1.2.11.dfsg-4

g++-11 recommends no packages.

Versions of packages g++-11 suggests:
pn  g++-11-multilib  <none>
ii  gcc-11-doc       11.2.0-1

-- no debconf information

Reply via email to