Привет!
Обнаружил в Visual C++ 2015 странное поведение. Баг?
#include <cstdio>
#define CALLING_CONV __vectorcall
struct parent {
virtual ~parent() {}
virtual void CALLING_CONV func() = 0;
};
struct child : parent {
void CALLING_CONV func() { printf("Hello!\r\n"); }
};
int main()
{
parent * p = new child();
void (CALLING_CONV parent::*Pfn)() = &parent::func;
(p->*Pfn)();
delete p;
return 0;
}
На строке '(p->*Pfn)();' программа вылетает. Если заменить __vectorcall на любой другой
calling convention (__cdecl, __stdcall, __fastcall, __thiscall), то все ок.
Visual Studio Professional 2015
Version 14.0.24720.00 Update 1
Конфигурация сборки — Debug или Release под платформу x86 (на x64 воспроизведения нет).
Здравствуйте, okman, Вы писали:
O>Здравствуйте, uzhas, Вы писали:
U>>похоже на баг
U>>виртуальный метод + vectorcall + указатель на метод..ну в общем, редкий сценарий, вполне возможен баг
O>Спасибо.
O>Проверил на Visual Studio 2015 update 3 — все то же самое. Запостил им баг, посмотрим, что ответят.
Поделитесь ссылкой. Проголосуем
Здравствуйте, SaZ, Вы писали:
SaZ>Поделитесь ссылкой. Проголосуем
Crash when using polymorphic call via pointer to member and __vectorcall. (ID 3102956)
https://connect.microsoft.com/VisualStudio/feedback/details/3102956/crash-when-using-polymorphic-call-via-pointer-to-member-and-vectorcall
Здравствуйте, okman, Вы писали:
O>Обнаружил в Visual C++ 2015 странное поведение. Баг?
В x64 работает нормально.
В x86 вылетает на последней команде
В x64 этот код выглядит так
00007FF61979232F mov rcx,qword ptr [p]
00007FF619792333 call qword ptr [Pfn]
00007FF61979109B jmp parent::`vcall'{8}' (07FF619791A94h)
00007FF619791A94 mov rax,qword ptr [rcx]
00007FF619791A97 jmp qword ptr [rax+8]
В x86
00E82390 mov ecx,dword ptr [p]
00E82393 call dword ptr [Pfn]
00E8107D jmp parent::`vcall'{4}' (0E81A3Fh)
00E81A3F mov eax,dword ptr [esp+4]
00E81A43 mov eax,dword ptr [eax]
00E81A45 jmp dword ptr [eax+4] // здесь и падает
Зачем она в стек полезла, если [p] в регистре ecx —
Если заменить __vectorcall на __fastcall, то вместо последних 3 строк имеем
00251A3F mov eax,dword ptr [ecx]
00251A41 jmp dword ptr [eax+4]
что и должно быть.
Видимо, баг, да.
Говорить дальше не было нужды. Как и все космонавты, капитан Нортон не испытывал особого доверия к явлениям, внешне слишком заманчивым.