Open b1622bb8-0285-400e-ba44-ba0e5027e546 opened 10 years ago
I fixed the _DebugHeapDelete
problem in r207771, but the others remain with /D_DEBUG /MDd
. They are blocked on importing a full class definition, which is llvm/llvm-project#11542 .
I can reproduce the problem by streaming a number, which invokes the locale machinery:
$ cat t.cpp
#include <iostream>
int main() {
int x = 123;
std::cout << x << '\n';
}
$ cl -nologo -D_HAS_EXCEPTIONS=0 -GR- -MTd -D_DEBUG -c t.cpp && dumpbin /symbols t.obj | grep 'DebugHeapDelete<void>'
t.cpp
585 00000000 SECTAC notype () External | ??$_DebugHeapDelete@X@std@@YAXPAX@Z (void __cdecl std::_DebugHeapDelete<void>(void *))
$ clang-cl -D_HAS_EXCEPTIONS=0 -GR- -MTd -D_DEBUG -c t.cpp && dumpbin /symbols t.obj | grep 'DebugHeapDelete<void>'
3F1 00000000 UNDEF notype External | ??$_DebugHeapDelete@X@std@@YAXPAX@Z (void __cdecl std::_DebugHeapDelete<void>(void *))
MSVC provides a definition for std::_DebugHeapDelete<void>(void*)
, but Clang does not. Clang should emit an error if it fails template instantiation, so I'm not sure why this compiles successfully at all.
If I use /MTd
to get the static CRT, a definition is provided. However if I use /MDd
, I get link errors. I've been linking the CRT statically because clang doesn't support dllimport
/ export
of full classes yet (#11170 ).
Sorry, left out that the same header also provides the following macro:
#define _DELETE_CRT_VEC(ptr) _STD _DebugHeapDelete((void *)ptr)
So it's definitely intentional that _DebugHeapDelete<void>
be called here.
In Visual Studio 2012, when building with _DEBUG
, the xdebug
header provides a template function:
template<class _Ty> void _DebugHeapDelete(_Ty *_Ptr)
{
if (_Ptr != 0)
{
_Ptr->~_Ty();
free(_Ptr);
}
}
with no other overrides or overloads that I can see.
The clang-cl I'm using here just reports no matching function call
, as the above template fails substitition [with _Ty = void]
, due to the call to (void*)->~void
.
So it's probably not resolving when linking because it's supposed to be an instantiated template that MSVC's CL doesn't fail on, but clang-cl does.
This is using the LLVM-3.5.r198737-win32 snapshot with -cxx-abi itanium, I'm guessing one of the compiler switches in the original report is causing clang-cl to turn the "cannot instantiate template" into an implicit "extern template class". /Ob0
"Disable inlining" perhaps?
The compiler command line shows that it is compiling the debug version. The linker line, which invokes the Microsoft linker is:
link /nologo /DEBUG /MACHINE:X86 /MANIFEST /subsystem:console /out:"..\..\..\bin.v2\libs\vmd\test\test_after_identifier.test\clang-vc11-win-3.4\debug\test_after_identifier.exe" @"..\..\..\bin.v2\libs\vmd\test\test_after_identifier.test\clang-vc11-win-3.4\debug\test_after_identifier.exe.rsp"
where the response file is simply:
"..\..\..\bin.v2\libs\vmd\test\test_after_identifier.test\clang-vc11-win-3.4\debug\test_after_identifier.obj"
The compile succeeds but the link gives an error.
If you think the .obj
file will help you discover what the problem is I can attach it if you like.
I don't understand the first error, but the last looks like there's some kind of debug/release mismatch (std::_DebugHeapDelete<void>
):
test_begin_identifier.obj : error LNK2019: unresolved external symbol "void __cdecl std::_DebugHeapDelete<void>(void *)" (??$_DebugHeapDelete@X@std@@YAXPAX@Z) referenced in function "private: void __thiscall std::numpunct<wchar_t>::_Tidy(void)" (?_Tidy@?$numpunct@_W@std@@AAEXXZ)
This is probably a mangler bug, or we're failing to instantiate an inline function that VC++ normally instantiates.
Extended Description
Atempting to link an executable while testing Boost libraries with clang-cl I am seeing this error in a number of situations:
The command line for clang-cl has these options:
-TP /Od /Ob0 /W3 /GR /MDd /Zc:forScope /Zc:wchar_t -fmsc-version=1700 /wd4675 /EHs /D_HAS_EXCEPTIONS=0 /GR- -c