Open ahatanak opened 2 months ago
@llvm/issue-subscribers-clang-frontend
Author: Akira Hatanaka (ahatanak)
It looks like clang started emitting the warning after 99500e8c08a4d941acb8a7eb00523296fb2acf7a. clang doesn't warn if I revert the commit.
CC @Fznamznon
This also happens in Clang 18 if we have https://godbolt.org/z/7GzabWKxq
class c {
protected:
virtual ~c();
virtual int d() const;
};
template <typename> class e : c {
constexpr ~e() = default;
int d() const override;
};
int t = sizeof(e<int>);
This appears to have just been exposed when the implicitly-declared destructor became constexpr
via https://wg21.link/p2448r2#pnum_23
I think this is ill-formed NDR -- the class is required to be complete, so its virtual functions are ODR-used.
In practice, e<int>
has a constexpr
virtual destructor, so we instantiate it eagerly, and we instantiate the complete vtable with the destructor, so the behavior here makes some sense. But it would seem better if we could defer marking the vtable used until the destructor is actually used (not just instantiated because it might be used at compile time, which doesn't need the vtable).
$ cat test.cpp
$ clang++ -c -std=gnu++2b -Wundefined-func-template test.cpp
test.cpp:7:27: warning: instantiation of function 'e::d' required here, but no definition is available [-Wundefined-func-template]
7 | template class e : c {
I don’t think instantiation of e::d is needed to compute the size of the class.