googletest icon indicating copy to clipboard operation
googletest copied to clipboard

Including header with overloaded std::ostream& operator<<(std::ostream&, typename T) causes build failure on gcc 10.2

Open jralls opened this issue 4 years ago • 7 comments

Describe the bug

Build fails:

In file included from /home/john/googletest/googletest/include/gtest/gtest.h:58,
                 from /home/john/gnucash-git/libgnucash/engine/test/gtest-gnc-rational.cpp:24:
/usr/include/c++/10.2.0/ostream:773: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&)’
  773 |     operator<<(_Ostream&& __os, const _Tp& __x)
      |     ^~~~~~~~
/usr/include/c++/10.2.0/ostream:773:5: note:   template argument deduction/substitution failed:
/usr/include/c++/10.2.0/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 = std::basic_ostream<char>&; _Tp = std::type_index]’:
/home/john/googletest/googletest/include/gtest/gtest-printers.h:216:33:   required from ‘void testing::internal::PrintWithFallback(const T&, std::ostream*) [with T = std::type_index; std::ostream = std::basic_ostream<char>]’
/home/john/googletest/googletest/include/gtest/gtest-printers.h:446:30:   required from ‘void testing::internal::PrintTo(const T&, std::ostream*) [with T = std::type_index; std::ostream = std::basic_ostream<char>]’
/home/john/googletest/googletest/include/gtest/gtest-printers.h:682:49:   required from here
/usr/include/c++/10.2.0/ostream:773:5: error: no type named ‘type’ in ‘struct std::enable_if<false, std::basic_ostream<char>&>’
In file included from /home/john/googletest/googletest/include/gtest/internal/gtest-internal.h:57,
                 from /home/john/googletest/googletest/include/gtest/gtest.h:62,
                 from /home/john/gnucash-git/libgnucash/engine/test/gtest-gnc-rational.cpp:24:
/home/john/googletest/googletest/include/gtest/gtest-printers.h: In instantiation of ‘void testing::internal::PrintWithFallback(const T&, std::ostream*) [with T = std::type_index; std::ostream = std::basic_ostream<char>]’:
/home/john/googletest/googletest/include/gtest/gtest-printers.h:446:30:   required from ‘void testing::internal::PrintTo(const T&, std::ostream*) [with T = std::type_index; std::ostream = std::basic_ostream<char>]’
/home/john/googletest/googletest/include/gtest/gtest-printers.h:682:49:   required from here
/usr/include/c++/10.2.0/iomanip:79:5: note: candidate: ‘template<class _CharT, class _Traits> std::basic_ostream<_Ch, _Tr>& std::operator<<(std::basic_ostream<_Ch, _Tr>&, std::_Resetiosflags)’
   79 |     operator<<(basic_ostream<_CharT, _Traits>& __os, _Resetiosflags __f)
      |     ^~~~~~~~
/usr/include/c++/10.2.0/iomanip:79:5: note:   template argument deduction/substitution failed:
In file included from /home/john/googletest/googletest/include/gtest/gtest-matchers.h:44,
                 from /home/john/googletest/googletest/include/gtest/internal/gtest-death-test-internal.h:39,
                 from /home/john/googletest/googletest/include/gtest/gtest-death-test.h:41,
                 from /home/john/googletest/googletest/include/gtest/gtest.h:64,
                 from /home/john/gnucash-git/libgnucash/engine/test/gtest-gnc-rational.cpp:24:
/home/john/googletest/googletest/include/gtest/gtest-printers.h:216:33: note:   cannot convert ‘std::declval<const std::type_index&>()’ (type ‘const std::type_index’) to type ‘std::_Resetiosflags’
  215 |             typename = decltype(std::declval<std::ostream&>()
      |                                 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  216 |                                 << std::declval<const T&>())>
      |                                 ^~~~~~~~~~~~~~~~~~~~~~~~~~~

Followed by a long list of SFINAE failure messages for every other overload of operator<<.

Steps to reproduce the bug

Get https://raw.githubusercontent.com/Gnucash/gnucash/maint/libgnucash/engine/gnc-int128.hpp Create the following gtest-test.cpp:

#include <gtest/gtest.h>
#include <engine/gnc-int128.hpp>


int main()
{
    GncInt128 f;
    std::cout << f << std::endl;
}

compile with

g++ -I googletest/googletest/include/  gtest-test.cpp

Making any adjustments needed to find the two includes.

Commenting out line 279

std::ostream& operator<< (std::ostream&, const GncInt128&) noexcept;

will allow the compilation to succeed.

Does the bug persist in the most recent commit?

Yes.

What operating system and version are you using?

Arch Linux, fully updated yesterday. The problem was first discovered using Ubuntu 21.04 with their packaged googletest.

The problem does not reproduce on macOS 11.2 with Xcode 12.3's clang.

What compiler and version are you using?

$ gcc -v Using built-in specs. COLLECT_GCC=gcc COLLECT_LTO_WRAPPER=/usr/lib/gcc/x86_64-pc-linux-gnu/10.2.0/lto-wrapper Target: x86_64-pc-linux-gnu Configured with: /build/gcc/src/gcc/configure --prefix=/usr --libdir=/usr/lib --libexecdir=/usr/lib --mandir=/usr/share/man --infodir=/usr/share/info --with-bugurl=https://bugs.archlinux.org/ --enable-languages=c,c++,ada,fortran,go,lto,objc,obj-c++,d --with-isl --with-linker-hash-style=gnu --with-system-zlib --enable-__cxa_atexit --enable-cet=auto --enable-checking=release --enable-clocale=gnu --enable-default-pie --enable-default-ssp --enable-gnu-indirect-function --enable-gnu-unique-object --enable-install-libiberty --enable-linker-build-id --enable-lto --enable-multilib --enable-plugin --enable-shared --enable-threads=posix --disable-libssp --disable-libstdcxx-pch --disable-libunwind-exceptions --disable-werror gdc_include_dir=/usr/include/dlang/gdc Thread model: posix Supported LTO compression algorithms: zlib zstd gcc version 10.2.0 (GCC) What build system are you using?

N/A

Additional context

I have bisected the problem, it is caused by commit ac3c2a8d0496893787015014a5abd397b766cce2 "overload PrintTo for std::type_info and std::type_index" and reverting it allows compilation to complete normally.

jralls avatar Apr 24 '21 19:04 jralls

Here's a godbolt demonstrating the problem. Note that I've ifdefed out everything except the constructors and the overloaded operator<<.

jralls avatar Apr 24 '21 22:04 jralls

Thank you for reporting this issue so extensively, John. I seen now, it appears reproducible, even without using GncInt128, by:

#include <gtest/gtest-printers.h>
#include <iosfwd>

struct Foo {
    template <typename T> Foo(T);
};
void operator<<(std::ostream&, const Foo&);

https://godbolt.org/z/d3MKb1cKd

N-Dekker avatar Apr 25 '21 20:04 N-Dekker

Thanks for reporting! We'll revert https://github.com/google/googletest/commit/ac3c2a8d0496893787015014a5abd397b766cce2.

dinord avatar Apr 26 '21 14:04 dinord

@dinord Would it still make sense to you to look what goes on here? Is it a compiler bug? Could there be a workaround?

Commit ac3c2a8d0496893787015014a5abd397b766cce2 (pull request #3184) simply just adds two PrintTo overloads. Wasn't the whole idea of PrintTo that it could be customized for specific types by adding overloads?

N-Dekker avatar Apr 26 '21 15:04 N-Dekker

@N-Dekker Sure, but I'd prefer to revert first in order to unblock users building from head.

dinord avatar Apr 26 '21 15:04 dinord

I tried the Intel and Microsoft compilers on godbolt and they both compiled the code without error; I already noted that clang does too. That surely suggests that there's at least a difference with gcc so it's worth trying to get the gcc devs to look at it.

jralls avatar Apr 26 '21 15:04 jralls

Pending PR fixing this (for visibility): https://github.com/google/googletest/pull/3993

dev0x13 avatar Nov 21 '22 10:11 dev0x13