We're seeing C++ code, that compiles successfully in GCC 11.3 and Visual Studio 2022, have issues with GCC 12.1. The code is on Compiler Explorer: https://godbolt.org/z/6PYEcsd1h (Thanks to @NathanPierson for simplifying it some.)
Basically, a template class is deciding to try to call a non-const base class function in a const function, even though a const overload is available. This appears to be some sort of compiler bug, but it could be some weird new C++ rule I don't understand. Does this represent a compiler bug?
struct BaseClass
{
// Commenting this non-const function out will also fix the compilation.
int* baseDevice() { return nullptr; }
const int* baseDevice() const { return nullptr; }
};
template <class ObjectClass>
struct DerivedClass : BaseClass
{
};
template <class ObjectClass>
struct TopClass : DerivedClass<ObjectClass>
{
public:
virtual int failsToCompile() const
{
// This should choose to call the const function, but it tries to call the non-const version.
if (BaseClass::baseDevice())
return 4;
return 1;
}
};
int main()
{
TopClass<int> x;
}
<source>: In instantiation of 'int TopClass<ObjectClass>::failsToCompile() const [with ObjectClass = ConcreteObject]':
<source>:27:17: required from here
<source>:30:32: error: passing 'const TopClass<ConcreteObject>' as 'this' argument discards qualifiers [-fpermissive]
30 | if (BaseClass::baseDevice())
| ~~~~~~~~~~~~~~~~~~~~~^~
<source>:14:15: note: in call to 'MyDevice* BaseClass::baseDevice()'
14 | MyDevice* baseDevice() { return nullptr; }
| ^~~~~~~~~~
ASM generation compiler returned: 1
It's a bug. I filed a bug report and the issue has already been verified coming from this commit.
The ticket has been assigned and the resolution has a targeted milestone of version 12.2 - so we can hope for a quick fix.