googletest
googletest copied to clipboard
GCC 11 enum class operator<< overload in a namespace doesn't work in INSTANTIATE_TEST_SUITE_P
Describe the bug
See the code in the next section. It works well in Ubuntu 20.04 (GCC 9.4.0 and libgtest-dev from apt source), but it doesn't work on Ubuntu 22.04 (GCC 11.3.0 and libgtest-dev from the apt source).
Steps to reproduce the bug
#include <gtest/gtest.h>
#include <iostream>
namespace xyz {
enum class Color
{
RED,
GREEN
};
} // namespace xyz
std::ostream& operator<<(std::ostream& os, const xyz::Color& color);
class ColorTest : public testing::TestWithParam<xyz::Color> {};
TEST_P(ColorTest, test) {}
INSTANTIATE_TEST_SUITE_P(Test, ColorTest, testing::Values(xyz::Color::RED, xyz::Color::GREEN));
int main(int argc, char* argv[]) {
testing::InitGoogleTest(&argc, argv);
return RUN_ALL_TESTS();
}
std::ostream& operator<<(std::ostream& os, const xyz::Color& color) {
return (os << (static_cast<int>(color) + 100));
}
Install g++ and libgtest-dev inside a ubuntu:22.04 docker container. Then compile the code above with:
g++ main.cc /usr/lib/x86_64-linux-gnu/libgtest.a -pthread
Does the bug persist in the most recent commit?
Not verified yet.
What operating system and version are you using?
The ubuntu:22.04 docker container.
What compiler and version are you using?
g++ (Ubuntu 11.3.0-1ubuntu1~22.04) 11.3.0
Copyright (C) 2021 Free Software Foundation, Inc.
This is free software; see the source for copying conditions. There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
What build system are you using?
Additional context
There are various workarounds.
- Removing the namespace.
5,6d4
< namespace xyz {
<
13,15c11
< } // namespace xyz
<
< std::ostream& operator<<(std::ostream& os, const xyz::Color& color);
---
> std::ostream& operator<<(std::ostream& os, const Color& color);
17c13
< class ColorTest : public testing::TestWithParam<xyz::Color> {};
---
> class ColorTest : public testing::TestWithParam<Color> {};
21c17
< INSTANTIATE_TEST_SUITE_P(Test, ColorTest, testing::Values(xyz::Color::RED, xyz::Color::GREEN));
---
> INSTANTIATE_TEST_SUITE_P(Test, ColorTest, testing::Values(Color::RED, Color::GREEN));
28c24
< std::ostream& operator<<(std::ostream& os, const xyz::Color& color) {
---
> std::ostream& operator<<(std::ostream& os, const Color& color) {
- Use
enuminstead ofenum class
7c7
< enum class Color
---
> enum Color
Adding an inline overload also works:
16a17,20
> inline std::ostream& operator<<(std::ostream& os, xyz::Color color) {
> return (os << static_cast<int>(color));
> }
>
However, it's an ambiguous overload. If we use GetParam() in the test body, the compilation will fail.
TEST_P(ColorTest, test) { std::cout << GetParam() << std::endl; }
I tried building the master with GCC 9, it also works.
@BewareMyPower is it known which version of gtest introduces and fixes this?
I don't know.