-
Notifications
You must be signed in to change notification settings - Fork 722
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
[Linux] WinAdapter: IUnknown
vtable includes destructors resulting in ABI mismatch
#3783
Comments
It should be possible to just remove the virtual destructor and suppress the warning. All destruction of objects is done via the |
Yes
If explicitly defined in the class and vtable that's okay, yes. It isn't for
My thought as well, but it looks pretty horrible: master...MarijnS95:winadapter-iunknown-no-virtual-dtor Unless we want to disable this warning project-wide, but that's ugly too when it really only concerns
Error is now irrelevant```cpp ../include/dxc/Support/microcom.h:104:3: warning: destructor called on non-final 'DxcRewriter' that has virtual functions but non-virtual destructor [-Wdelete-non-abstract-non-virtual-dtor] obj->~T(); ^ ../tools/clang/tools/libclang/dxcrewriteunused.cpp:1274:3: note: in instantiation of function template specialization 'DxcCallDestructor' requested here DXC_MICROCOM_TM_ADDREF_RELEASE_IMPL() ^ ../include/dxc/Support/microcom.h:120:7: note: expanded from macro 'DXC_MICROCOM_TM_ADDREF_RELEASE_IMPL' DxcCallDestructor(this); \ ^ ../include/dxc/Support/microcom.h:104:9: note: qualify call to silence this warning obj->~T(); ^ DxcRewriter:: ```
And so I realized I should have written I'll work on this some more and open a PR later. The sooner this lands the better, I'm already not looking forward to removing our Linux hacks from |
From peeking at the commits you linked, you probably don't want to explicitly scope to not I also don't entirely understand why this warning is popping up. I don't see it with either GCC or Clang with |
That's completely on purpose since building with Clang on Windows should not use
I guess you're building on Windows where |
I should clarify, I was just playing around with Clang/GCC on Godbolt, targeting Linux, defining a structure with a virtual method and no virtual destructor. Compiling with So, even though you wouldn't be using |
I wonder what flag causes this to turn on. There are mentions of
I'd really like to get confirmation for this though, having a hunch that Microsoft might have done something special to their definition to prevent triggering it - I doubt MSVC doesn't have a warning for this class of errors, or is it not explicitly turned on there at all? Guess I should go hunt for the source declaration of |
Indeed, MSVC does, but it's only enabled with |
Cool, so this isn't even an issue with the |
The vtable for `IUnknown` and its subclasses contain two deletion pointers when compiled on non-Windows systems with `IUnknown` from `WinAdapter.h`: vtable for 'DxcLibrary' @ 0x7ffff7cbc5f8 (subobject @ 0x5555556bb9e0): [0]: 0x7ffff6a56d40 <DxcLibrary::QueryInterface(_GUID const&, void**)> [1]: 0x7ffff6a56d20 <DxcLibrary::AddRef()> [2]: 0x7ffff6a56d30 <DxcLibrary::Release()> [3]: 0x7ffff6b36bc0 <IUnknown::~IUnknown()> // Complete object destructor [4]: 0x7ffff6a57130 <DxcLibrary::~DxcLibrary()> // Deleting destructor [5]: 0x7ffff6a56d50 <DxcLibrary::SetMalloc(IMalloc*)> [6]: 0x7ffff6a56d60 <DxcLibrary::CreateBlobFromBlob(IDxcBlob*, unsigned int, unsigned int, IDxcBlob**)> ... More DxcLibrary virtual functions This shifts the the pointers for functions for all subclasses, and is [annoying] to deal with in otherwise cross-platform applications using DirectXShaderCompiler as library. `dxcompiler.dll` compiled on/for Windows without `WinAdapter.h` does not suffer this problem, and only has three function pointers for `IUnknown`. Fortunately it is easily solved by removing the virtual destructor from `IUnknown`. LLVM enables `-Wnon-virtual-dtor` that warns against classes with virtual methods but no virtual destructor, though this warning is best not enabled akin to Windows builds where `IUnknown` from `windows.h` (`unknwn.h`) results in the same warning on MSVC ([1]/[2]). [annoying]: https://github.com/Traverse-Research/hassle-rs/blob/1e624792fc3a252ac7788e3c1c5feda52887272f/src/unknown.rs [1]: microsoft#3783 (comment) [2]: https://godbolt.org/z/hKPT6ThEf
* WinAdapter: Remove virtual dtors from IUnknown to fix vtable ABI The vtable for `IUnknown` and its subclasses contain two deletion pointers when compiled on non-Windows systems with `IUnknown` from `WinAdapter.h`: vtable for 'DxcLibrary' @ 0x7ffff7cbc5f8 (subobject @ 0x5555556bb9e0): [0]: 0x7ffff6a56d40 <DxcLibrary::QueryInterface(_GUID const&, void**)> [1]: 0x7ffff6a56d20 <DxcLibrary::AddRef()> [2]: 0x7ffff6a56d30 <DxcLibrary::Release()> [3]: 0x7ffff6b36bc0 <IUnknown::~IUnknown()> // Complete object destructor [4]: 0x7ffff6a57130 <DxcLibrary::~DxcLibrary()> // Deleting destructor [5]: 0x7ffff6a56d50 <DxcLibrary::SetMalloc(IMalloc*)> [6]: 0x7ffff6a56d60 <DxcLibrary::CreateBlobFromBlob(IDxcBlob*, unsigned int, unsigned int, IDxcBlob**)> ... More DxcLibrary virtual functions This shifts the the pointers for functions for all subclasses, and is [annoying] to deal with in otherwise cross-platform applications using DirectXShaderCompiler as library. `dxcompiler.dll` compiled on/for Windows without `WinAdapter.h` does not suffer this problem, and only has three function pointers for `IUnknown`. Fortunately it is easily solved by removing the virtual destructor from `IUnknown`. LLVM enables `-Wnon-virtual-dtor` that warns against classes with virtual methods but no virtual destructor, though this warning is best not enabled akin to Windows builds where `IUnknown` from `windows.h` (`unknwn.h`) results in the same warning on MSVC ([1]/[2]). [annoying]: https://github.com/Traverse-Research/hassle-rs/blob/1e624792fc3a252ac7788e3c1c5feda52887272f/src/unknown.rs [1]: microsoft#3783 (comment) [2]: https://godbolt.org/z/hKPT6ThEf * WinAdapter: Make `IUnknown` and `IMalloc` pure-virtual classes `IUnknown` in Windows' `unknwn.h` and `IMalloc` in `ObjIdl.h` are marked as pure virtual, and are best marked as such in `WinAdapter` for non-Windows platforms too [1]. Only the shim for `IMalloc` was relying on the default refcounting implementation, all other subclasses either contain pure-virtual methods themselves or provide an implementation for `AddRef`/`Release` as required. Likewise the default implementation for `IMalloc` was only instantiated once by `CoGetMalloc`, and has been moved into a local class implementing the `IMalloc` interface instead. [1]: microsoft#3793 (comment) * WinAdapter: Add three missing virtual functions to `IMalloc` interface To prevent unexpected vtable breakage, add the missing functions from the [documentation]. Note that they are listed in the wrong order, the right order is retrieved from the `ObjIdl.h` header and implementations for `IMalloc` in DirectXShaderCompiler. All implementations are now properly using the `override` keyword too, to enforce virtual method existence in the base class. [documentation]: https://docs.microsoft.com/en-us/windows/win32/api/objidl/nn-objidl-imalloc Co-authored-by: Marijn Suijten <[email protected]>
The vtable for `IUnknown` and its subclasses contain two deletion pointers when compiled on non-Windows systems with `IUnknown` from `WinAdapter.h`: vtable for 'DxcLibrary' @ 0x7ffff7cbc5f8 (subobject @ 0x5555556bb9e0): [0]: 0x7ffff6a56d40 <DxcLibrary::QueryInterface(_GUID const&, void**)> [1]: 0x7ffff6a56d20 <DxcLibrary::AddRef()> [2]: 0x7ffff6a56d30 <DxcLibrary::Release()> [3]: 0x7ffff6b36bc0 <IUnknown::~IUnknown()> // Complete object destructor [4]: 0x7ffff6a57130 <DxcLibrary::~DxcLibrary()> // Deleting destructor [5]: 0x7ffff6a56d50 <DxcLibrary::SetMalloc(IMalloc*)> [6]: 0x7ffff6a56d60 <DxcLibrary::CreateBlobFromBlob(IDxcBlob*, unsigned int, unsigned int, IDxcBlob**)> ... More DxcLibrary virtual functions This shifts the the pointers for functions for all subclasses, and is [annoying] to deal with in otherwise cross-platform applications using DirectXShaderCompiler as library. `dxcompiler.dll` compiled on/for Windows without `WinAdapter.h` does not suffer this problem, and only has three function pointers for `IUnknown`. Fortunately it is easily solved by removing the virtual destructor from `IUnknown`. LLVM enables `-Wnon-virtual-dtor` that warns against classes with virtual methods but no virtual destructor, though this warning is best not enabled akin to Windows builds where `IUnknown` from `windows.h` (`unknwn.h`) results in the same warning on MSVC ([1]/[2]). [annoying]: https://github.com/Traverse-Research/hassle-rs/blob/1e624792fc3a252ac7788e3c1c5feda52887272f/src/unknown.rs [1]: microsoft#3783 (comment) [2]: https://godbolt.org/z/hKPT6ThEf
The vtable for `IUnknown` and its subclasses contain two deletion pointers when compiled on non-Windows systems with `IUnknown` from `WinAdapter.h`: vtable for 'DxcLibrary' @ 0x7ffff7cbc5f8 (subobject @ 0x5555556bb9e0): [0]: 0x7ffff6a56d40 <DxcLibrary::QueryInterface(_GUID const&, void**)> [1]: 0x7ffff6a56d20 <DxcLibrary::AddRef()> [2]: 0x7ffff6a56d30 <DxcLibrary::Release()> [3]: 0x7ffff6b36bc0 <IUnknown::~IUnknown()> // Complete object destructor [4]: 0x7ffff6a57130 <DxcLibrary::~DxcLibrary()> // Deleting destructor [5]: 0x7ffff6a56d50 <DxcLibrary::SetMalloc(IMalloc*)> [6]: 0x7ffff6a56d60 <DxcLibrary::CreateBlobFromBlob(IDxcBlob*, unsigned int, unsigned int, IDxcBlob**)> ... More DxcLibrary virtual functions This shifts the the pointers for functions for all subclasses, and is [annoying] to deal with in otherwise cross-platform applications using DirectXShaderCompiler as library. `dxcompiler.dll` compiled on/for Windows without `WinAdapter.h` does not suffer this problem, and only has three function pointers for `IUnknown`. Fortunately it is easily solved by removing the virtual destructor from `IUnknown`. LLVM enables `-Wnon-virtual-dtor` that warns against classes with virtual methods but no virtual destructor, though this warning is best not enabled akin to Windows builds where `IUnknown` from `windows.h` (`unknwn.h`) results in the same warning on MSVC ([1]/[2]). [annoying]: https://github.com/Traverse-Research/hassle-rs/blob/1e624792fc3a252ac7788e3c1c5feda52887272f/src/unknown.rs [1]: microsoft#3783 (comment) [2]: https://godbolt.org/z/hKPT6ThEf
The vtable for `IUnknown` and its subclasses contain two deletion pointers when compiled on non-Windows systems with `IUnknown` from `WinAdapter.h`: vtable for 'DxcLibrary' @ 0x7ffff7cbc5f8 (subobject @ 0x5555556bb9e0): [0]: 0x7ffff6a56d40 <DxcLibrary::QueryInterface(_GUID const&, void**)> [1]: 0x7ffff6a56d20 <DxcLibrary::AddRef()> [2]: 0x7ffff6a56d30 <DxcLibrary::Release()> [3]: 0x7ffff6b36bc0 <IUnknown::~IUnknown()> // Complete object destructor [4]: 0x7ffff6a57130 <DxcLibrary::~DxcLibrary()> // Deleting destructor [5]: 0x7ffff6a56d50 <DxcLibrary::SetMalloc(IMalloc*)> [6]: 0x7ffff6a56d60 <DxcLibrary::CreateBlobFromBlob(IDxcBlob*, unsigned int, unsigned int, IDxcBlob**)> ... More DxcLibrary virtual functions This shifts the the pointers for functions for all subclasses, and is [annoying] to deal with in otherwise cross-platform applications using DirectXShaderCompiler as library. `dxcompiler.dll` compiled on/for Windows without `WinAdapter.h` does not suffer this problem, and only has three function pointers for `IUnknown`. Fortunately it is easily solved by removing the virtual destructor from `IUnknown`. LLVM enables `-Wnon-virtual-dtor` that warns against classes with virtual methods but no virtual destructor, though this warning is best not enabled akin to Windows builds where `IUnknown` from `windows.h` (`unknwn.h`) results in the same warning on MSVC ([1]/[2]). [annoying]: https://github.com/Traverse-Research/hassle-rs/blob/1e624792fc3a252ac7788e3c1c5feda52887272f/src/unknown.rs [1]: microsoft#3783 (comment) [2]: https://godbolt.org/z/hKPT6ThEf
The vtable for `IUnknown` and its subclasses contain two deletion pointers when compiled on non-Windows systems with `IUnknown` from `WinAdapter.h`: vtable for 'DxcLibrary' @ 0x7ffff7cbc5f8 (subobject @ 0x5555556bb9e0): [0]: 0x7ffff6a56d40 <DxcLibrary::QueryInterface(_GUID const&, void**)> [1]: 0x7ffff6a56d20 <DxcLibrary::AddRef()> [2]: 0x7ffff6a56d30 <DxcLibrary::Release()> [3]: 0x7ffff6b36bc0 <IUnknown::~IUnknown()> // Complete object destructor [4]: 0x7ffff6a57130 <DxcLibrary::~DxcLibrary()> // Deleting destructor [5]: 0x7ffff6a56d50 <DxcLibrary::SetMalloc(IMalloc*)> [6]: 0x7ffff6a56d60 <DxcLibrary::CreateBlobFromBlob(IDxcBlob*, unsigned int, unsigned int, IDxcBlob**)> ... More DxcLibrary virtual functions This shifts the the pointers for functions for all subclasses, and is [annoying] to deal with in otherwise cross-platform applications using DirectXShaderCompiler as library. `dxcompiler.dll` compiled on/for Windows without `WinAdapter.h` does not suffer this problem, and only has three function pointers for `IUnknown`. Fortunately it is easily solved by removing the virtual destructor from `IUnknown`. LLVM enables `-Wnon-virtual-dtor` that warns against classes with virtual methods but no virtual destructor, though this warning is best not enabled akin to Windows builds where `IUnknown` from `windows.h` (`unknwn.h`) results in the same warning on MSVC ([1]/[2]). [annoying]: https://github.com/Traverse-Research/hassle-rs/blob/1e624792fc3a252ac7788e3c1c5feda52887272f/src/unknown.rs [1]: microsoft#3783 (comment) [2]: https://godbolt.org/z/hKPT6ThEf
…ABI (#3793) * WinAdapter: Remove virtual dtors from IUnknown to fix vtable ABI The vtable for `IUnknown` and its subclasses contain two deletion pointers when compiled on non-Windows systems with `IUnknown` from `WinAdapter.h`: vtable for 'DxcLibrary' @ 0x7ffff7cbc5f8 (subobject @ 0x5555556bb9e0): [0]: 0x7ffff6a56d40 <DxcLibrary::QueryInterface(_GUID const&, void**)> [1]: 0x7ffff6a56d20 <DxcLibrary::AddRef()> [2]: 0x7ffff6a56d30 <DxcLibrary::Release()> [3]: 0x7ffff6b36bc0 <IUnknown::~IUnknown()> // Complete object destructor [4]: 0x7ffff6a57130 <DxcLibrary::~DxcLibrary()> // Deleting destructor [5]: 0x7ffff6a56d50 <DxcLibrary::SetMalloc(IMalloc*)> [6]: 0x7ffff6a56d60 <DxcLibrary::CreateBlobFromBlob(IDxcBlob*, unsigned int, unsigned int, IDxcBlob**)> ... More DxcLibrary virtual functions This shifts the the pointers for functions for all subclasses, and is [annoying] to deal with in otherwise cross-platform applications using DirectXShaderCompiler as library. `dxcompiler.dll` compiled on/for Windows without `WinAdapter.h` does not suffer this problem, and only has three function pointers for `IUnknown`. Fortunately, it is easily solved by removing the virtual destructor from `IUnknown`. LLVM enables `-Wnon-virtual-dtor` that warns against classes with virtual methods but no virtual destructor, though this warning is best not enabled akin to Windows builds where `IUnknown` from `windows.h` (`unknwn.h`) results in the same warning on MSVC ([1]/[2]). [annoying]: https://github.com/Traverse-Research/hassle-rs/blob/1e624792fc3a252ac7788e3c1c5feda52887272f/src/unknown.rs [1]: #3783 (comment) [2]: https://godbolt.org/z/hKPT6ThEf * WinAdapter: Make `IUnknown` and `IMalloc` pure-virtual classes `IUnknown` in Windows' `unknwn.h` and `IMalloc` in `ObjIdl.h` are marked as pure virtual, and are best marked as such in `WinAdapter` for non-Windows platforms too [1]. Only the shim for `IMalloc` was relying on the default refcounting implementation, all other subclasses either contain pure-virtual methods themselves or provide an implementation for `AddRef`/`Release` as required. Likewise the default implementation for `IMalloc` was only instantiated once by `CoGetMalloc`, and has been moved into a local class implementing the `IMalloc` interface instead. [1]: #3793 (comment) * WinAdapter: Add three missing virtual functions to `IMalloc` interface To prevent unexpected vtable breakage, add the missing functions from the [documentation]. Note that they are listed in the wrong order, the right order is retrieved from the `ObjIdl.h` header and implementations for `IMalloc` in DirectXShaderCompiler. All implementations are now properly using the `override` keyword too, to enforce virtual method existence in the base class. [documentation]: https://docs.microsoft.com/en-us/windows/win32/api/objidl/nn-objidl-imalloc * Make all WinAdapter destructions explicit This prevents warnings about non-virtual destructor usage that trip up the Linux build. It represents status quo on Windows. Co-authored-by: Greg Roth <[email protected]>
The vtable for
IUnknown
fromWinAdapter.h
contains five instead of three function pointers, shifting vtable entries for every subclass. Two pointers following the three virutal functions inIUnknown
are reserved for a complete object and deleting destructor:This makes it annoying or impossible to interact with the interfaces from Linux and Windows in a generic way.
Simply removing it results in compiler warnings from both Clang and GCC:
No idea if ignoring them locally (
#pragma clang/GCC diagnostic ignored "-Wnon-virtual-dtor"
) or globally is the right way forward though. Members owned by subclasses ofIUnknown
should be cleaned up through theRelease()
function anyway otherwise this would leak memory and other resources on Windows where no virtual destructors are used.I recall reading something about
operator delete
(called asdelete this
inIUnknown::Release
) requiring object size to call the appropriate memory deallocation function which could be facilitated through this destructor. The deleting destructor could possibly pass a size to one of theoperator delete
variants.@pow2clk Hope you have some suggestions since you've been working on Linux compatibility - apart this issue everything runs flawlessly on Linux on-par with our Windows builds and that's simply awesome!
The text was updated successfully, but these errors were encountered: