__await is still broken in Visual Studio 2015 RTM
The following simple code does not work:
#include "stdafx.h" #include <experimental\generator> #include <future> using namespace std; using namespace std::experimental; future<int> get_int() { return async([] { return 0; }); } future<int> wait_int() { return __await get_int(); } int main() { auto const i = wait_int().get(); return 0; }
App hits int 3
instruction (XXX.exe has triggered a breakpoint) and then hangs forever waiting for suspended coroutine to finish. Bravo!
My investigation shows that compiler generates invalid instructions within XXX.exe!wait_int$_ResumeCoro$2() function:
00007FF6166FB0F0 mov qword ptr [rsp+8],rcx 00007FF6166FB0F5 push rbp 00007FF6166FB0F6 sub rsp,30h 00007FF6166FB0FA mov qword ptr [rsp+20h],0FFFFFFFFFFFFFFFEh 00007FF6166FB103 mov rbp,qword ptr [$S2] 00007FF6166FB108 mov eax,dword ptr [rbp+20h] 00007FF6166FB10B mov dword ptr [rbp+78h],eax 00007FF6166FB10E cmp dword ptr [rbp+78h],5
rbp
has the address of coroutine frame, frame has two consequent 64-bit values - address of resume method and some internal state flag, which is set to 2 initially.
dword ptr [rbp+20h]
- this instruction obtains the flag, but the offset is completely wrong, it must be dword ptr [rbp+8h]
.
So all cases of state flag switch are bypassed. Default case makes the assert hit. Boom.
UPD: It doesn't support Debug Information Format == Program Database for Edit And Continue (/Zl). With this setting set to something else the code is generated properly: mov eax, [rbp+8]
.