Description
(I'm not sure if this issue is 1 bug underneath, or 2 bugs.)
If you call a dllimport
function from a naked
assembly function on x86:
__declspec(dllimport) void bar();
__declspec(naked) void foo()
{
__asm
{
mov eax, 0
mov ebx, 0
mov ecx, 0
mov edx, 0
mov esi, 0
mov edi, 0
jmp bar
}
}
this causes Clang to attempt to pick an unused general-purpose register to load the associated __imp_...
symbol into, before the naked body executes.
-
The fact that Clang even attempts to do this is itself a bug, because
naked
's entire purpose is to avoid extra instructions from being inserted into the function in the first place. This causes registers to be clobbered that the callees don't expect! -
In the above example, Clang's attempt fails, because it fails to find an unused general-purpose register. (Whereas if you comment out one of the
mov
s, it succeeds.) It therefore errors, when it shouldn't:
<source>(5,9): error: inline assembly requires more registers than available
5 | __asm
| ^
In fact, MSVC compiles this entirely correctly, as intended:
?foo@@YAXXZ PROC
mov eax, 0
mov ebx, 0
mov ecx, 0
mov edx, 0
mov esi, 0
mov edi, 0
jmp (null) PTR __imp_?bar@@YAXXZ
?foo@@YAXXZ ENDP