-
-
Notifications
You must be signed in to change notification settings - Fork 3.1k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Fails to compile with operator<< available for equality test types in Clang, but not GCC #1403
Comments
I suspect the bug has to do with Clang being more strict about violations of using an overload in a template before the overload has been declared; that is, inside Catch2 there is a template that uses a not-yet-declared Catch2 function overload dependent on user types; the declaration happens afterwards, GCC incorrectly accepts it, but Catch2 correctly does not. |
Guys, I think you may have a very serious error, here is why: #include <internal/catch_stream.h>
#include <catch.hpp> The problem goes away. That means:
I think your It seems you are doing some SFINAE on template<typename T>
auto operator << ( T const& value ) -> ReusableStringStream& {
*m_oss << value;
return *this;
} |
Minimal example, at the compiler explorer: #include <array>
#include <iosfwd>
template<typename T, std::size_t L>
std::ostream &operator<<(std::ostream &, const std::array<T, L> &);
// Inclusion of internal/catch_stream.h ahead is a fix
// #include <internal/catch_stream.h>
#include <catch.hpp>
namespace Catch {
void triggerBug(ReusableStringStream &rss, std::array<int, 1> a) {
rss << a;
}
} |
I spent a bunch of time figuring out this issue, here's what I got: #include <array>
#include <iosfwd>
// non-template
std::ostream &operator<<(std::ostream &, const std::array<int, 1> &);
template<std::size_t L>
std::ostream &operator<<(std::ostream &, const std::array<long, L> &);
// resembles #include <internal/catch_common.h>
namespace Catch {
struct SourceLineInfo;
// introduces an overload of operator<< into namespace Catch
void operator<<(std::ostream &, SourceLineInfo const &);
}
// resembles #include <internal/catch_stream.h>
namespace Catch {
struct HasOperator {
std::ostream *m_;
public:
template<typename T>
void operator<<(const T &v) {
*m_ << v;
}
};
}
// done in #include <internal/catch_tostring.h>
namespace Catch {
using ::operator<<;
}
namespace Catch {
void usesGlobalNonTemplateOperator(HasOperator &rss, std::array<int, 1> a) {
rss.operator<<(a);
}
void usesGlobalTemplate(HasOperator &rss, std::array<long, 1> a) {
rss.operator<<(a);
}
}
void ok(std::ostream &o, std::array<long, 1> a) {
o << a;
} The introduction of the overload of |
Given a valid overload of
operator<<
as in this code:Fails to compile with recent versions of Clang:
It can be reproduced in the compiler explorer:
https://gcc.godbolt.org/z/Wkwab4
Originally I was using Clang 7.0.0 on Mac Os X
The text was updated successfully, but these errors were encountered: