Skip to content

clang-cl does not work with /MDd (dynamic debug CRT) due to std::locale link errors #18630

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

Open
eldiener mannequin opened this issue Dec 15, 2013 · 6 comments
Open

clang-cl does not work with /MDd (dynamic debug CRT) due to std::locale link errors #18630

eldiener mannequin opened this issue Dec 15, 2013 · 6 comments
Labels
bugzilla Issues migrated from bugzilla c++ clang:to-be-triaged Should not be used for new issues platform:windows

Comments

@eldiener
Copy link
Mannequin

eldiener mannequin commented Dec 15, 2013

Bugzilla Link 18256
Version trunk
OS Windows XP
Depends On #11542
CC @DougGregor,@rnk

Extended Description

Atempting to link an executable while testing Boost libraries with clang-cl I am seeing this error in a number of situations:

clang-win.link ..\..\..\bin.v2\libs\vmd\test\test_begin_identifier.test\clang-vc11-win-3.4\debug\test_begin_identifier.exe
test_begin_identifier.obj : error LNK2019: unresolved external symbol "public: static class std::locale::id std::ctype<char>::id" (?id@?$ctype@D@std@@2V0locale@2@A) referenced in function "class std::ctype<char> const & __cdecl std::use_facet<class std::ctype<char> >(class std::locale const &)" (??$use_facet@V?$ctype@D@std@@@std@@YAABV?$ctype@D@0@ABVlocale@0@@Z)
test_begin_identifier.obj : error LNK2019: unresolved external symbol "public: static class std::locale::id std::ctype<wchar_t>::id" (?id@?$ctype@_W@std@@2V0locale@2@A) referenced in function "class std::ctype<wchar_t> const & __cdecl std::use_facet<class std::ctype<wchar_t> >(class std::locale const &)" (??$use_facet@V?$ctype@_W@std@@@std@@YAABV?$ctype@_W@0@ABVlocale@0@@Z)
test_begin_identifier.obj : error LNK2019: unresolved external symbol "private: static int std::locale::id::_Id_cnt" (?_Id_cnt@id@locale@std@@0HA) referenced in function "public: __thiscall std::locale::id::operator unsigned int(void)" (??Bid@locale@std@@QAEIXZ)
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)

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

@rnk
Copy link
Collaborator

rnk commented Dec 16, 2013

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.

@eldiener
Copy link
Mannequin Author

eldiener mannequin commented Dec 17, 2013

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.

@llvmbot
Copy link
Member

llvmbot commented May 1, 2014

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?

@llvmbot
Copy link
Member

llvmbot commented May 1, 2014

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.

@rnk
Copy link
Collaborator

rnk commented May 1, 2014

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 ).

@rnk
Copy link
Collaborator

rnk commented May 1, 2014

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 #11542 .

@llvmbot llvmbot transferred this issue from llvm/llvm-bugzilla-archive Dec 9, 2021
@Endilll Endilll changed the title clang-cl does not work with /MDd (dynamic debug CRT) due to std::locale link errors clang-cl does not work with /MDd (dynamic debug CRT) due to std::locale link errors Jul 27, 2024
@Endilll Endilll added the clang:to-be-triaged Should not be used for new issues label Jul 27, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bugzilla Issues migrated from bugzilla c++ clang:to-be-triaged Should not be used for new issues platform:windows
Projects
None yet
Development

No branches or pull requests

3 participants