While upgrading an internal code base to C++20, I ran into a seeming template instantiation difference between C++17 and C++20, which is reduced here. We have a method of a class template that uses
dynamic_cast in a TU that’s built with
-fno-rtti, but that method isn’t explicitly referenced anywhere. Clang with
-std=c++17 lets us get away with this, whereas Clang with
-std=c++20 complains about using
dynamic_cast but building without RTTI. gcc builds successfully in both standards versions.
I think this is sketchy regardless of the error, and I was planning to enable RTTI to fix it, but I also wanted to try to understand it a bit more. Does anyone know why Clang lets us get away with this in C++17 mode but not in C++20? From comparing AST dumps (Compiler Explorer), it seems like implicit destructors get marked
constexpr in C++20, and that sounds kinda similar to Proposal: adding a c++20 early adopter mode for libc++ constexpr annotations in c++17 (where new
constexpr additions in C++20 caused incomplete types to be errors in more places), but I’d like to understand the exact mechanism a bit better.