-
Notifications
You must be signed in to change notification settings - Fork 707
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: Remove virtual dtors from IUnknown to fix vtable ABI #3793
[Linux] WinAdapter: Remove virtual dtors from IUnknown to fix vtable ABI #3793
Conversation
❌ Build DirectXShaderCompiler 1.0.144 failed (commit 6c3eee293b by @MarijnS95) |
Huh. The Removing the implementation of |
@jenatali thanks for the insight!
I wonder if that's done on purpose, to have an easier time implementing other wrapper structs. Though it seems only ../lib/DxcSupport/WinFunctions.cpp:158:19: error: allocating an object of abstract class type 'IMalloc'
*ppMalloc = new IMalloc;
^
../include/dxc/Support/WinAdapter.h:626:17: note: unimplemented pure virtual method 'AddRef' in 'IMalloc'
virtual ULONG AddRef() = 0;
^
../include/dxc/Support/WinAdapter.h:627:17: note: unimplemented pure virtual method 'Release' in 'IMalloc'
virtual ULONG Release() = 0;
^ That's simply solved by moving
For completeness this error occurs on all other subclasses that contain virtual methods themselves. Expand this block to see all the errors.[62/1040] Building CXX object lib/Support/CMakeFiles/LLVMSupport.dir/Process.cpp.o
In file included from ../lib/Support/Process.cpp:78:
../lib/Support/Unix/Process.inc:98:10: warning: 'mallinfo' is deprecated [-Wdeprecated-declarations]
mi = ::mallinfo();
^
/usr/include/malloc.h:118:48: note: 'mallinfo' has been explicitly marked deprecated here
extern struct mallinfo mallinfo (void) __THROW __MALLOC_DEPRECATED;
^
/usr/include/malloc.h:31:30: note: expanded from macro '__MALLOC_DEPRECATED'
# define __MALLOC_DEPRECATED __attribute_deprecated__
^
/usr/include/sys/cdefs.h:261:51: note: expanded from macro '__attribute_deprecated__'
# define __attribute_deprecated__ __attribute__ ((__deprecated__))
^
1 warning generated.
[530/1040] Building CXX object lib/DxcSupport/CMakeFiles/LLVMDxcSupport.dir/dxcmem.cpp.o
../lib/DxcSupport/dxcmem.cpp:46:55: warning: ISO C++ requires the name after '::~' to be found in the same scope as the name before '::~' [-Wdtor-name]
g_ThreadMallocTls->llvm::sys::ThreadLocal<IMalloc>::~ThreadLocal();
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~^~
::ThreadLocal
1 warning generated.
[532/1040] Building CXX object lib/DxcSupport/CMakeFiles/LLVMDxcSupport.dir/WinAdapter.cpp.o
../lib/DxcSupport/WinAdapter.cpp:31:5: warning: delete called on non-final 'IMalloc' that has virtual functions but non-virtual destructor [-Wdelete-non-abstract-non-virtual-dtor]
delete this;
^
1 warning generated.
[602/1040] Building CXX object lib/HLSL/CMakeFiles/LLVMHLSL.dir/HLMatrixLowerPass.cpp.o
../lib/HLSL/HLMatrixLowerPass.cpp:1582:18: warning: unused variable 'ValMatTy' [-Wunused-variable]
HLMatrixType ValMatTy = HLMatrixType::cast(TrueMat->getType());
^
1 warning generated.
[861/1040] Building CXX object tools/clang/lib/CodeGen/CMakeFiles/clangCodeGen.dir/CGHLSLMSFinishCodeGen.cpp.o
../tools/clang/lib/CodeGen/CGHLSLMSFinishCodeGen.cpp:164:6: warning: unused function 'IsHLSLBufferViewType' [-Wunused-function]
bool IsHLSLBufferViewType(llvm::Type *Ty) {
^
1 warning generated.
[972/1040] Building CXX object tools/clang/tools/libclang/CMakeFiles/libclang.dir/dxcisenseimpl.cpp.o
../tools/clang/tools/libclang/dxcisenseimpl.cpp:584:5: warning: delete called on non-final 'DxcBasicUnsavedFile' that has virtual functions but non-virtual destructor [-Wdelete-non-abstract-non-virtual-dtor]
delete newValue;
^
1 warning generated.
[991/1040] Building CXX object tools/clang/tools/dxclib/CMakeFiles/dxclib.dir/dxc.cpp.o
../tools/clang/tools/dxclib/dxc.cpp:591:3: warning: delete called on non-final 'DxcIncludeHandlerForInjectedSources' that has virtual functions but non-virtual destructor [-Wdelete-non-abstract-non-virtual-dtor]
DXC_MICROCOM_ADDREF_RELEASE_IMPL(m_dwRef)
^
../include/dxc/Support/microcom.h:90:7: note: expanded from macro 'DXC_MICROCOM_ADDREF_RELEASE_IMPL'
delete this; \
^
1 warning generated.
[994/1040] Building CXX object tools/clang/unittests/HLSL/CMakeFiles/clang-hlsl-tests.dir/Objects.cpp.o
In file included from ../tools/clang/unittests/HLSL/Objects.cpp:11:
../include/dxc/Test/CompilationResult.h:74:22: warning: delete called on non-final 'TrivialDxcUnsavedFile' that has virtual functions but non-virtual destructor [-Wdelete-non-abstract-non-virtual-dtor]
if (result == 0) delete this;
^
1 warning generated.
[995/1040] Building CXX object tools/clang/unittests/HLSL/CMakeFiles/clang-hlsl-tests.dir/VerifierTest.cpp.o
In file included from ../tools/clang/unittests/HLSL/VerifierTest.cpp:14:
../include/dxc/Test/CompilationResult.h:74:22: warning: delete called on non-final 'TrivialDxcUnsavedFile' that has virtual functions but non-virtual destructor [-Wdelete-non-abstract-non-virtual-dtor]
if (result == 0) delete this;
^
1 warning generated.
[1003/1040] Building CXX object tools/clang/unittests/HLSL/CMakeFiles/clang-hlsl-tests.dir/FunctionTest.cpp.o
In file included from ../tools/clang/unittests/HLSL/FunctionTest.cpp:16:
../include/dxc/Test/CompilationResult.h:74:22: warning: delete called on non-final 'TrivialDxcUnsavedFile' that has virtual functions but non-virtual destructor [-Wdelete-non-abstract-non-virtual-dtor]
if (result == 0) delete this;
^
1 warning generated.
[1006/1040] Building CXX object tools/clang/unittests/HLSL/CMakeFiles/clang-hlsl-tests.dir/ExtensionTest.cpp.o
In file included from ../tools/clang/unittests/HLSL/ExtensionTest.cpp:10:
../include/dxc/Test/CompilationResult.h:74:22: warning: delete called on non-final 'TrivialDxcUnsavedFile' that has virtual functions but non-virtual destructor [-Wdelete-non-abstract-non-virtual-dtor]
if (result == 0) delete this;
^
../tools/clang/unittests/HLSL/ExtensionTest.cpp:306:3: warning: delete called on non-final 'TestIntrinsicTable' that has virtual functions but non-virtual destructor [-Wdelete-non-abstract-non-virtual-dtor]
DXC_MICROCOM_ADDREF_RELEASE_IMPL(m_dwRef)
^
../include/dxc/Support/microcom.h:90:7: note: expanded from macro 'DXC_MICROCOM_ADDREF_RELEASE_IMPL'
delete this; \
^
../tools/clang/unittests/HLSL/ExtensionTest.cpp:406:3: warning: delete called on non-final 'TestSemanticDefineValidator' that has virtual functions but non-virtual destructor [-Wdelete-non-abstract-non-virtual-dtor]
DXC_MICROCOM_ADDREF_RELEASE_IMPL(m_dwRef)
^
../include/dxc/Support/microcom.h:90:7: note: expanded from macro 'DXC_MICROCOM_ADDREF_RELEASE_IMPL'
delete this; \
^
3 warnings generated.
[1007/1040] Building CXX object tools/clang/unittests/HLSLTestLib/CMakeFiles/HLSLTestLib.dir/DxcTestUtils.cpp.o
In file included from ../tools/clang/unittests/HLSLTestLib/DxcTestUtils.cpp:12:
../include/dxc/Test/CompilationResult.h:74:22: warning: delete called on non-final 'TrivialDxcUnsavedFile' that has virtual functions but non-virtual destructor [-Wdelete-non-abstract-non-virtual-dtor]
if (result == 0) delete this;
^
1 warning generated.
[1010/1040] Building CXX object tools/clang/unittests/HLSL/CMakeFiles/clang-hlsl-tests.dir/DXIsenseTest.cpp.o
In file included from ../tools/clang/unittests/HLSL/DXIsenseTest.cpp:12:
../include/dxc/Test/CompilationResult.h:74:22: warning: delete called on non-final 'TrivialDxcUnsavedFile' that has virtual functions but non-virtual destructor [-Wdelete-non-abstract-non-virtual-dtor]
if (result == 0) delete this;
^
1 warning generated.
[1013/1040] Building CXX object tools/clang/unittests/HLSL/CMakeFiles/clang-hlsl-tests.dir/DxilModuleTest.cpp.o
In file included from ../tools/clang/unittests/HLSL/DxilModuleTest.cpp:10:
../include/dxc/Test/CompilationResult.h:74:22: warning: delete called on non-final 'TrivialDxcUnsavedFile' that has virtual functions but non-virtual destructor [-Wdelete-non-abstract-non-virtual-dtor]
if (result == 0) delete this;
^
1 warning generated.
[1040/1040] Linking CXX executable bin/clang-spirv-tests |
Note that So you'd run into the same problem if you tried to have cross-platform usage of IMalloc. The solution is to make anything which implements
Nah, looks like these are all in tests. I suspect core code suppresses this warning already. There's plenty of classes which inherit from |
❌ Build DirectXShaderCompiler 1.0.147 failed (commit af7fc15f3c by @MarijnS95) |
Ah I could have figured :)
This is again a default implementation that's only used from
By the way that documentation shows more functions are available, and that was never caught because implementations like
Not sure why I wrote Final nit, looks like the API in WinAdapter isn't using |
d4a0948
to
83b15a2
Compare
❌ Build DirectXShaderCompiler 1.0.148 failed (commit 0da7b95d8f by @MarijnS95) |
Thank you for this change! |
❌ Build DirectXShaderCompiler 1.0.157 failed (commit e1296dab7c by @jaebaek) |
❌ Build DirectXShaderCompiler 1.0.158 failed (commit f8585c5083 by @jaebaek) |
f6eccd0
to
570a5f2
Compare
Yes it's going to be awesome and we can finally drop our hacks! Unfortunately this means the applications we're using
Thanks! Yes Finally, |
Self-reply: I've hack-fixed this by running placement-new (which is fine to run unconditionally because the classes don't contain any other data). We're crashing inside |
Nice :) I do not have any specific comment for now. I just thought using I attach the one with I want to check my other projects with this change. I am just curious previous issues I met was this issue or not. Thanks! 👍 |
Not sure if you noticed the ninja-edit, but it's "fixed" now with placement-new, let me know if that's an acceptable change (I'll add a comment on the placement-new). It's more concise to keep these stateless instances as EDIT: It looks like
Oh yeah, it looks like this was one odd case where the class type instead of the (pure virtual) interface was used in |
❌ Build DirectXShaderCompiler 1.0.159 failed (commit 0b3ffdee87 by @MarijnS95) |
570a5f2
to
53d18bc
Compare
Oh yikes, the explicit type was used on purpose to access |
I am not versed on the code base of this change in terms of the purpose of classes. I am afraid that I am not a right person to make a decision for the direction of changes here. If there are no other issues, fixing the vtable issue with working code looks good to me. Let's wait @jenatali 's code review |
@jaebaek Thanks for the review and suggestions thus far anyway! If anything I'll submit the conversion to a (Assuming it is okay to leave |
`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)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We discussed this internally and I thought about it some more and came up with basically two options:
- Effectively disable the warnings about the possibility of bad destructor calls due to not being virtual
- Make every final descendent from IUnknown final.
The first is simple to implement and maintain, but does carry some risk of undetected programmer mistakes.
The second is probably "right". In that it forces people to either make final classes or add virtual destructors. However, it is cumbersome and represents a retraction of capabilities as there are users out there who have created descendants from our classes and would have to change how they use them. Incidentally, you are only supposed to create CComPtrs with interface types, but DXC, D3D and pretty much every else seems to violate this rampantly 😅
As such, I'm asking that the additions of finals to leaf node classes be removed along with the workarounds that they necessitated and that the Release() implementation in DXC_MICROCOM_ADDREF_RELEASE_IMPL be modified to be more in line with the "TM" variant. This has the effect of disabling the warnings only where we want exceptions with IUnknown descended classes.
Since it's a bit hard to communicate all this in the abstract, I created a commit that includes my suggestions plus a few other additions that you can draw from or incorporate directly if you choose: pow2clk@ea34d70
edit: corrected commit
# append_if(CXX_WONT_WARN_ON_FINAL_NONVIRTUALDTOR | ||
# "-Wnon-virtual-dtor" CMAKE_CXX_FLAGS) | ||
|
||
# HLSL Change Ends |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I wish that this could be disabled only where it needs to be, but it needs to be in quite a lot of places and that would probably be more annoying than its worth
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We'd effectively have to inline-disable the warning every time a pure virtual interface is defined it seems. I guess the main point for this was because MSVC doesn't warn on this either.
include/dxc/Support/microcom.h
Outdated
@@ -101,7 +101,7 @@ inline T *CreateOnMalloc(IMalloc * pMalloc, Args&&... args) { | |||
|
|||
template<typename T> | |||
void DxcCallDestructor(T *obj) { | |||
obj->~T(); | |||
obj->T::~T(); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This effectively disables the warning because the warning is concerned that if there is a descendent of the T class that is referenced by a pointer to the T class, only the T destructor will be called. This does just that.
I can't comment on the specific line due to github limitations, but my preferred solution would be to replace delete this
on line 90 with a call to DxcCallDestructor followed by an explicit call to the delete operator.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Disabling that warning in this way would have been fine with the final
notion, but theoretically it should be possible to have subclasses of subclasses with virtual destructors beyond that 1? This would then call the wrong destructor, though it wasn't removed in your commit?
For my understanding, as this has all been long ago and I don't write a lot of C++: calling operator delete(this)
directly is different in that it doesn't perform a virtual dispatch to any of the destructor operators (since that's done already by DxcCallDestructor
) but merely frees the memory allocated by new
?
EDIT: Seems like it's for deallocation purposes only, yes: https://en.cppreference.com/w/cpp/memory/new/operator_delete
Footnotes
-
As long as it isn't intermixed with the pure-virtual interfaces that would otherwise get a skewed vtable. ↩
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Perhaps this is fine after all, given that:
- COM objects should only be freed through the
Release
virtual function; - Hence, every descendant should override it;
- Which will call the "lowest" destructor through
DxcCallDestructor
: it's known statically here asT
, hence doesn't need to be virtual.
CComPtr<IMalloc> pTmp(newValue->m_pMalloc); | ||
newValue->DxcBasicUnsavedFile::~DxcBasicUnsavedFile(); | ||
pTmp->Free(newValue); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@pow2clck what'd happen if we just call newValue->Release()
here? Same for InternalDxcBlobEncoding_Impl
/MemoryStream
above that had to get the ->T::~T
"fix" to get rid of the warning.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Oh that's not entirely correct: Those two types have their code located in Release()
already 1, and the code here also uses IMalloc
. The only thing all three have in common: they use IMalloc
(ie. not suitable for DXC_MICROCOM_ADDREF_RELEASE_IMPL
) yet don't use DxcThreadMalloc
(ie. not suitable for DXC_MICROCOM_TM_ADDREF_RELEASE_IMPL
either).
Footnotes
-
My suggestion would lead to infinite recursion 😂 ↩
✅ Build DirectXShaderCompiler 1.0.1103 completed (commit 3de5ae798e by @pow2clk) |
We have a very peculiar workaround for DXC (pending upstream fix [microsoft/DirectXShaderCompiler#3793]) that requires us to conditionally provide function implementations for extra vtable "spacers": https://github.com/Traverse-Research/hassle-rs/blob/f5a090c70bbcf66f3bafd3d549716a414e873838/src/wrapper.rs#L130-L139. The spacers are conditionally defined in: https://github.com/Traverse-Research/hassle-rs/blob/f5a090c70bbcf66f3bafd3d549716a414e873838/src/unknown.rs. These need to be forwarded otherwise the initialization of these vtable members will happen unconditionally even when they don't exist: https://github.com/Traverse-Research/hassle-rs/actions/runs/1777800733 Fixes microsoft#166 [microsoft/DirectXShaderCompiler#3793]: microsoft/DirectXShaderCompiler#3793
We have a very peculiar workaround for DXC (pending upstream fix [microsoft/DirectXShaderCompiler#3793]) that requires us to conditionally provide function implementations for extra vtable "spacers": https://github.com/Traverse-Research/hassle-rs/blob/f5a090c70bbcf66f3bafd3d549716a414e873838/src/wrapper.rs#L130-L139. The spacers are conditionally defined in: https://github.com/Traverse-Research/hassle-rs/blob/f5a090c70bbcf66f3bafd3d549716a414e873838/src/unknown.rs. These need to be forwarded otherwise the initialization of these vtable members will happen unconditionally even when they don't exist: https://github.com/Traverse-Research/hassle-rs/actions/runs/1777800733 Fixes microsoft#166 [microsoft/DirectXShaderCompiler#3793]: microsoft/DirectXShaderCompiler#3793
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
`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)
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
This prevents warnings about non-virtual destructor usage that trip up the Linux build. It represents status quo on Windows.
3904a9b
to
322b181
Compare
@pow2clk This is once again rebased on |
✅ Build DirectXShaderCompiler 1.0.1366 completed (commit 1490e620ee by @pow2clk) |
@pow2clk It seems the CI still succeeds after a merge with master... 2 months later 🙂 |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
A much-delayed approval. Sorry again :(
@pow2clk thank you so much, after 1.5 years this is finally allowing me to drop some hacks in downstream wrapper projects 👍 |
…extra trait" This reverts commit c37cb03. [This commit] is squashed in the merge of PR #5, and does not exist in-tree. microsoft/DirectXShaderCompiler#3793 has finally been merged on October 13th 2022 and now allows us to drop the vtable dummies for virtual destructors again, as those are not part of the ABI and shouldn't have been in the vtable in the first place. [This commit]: c37cb03
…extra trait" This reverts commit c37cb03. [This commit] is squashed in the merge of PR #5, and does not exist in-tree. microsoft/DirectXShaderCompiler#3793 has finally been merged on October 13th 2022 and now allows us to drop the vtable dummies for virtual destructors again, as those are not part of the ABI and shouldn't have been in the vtable in the first place. [This commit]: c37cb03
…) through extra trait" (#50) * Revert "[WIN/LINUX] Implement vtable dummies (virtual dtors) through extra trait" This reverts commit c37cb03. [This commit] is squashed in the merge of PR #5, and does not exist in-tree. microsoft/DirectXShaderCompiler#3793 has finally been merged on October 13th 2022 and now allows us to drop the vtable dummies for virtual destructors again, as those are not part of the ABI and shouldn't have been in the vtable in the first place. [This commit]: c37cb03 * README: Replace verbose compatibility "guide" with direct table It's been quite a while ago (about two years) since we landed a whole bunch of compatibility fixes for DXC, and I hope everyone is using (much) newer releases by now. I also doubt anyone is interested in detailed descriptions of what we fixed (including the how and why), and just wants a clear answer on the DXC release or commit they must minimally use for compatibility with a certain `hassle-rs` release. * README: Vtable changes have been published in DXC v1.7.2212
We have a very peculiar workaround for DXC (pending upstream fix [microsoft/DirectXShaderCompiler#3793]) that requires us to conditionally provide function implementations for extra vtable "spacers": https://github.com/Traverse-Research/hassle-rs/blob/f5a090c70bbcf66f3bafd3d549716a414e873838/src/wrapper.rs#L130-L139. The spacers are conditionally defined in: https://github.com/Traverse-Research/hassle-rs/blob/f5a090c70bbcf66f3bafd3d549716a414e873838/src/unknown.rs. These need to be forwarded otherwise the initialization of these vtable members will happen unconditionally even when they don't exist: https://github.com/Traverse-Research/hassle-rs/actions/runs/1777800733 Fixes microsoft#166 [microsoft/DirectXShaderCompiler#3793]: microsoft/DirectXShaderCompiler#3793
Fixes #3783
The vtable for
IUnknown
and its subclasses contain two deletion pointers when compiled on non-Windows systems withIUnknown
fromWinAdapter.h
: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/forWindows without
WinAdapter.h
does not suffer this problem, and only has three function pointers forIUnknown
.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 thiswarning is best not enabled akin to Windows builds where
IUnknown
fromwindows.h
(unknwn.h
) results in the same warning on MSVC (1/2).Tested on Clang
11.1.0
and GCC11.1.0
. Unfortunately GCC fails compiling on an irrelevant-Werror=stringop-truncation
inSPIRV-Tools
, irrespective of this PR.On Clang this PR still results in quite a few warnings of the sort:
And it seems the same warning is named
-Wdelete-non-virtual-dtor
on GCC - but unfortunately surrounded by hundreds upon hundreds of these warnings.CC @jenatali; thanks for checking this with me and pointing out the warning on MSVC too!