Skip to content

clang-cl /EHa /Os crash while compiling coroutines + std::unique_ptr, assertion hit even without std::unique_ptr, since 17.x.x #148035

Open
@tzuralon

Description

@tzuralon

Reproduces in llvm trunk (git commit e66c205), Release (but compiled with debug information, explained later why, and also reproduced in any clang release >16):

C:\Dev\Projects\clang_asynch_exceptions_coroutines_bug>clang-cl-release\clang-cl.exe /EHa /Os /std:c++latest coroutine_with_unique_ptr_argument.cpp
PLEASE submit a bug report to https://github.com/llvm/llvm-project/issues/ and include the crash backtrace, preprocessed source, and associated run script.
Stack dump:
0.      Program arguments: C:\\Dev\\Projects\\clang_asynch_exceptions_coroutines_bug\\clang-cl-release\\clang-cl.exe -cc1 -triple x86_64-pc-windows-msvc19.38.33135 -Os -emit-obj -mincremental-linker-compatible -dumpdir a- -disable-free -clear-ast-before-backend -disable-llvm-verifier -discard-value-names -main-file-name coroutine_with_unique_ptr_argument.cpp -mrelocation-model pic -pic-level 2 -mframe-pointer=none -relaxed-aliasing -fmath-errno -ffp-contract=on -fno-rounding-math -mconstructor-aliases -fms-volatile -funwind-tables=2 -target-cpu x86-64 -mllvm -x86-asm-syntax=intel -tune-cpu generic -D_MT -flto-visibility-public-std --dependent-lib=libcmt --dependent-lib=oldnames -stack-protector 2 -fcxx-exceptions -fexceptions -fasync-exceptions -fdiagnostics-format msvc -fdebug-compilation-dir=C:\\Dev\\Projects\\clang_asynch_exceptions_coroutines_bug -fcoverage-compilation-dir=C:\\Dev\\Projects\\clang_asynch_exceptions_coroutines_bug -resource-dir C:\\Dev\\Projects\\clang_asynch_exceptions_coroutines_bug\\lib\\clang\\21 -internal-isystem C:\\Dev\\Projects\\clang_asynch_exceptions_coroutines_bug\\lib\\clang\\21\\include -internal-isystem "C:\\Program Files\\Microsoft Visual Studio\\2022\\Community\\VC\\Tools\\MSVC\\14.38.33130\\include" -internal-isystem "C:\\Program Files\\Microsoft Visual Studio\\2022\\Community\\VC\\Tools\\MSVC\\14.38.33130\\atlmfc\\include" -internal-isystem "C:\\Program Files (x86)\\Windows Kits\\10\\Include\\10.0.22621.0\\ucrt" -internal-isystem "C:\\Program Files (x86)\\Windows Kits\\10\\Include\\10.0.22621.0\\shared" -internal-isystem "C:\\Program Files (x86)\\Windows Kits\\10\\Include\\10.0.22621.0\\um" -internal-isystem "C:\\Program Files (x86)\\Windows Kits\\10\\Include\\10.0.22621.0\\winrt" -internal-isystem "C:\\Program Files (x86)\\Windows Kits\\10\\Include\\10.0.22621.0\\cppwinrt" -fdeprecated-macro -ferror-limit 19 -fmessage-length=156 -fno-use-cxa-atexit -fms-extensions -fms-compatibility -fms-compatibility-version=19.38.33135 -std=c++26 -fno-implicit-modules -fskip-odr-check-in-gmf -fcolor-diagnostics -vectorize-loops -vectorize-slp -faddrsig -o C:\\Users\\tzura\\AppData\\Local\\Temp\\coroutine_with_unique_ptr_argument-92b223.obj -x c++ coroutine_with_unique_ptr_argument.cpp
1.      <eof> parser at end of file
2.      Code generation
3.      Running pass 'Function Pass Manager' on module 'coroutine_with_unique_ptr_argument.cpp'.
4.      Running pass 'Greedy Register Allocator' on function '@"?resuming_on_new_thread@@YA?AUtask@@V?$unique_ptr@HU?$default_delete@H@std@@@std@@@Z"'
Exception Code: 0xC0000005
 #0 0x00007ff7825f3414 llvm::SplitEditor::deleteRematVictims(void) (C:\Dev\Projects\clang_asynch_exceptions_coroutines_bug\clang-cl-release\clang-cl.exe+0x983414)
 #1 0x00007ff7825f4c02 llvm::SplitEditor::finish(class llvm::SmallVectorImpl<unsigned int> *) (C:\Dev\Projects\clang_asynch_exceptions_coroutines_bug\clang-cl-release\clang-cl.exe+0x984c02)
 #2 0x00007ff7823b9689 llvm::RAGreedy::splitAroundRegion(class llvm::LiveRangeEdit &, class llvm::ArrayRef<unsigned int>) (C:\Dev\Projects\clang_asynch_exceptions_coroutines_bug\clang-cl-release\clang-cl.exe+0x749689)
 #3 0x00007ff7823b37d9 llvm::RAGreedy::doRegionSplit(class llvm::LiveInterval const &, unsigned int, bool, class llvm::SmallVectorImpl<class llvm::Register> &) (C:\Dev\Projects\clang_asynch_exceptions_coroutines_bug\clang-cl-release\clang-cl.exe+0x7437d9)
 #4 0x00007ff7823bd177 llvm::RAGreedy::tryRegionSplit(class llvm::LiveInterval const &, class llvm::AllocationOrder &, class llvm::SmallVectorImpl<class llvm::Register> &) (C:\Dev\Projects\clang_asynch_exceptions_coroutines_bug\clang-cl-release\clang-cl.exe+0x74d177)
 #5 0x00007ff7823bd3c6 llvm::RAGreedy::trySplit(class llvm::LiveInterval const &, class llvm::AllocationOrder &, class llvm::SmallVectorImpl<class llvm::Register> &, class llvm::SmallSet<class llvm::Register, 16, struct std::less<class llvm::Register>> const &) (C:\Dev\Projects\clang_asynch_exceptions_coroutines_bug\clang-cl-release\clang-cl.exe+0x74d3c6)
 #6 0x00007ff7823b8c9c llvm::RAGreedy::selectOrSplitImpl(class llvm::LiveInterval const &, class llvm::SmallVectorImpl<class llvm::Register> &, class llvm::SmallSet<class llvm::Register, 16, struct std::less<class llvm::Register>> &, class llvm::SmallVector<struct std::pair<class llvm::LiveInterval const *, class llvm::MCRegister>, 8> &, unsigned int) (C:\Dev\Projects\clang_asynch_exceptions_coroutines_bug\clang-cl-release\clang-cl.exe+0x748c9c)
 #7 0x00007ff7823b896a llvm::RAGreedy::selectOrSplit(class llvm::LiveInterval const &, class llvm::SmallVectorImpl<class llvm::Register> &) (C:\Dev\Projects\clang_asynch_exceptions_coroutines_bug\clang-cl-release\clang-cl.exe+0x74896a)
 #8 0x00007ff7825ee15a llvm::RegAllocBase::allocatePhysRegs(void) (C:\Dev\Projects\clang_asynch_exceptions_coroutines_bug\clang-cl-release\clang-cl.exe+0x97e15a)
 #9 0x00007ff7823b7fcc llvm::RAGreedy::run(class llvm::MachineFunction &) (C:\Dev\Projects\clang_asynch_exceptions_coroutines_bug\clang-cl-release\clang-cl.exe+0x747fcc)
#10 0x00007ff7823b8860 RAGreedyPass::run(class llvm::MachineFunction &, class llvm::AnalysisManager<class llvm::MachineFunction> &) (C:\Dev\Projects\clang_asynch_exceptions_coroutines_bug\clang-cl-release\clang-cl.exe+0x748860)
#11 0x00007ff7823a5aad llvm::MachineFunctionPass::runOnFunction(class llvm::Function &) (C:\Dev\Projects\clang_asynch_exceptions_coroutines_bug\clang-cl-release\clang-cl.exe+0x735aad)
#12 0x00007ff7827cbaa1 llvm::FPPassManager::runOnFunction(class llvm::Function &) (C:\Dev\Projects\clang_asynch_exceptions_coroutines_bug\clang-cl-release\clang-cl.exe+0xb5baa1)
#13 0x00007ff7827cbcc5 llvm::FPPassManager::runOnModule(class llvm::Module &) (C:\Dev\Projects\clang_asynch_exceptions_coroutines_bug\clang-cl-release\clang-cl.exe+0xb5bcc5)
#14 0x00007ff7827cbf2e llvm::FPPassManager::runOnModule(class llvm::Module &) (C:\Dev\Projects\clang_asynch_exceptions_coroutines_bug\clang-cl-release\clang-cl.exe+0xb5bf2e)
#15 0x00007ff7827cb650 llvm::legacy::PassManager::run(class llvm::Module &) (C:\Dev\Projects\clang_asynch_exceptions_coroutines_bug\clang-cl-release\clang-cl.exe+0xb5b650)
#16 0x00007ff782fd473d clang::EmbedObject(class llvm::Module *, class clang::CodeGenOptions const &, class clang::DiagnosticsEngine &) (C:\Dev\Projects\clang_asynch_exceptions_coroutines_bug\clang-cl-release\clang-cl.exe+0x136473d)
#17 0x00007ff782fd8729 llvm::DenseMapBase<class llvm::DenseMap<class llvm::Loop *, class std::list<struct std::pair<struct llvm::AnalysisKey *, class std::unique_ptr<struct llvm::detail::AnalysisResultConcept<class llvm::Loop, class llvm::AnalysisManager<class llvm::Loop, struct llvm::LoopStandardAnalysisResults &>::Invalidator>, struct std::default_delete<struct llvm::detail::AnalysisResultConcept<class llvm::Loop, class llvm::AnalysisManager<class llvm::Loop, struct llvm::LoopStandardAnalysisResults &>::Invalidator>>>>, class std::allocator<struct std::pair<struct llvm::AnalysisKey *, class std::unique_ptr<struct llvm::detail::AnalysisResultConcept<class llvm::Loop, class llvm::AnalysisManager<class llvm::Loop, struct llvm::LoopStandardAnalysisResults &>::Invalidator>, struct std::default_delete<struct llvm::detail::AnalysisResultConcept<class llvm::Loop, class llvm::AnalysisManager<class llvm::Loop, struct llvm::LoopStandardAnalysisResults &>::Invalidator>>>>>>, struct llvm::DenseMapInfo<class llvm::Loop *, void>, struct llvm::detail::DenseMapPair<class llvm::Loop *, class std::list<struct std::pair<struct llvm::AnalysisKey *, class std::unique_ptr<struct llvm::detail::AnalysisResultConcept<class llvm::Loop, class llvm::AnalysisManager<class llvm::Loop, struct llvm::LoopStandardAnalysisResults &>::Invalidator>, struct std::default_delete<struct llvm::detail::AnalysisResultConcept<class llvm::Loop, class llvm::AnalysisManager<class llvm::Loop, struct llvm::LoopStandardAnalysisResults &>::Invalidator>>>>, class std::allocator<struct std::pair<struct llvm::AnalysisKey *, class std::unique_ptr<struct llvm::detail::AnalysisResultConcept<class llvm::Loop, class llvm::AnalysisManager<class llvm::Loop, struct llvm::LoopStandardAnalysisResults &>::Invalidator>, struct std::default_delete<struct llvm::detail::AnalysisResultConcept<class llvm::Loop, class llvm::AnalysisManager<class llvm::Loop, struct llvm::LoopStandardAnalysisResults &>::Invalidator>>>>>>>>, class llvm::Loop *, class std::list<struct std::pair<struct llvm::AnalysisKey *, class std::unique_ptr<struct llvm::detail::AnalysisResultConcept<class llvm::Loop, class llvm::AnalysisManager<class llvm::Loop, struct llvm::LoopStandardAnalysisResults &>::Invalidator>, struct std::default_delete<struct llvm::detail::AnalysisResultConcept<class llvm::Loop, class llvm::AnalysisManager<class llvm::Loop, struct llvm::LoopStandardAnalysisResults &>::Invalidator>>>>, class std::allocator<struct std::pair<struct llvm::AnalysisKey *, class std::unique_ptr<struct llvm::detail::AnalysisResultConcept<class llvm::Loop, class llvm::AnalysisManager<class llvm::Loop, struct llvm::LoopStandardAnalysisResults &>::Invalidator>, struct std::default_delete<struct llvm::detail::AnalysisResultConcept<class llvm::Loop, class llvm::AnalysisManager<class llvm::Loop, struct llvm::LoopStandardAnalysisResults &>::Invalidator>>>>>>, struct llvm::DenseMapInfo<class llvm::Loop *, void>, struct llvm::detail::DenseMapPair<class llvm::Loop *, class std::list<struct std::pair<struct llvm::AnalysisKey *, class std::unique_ptr<struct llvm::detail::AnalysisResultConcept<class llvm::Loop, class llvm::AnalysisManager<class llvm::Loop, struct llvm::LoopStandardAnalysisResults &>::Invalidator>, struct std::default_delete<struct llvm::detail::AnalysisResultConcept<class llvm::Loop, class llvm::AnalysisManager<class llvm::Loop, struct llvm::LoopStandardAnalysisResults &>::Invalidator>>>>, class std::allocator<struct std::pair<struct llvm::AnalysisKey *, class std::unique_ptr<struct llvm::detail::AnalysisResultConcept<class llvm::Loop, class llvm::AnalysisManager<class llvm::Loop, struct llvm::LoopStandardAnalysisResults &>::Invalidator>, struct std::default_delete<struct llvm::detail::AnalysisResultConcept<class llvm::Loop, class llvm::AnalysisManager<class llvm::Loop, struct llvm::LoopStandardAnalysisResults &>::Invalidator>>>>>>>>::destroyAll(void) (C:\Dev\Projects\clang_asynch_exceptions_coroutines_bug\clang-cl-release\clang-cl.exe+0x1368729)
#18 0x00007ff782fd8e76 clang::emitBackendOutput(class clang::CompilerInstance &, class clang::CodeGenOptions &, class llvm::StringRef, class llvm::Module *, enum clang::BackendAction, class llvm::IntrusiveRefCntPtr<class llvm::vfs::FileSystem>, class std::unique_ptr<class llvm::raw_pwrite_stream, struct std::default_delete<class llvm::raw_pwrite_stream>>, class clang::BackendConsumer *) (C:\Dev\Projects\clang_asynch_exceptions_coroutines_bug\clang-cl-release\clang-cl.exe+0x1368e76)
#19 0x00007ff78378c62e clang::BackendConsumer::HandleTranslationUnit(class clang::ASTContext &) (C:\Dev\Projects\clang_asynch_exceptions_coroutines_bug\clang-cl-release\clang-cl.exe+0x1b1c62e)
#20 0x00007ff784669025 clang::ParseAST(class clang::Sema &, bool, bool) (C:\Dev\Projects\clang_asynch_exceptions_coroutines_bug\clang-cl-release\clang-cl.exe+0x29f9025)
#21 0x00007ff783a0ab3c clang::ASTFrontendAction::ExecuteAction(void) (C:\Dev\Projects\clang_asynch_exceptions_coroutines_bug\clang-cl-release\clang-cl.exe+0x1d9ab3c)
#22 0x00007ff78378b36b clang::CodeGenAction::ExecuteAction(void) (C:\Dev\Projects\clang_asynch_exceptions_coroutines_bug\clang-cl-release\clang-cl.exe+0x1b1b36b)
#23 0x00007ff783a0a9b4 clang::FrontendAction::Execute(void) (C:\Dev\Projects\clang_asynch_exceptions_coroutines_bug\clang-cl-release\clang-cl.exe+0x1d9a9b4)
#24 0x00007ff7839f110a clang::CompilerInstance::ExecuteAction(class clang::FrontendAction &) (C:\Dev\Projects\clang_asynch_exceptions_coroutines_bug\clang-cl-release\clang-cl.exe+0x1d8110a)
#25 0x00007ff783acf934 clang::ExecuteCompilerInvocation(class clang::CompilerInstance *) (C:\Dev\Projects\clang_asynch_exceptions_coroutines_bug\clang-cl-release\clang-cl.exe+0x1e5f934)
#26 0x00007ff781d91f72 cc1_main(class llvm::ArrayRef<char const *>, char const *, void *) (C:\Dev\Projects\clang_asynch_exceptions_coroutines_bug\clang-cl-release\clang-cl.exe+0x121f72)
#27 0x00007ff781d8b612 clang::DiagnosticConsumer::EndSourceFile(void) (C:\Dev\Projects\clang_asynch_exceptions_coroutines_bug\clang-cl-release\clang-cl.exe+0x11b612)
#28 0x00007ff781d8c710 clang_main(int, char **, struct llvm::ToolContext const &) (C:\Dev\Projects\clang_asynch_exceptions_coroutines_bug\clang-cl-release\clang-cl.exe+0x11c710)
#29 0x00007ff781d9cbc4 main (C:\Dev\Projects\clang_asynch_exceptions_coroutines_bug\clang-cl-release\clang-cl.exe+0x12cbc4)
#30 0x00007ff785d78438 invoke_main D:\a\_work\1\s\src\vctools\crt\vcstartup\src\startup\exe_common.inl:78:0
#31 0x00007ff785d78438 __scrt_common_main_seh D:\a\_work\1\s\src\vctools\crt\vcstartup\src\startup\exe_common.inl:288:0
#32 0x00007ffc348be8d7 (C:\WINDOWS\System32\KERNEL32.DLL+0x2e8d7)
#33 0x00007ffc35d1c34c (C:\WINDOWS\SYSTEM32\ntdll.dll+0x3c34c)
clang-cl: error: clang frontend command failed due to signal (use -v to see invocation)
clang version 21.0.0git (https://github.com/llvm/llvm-project.git e66c205bda33a91fbe2ba5b4a5d6b823e5c23e8a)
Target: x86_64-pc-windows-msvc
Thread model: posix
InstalledDir: C:\Dev\Projects\clang_asynch_exceptions_coroutines_bug\clang-cl-release
clang-cl: note: diagnostic msg:
********************

PLEASE ATTACH THE FOLLOWING FILES TO THE BUG REPORT:
Preprocessed source(s) and associated run script(s) are located at:
clang-cl: note: diagnostic msg: C:\Users\tzura\AppData\Local\Temp\coroutine_with_unique_ptr_argument-a10a37.cpp
clang-cl: note: diagnostic msg: C:\Users\tzura\AppData\Local\Temp\coroutine_with_unique_ptr_argument-a10a37.sh
clang-cl: note: diagnostic msg:

********************

coroutine_with_unique_ptr_argument.cpp:

#include <coroutine>
#include <memory>

auto switch_to_new_thread()
{
    struct awaitable
    {
        bool await_ready() { return false; }
        void await_suspend(std::coroutine_handle<> h) {}
        void await_resume() {}
    };
    return awaitable{};
}

struct task
{
    struct promise_type
    {
        task get_return_object() { return {}; }
        std::suspend_never initial_suspend() { return {}; }
        std::suspend_never final_suspend() noexcept { return {}; }
        void return_void() {}
        void unhandled_exception() {}
    };
};

task resuming_on_new_thread(
    std::unique_ptr<int> x
)
{
    co_await switch_to_new_thread();
}

int main()
{
    resuming_on_new_thread(
        {}
    );
}

I managed to reduce it to using some class having a move ctor + deleter in the dtor:
coroutine_with_argument_having_deleter_and_move_ctor.cpp:

//#include "memory.h"
#include <coroutine>

auto switch_to_new_thread()
{
    struct awaitable
    {
        bool await_ready() { return false; }
        void await_suspend(std::coroutine_handle<> h) {}
        void await_resume() {}
    };
    return awaitable{};
}

struct task
{
    struct promise_type
    {
        task get_return_object() { return {}; }
        std::suspend_never initial_suspend() { return {}; }
        std::suspend_never final_suspend() noexcept { return {}; }
        void return_void() {}
        void unhandled_exception() {}
    };
};

class unique_ptr {
public:
    unique_ptr() = default;

    unique_ptr(unique_ptr&&) = default;

    ~unique_ptr() noexcept {
        delete ptr;
    }

private:
    int* ptr;
};

task resuming_on_new_thread(
    unique_ptr x
)
{
    co_await switch_to_new_thread();
}

int main()
{
    unique_ptr x;
    resuming_on_new_thread(
        std::move(x)
    );
}

In clang debug / clang release with assertions, both cpps cause clang to crash due to validation of the IR, with a different error message.
In that case, even the cppreference coroutines example attached emits the same validation error, of "Unwind edges out of a funclet pad must have the same unwind dest".

C:\Dev\Projects\clang_asynch_exceptions_coroutines_bug>clang-cl-debug\clang-cl.exe /EHa /std:c++latest coroutine.cpp
Unwind edges out of a funclet pad must have the same unwind dest
  %9 = cleanuppad within none []
  invoke void @llvm.seh.scope.end() [ "funclet"(token %9) ]
          to label %CoroEnd65 unwind label %ehcleanup44
  cleanupret from %9 unwind to caller
fatal error: error in backend: Broken function
PLEASE submit a bug report to https://github.com/llvm/llvm-project/issues/ and include the crash backtrace, preprocessed source, and associated run script.
Stack dump:
0.      Program arguments: C:\\Dev\\Projects\\clang_asynch_exceptions_coroutines_bug\\clang-cl-debug\\clang-cl.exe -cc1 -triple x86_64-pc-windows-msvc19.38.33135 -emit-obj -mincremental-linker-compatible -dumpdir a- -disable-free -clear-ast-before-backend -main-file-name coroutine.cpp -mrelocation-model pic -pic-level 2 -mframe-pointer=none -relaxed-aliasing -fmath-errno -ffp-contract=on -fno-rounding-math -mconstructor-aliases -fms-volatile -funwind-tables=2 -target-cpu x86-64 -mllvm -x86-asm-syntax=intel -tune-cpu generic -D_MT -flto-visibility-public-std --dependent-lib=libcmt --dependent-lib=oldnames -stack-protector 2 -fcxx-exceptions -fexceptions -fasync-exceptions -fdiagnostics-format msvc -fdebug-compilation-dir=C:\\Dev\\Projects\\clang_asynch_exceptions_coroutines_bug -fcoverage-compilation-dir=C:\\Dev\\Projects\\clang_asynch_exceptions_coroutines_bug -resource-dir C:\\Dev\\Projects\\clang_asynch_exceptions_coroutines_bug\\lib\\clang\\21 -internal-isystem C:\\Dev\\Projects\\clang_asynch_exceptions_coroutines_bug\\lib\\clang\\21\\include -internal-isystem "C:\\Program Files\\Microsoft Visual Studio\\2022\\Community\\VC\\Tools\\MSVC\\14.38.33130\\include" -internal-isystem "C:\\Program Files\\Microsoft Visual Studio\\2022\\Community\\VC\\Tools\\MSVC\\14.38.33130\\atlmfc\\include" -internal-isystem "C:\\Program Files (x86)\\Windows Kits\\10\\Include\\10.0.22621.0\\ucrt" -internal-isystem "C:\\Program Files (x86)\\Windows Kits\\10\\Include\\10.0.22621.0\\shared" -internal-isystem "C:\\Program Files (x86)\\Windows Kits\\10\\Include\\10.0.22621.0\\um" -internal-isystem "C:\\Program Files (x86)\\Windows Kits\\10\\Include\\10.0.22621.0\\winrt" -internal-isystem "C:\\Program Files (x86)\\Windows Kits\\10\\Include\\10.0.22621.0\\cppwinrt" -fdeprecated-macro -ferror-limit 19 -fmessage-length=156 -fno-use-cxa-atexit -fms-extensions -fms-compatibility -fms-compatibility-version=19.38.33135 -std=c++26 -fno-implicit-modules -fskip-odr-check-in-gmf -fcolor-diagnostics -faddrsig -o C:\\Users\\tzura\\AppData\\Local\\Temp\\coroutine-40534e.obj -x c++ coroutine.cpp
1.      <eof> parser at end of file
2.      Optimizer
3.      Running pass "coro-cond(coro-early,cgscc(coro-split),coro-cleanup,globaldce)" on module "coroutine.cpp"
4.      Running pass "cgscc(coro-split)" on module "coroutine.cpp"
5.      While splitting coroutine @"?resuming_on_new_thread@@YA?AUtask@@AEAVjthread@std@@@Z"
clang-cl: error: clang frontend command failed with exit code 70 (use -v to see invocation)
clang version 21.0.0git (https://github.com/llvm/llvm-project.git e66c205bda33a91fbe2ba5b4a5d6b823e5c23e8a)
Target: x86_64-pc-windows-msvc
Thread model: posix
InstalledDir: C:\Dev\Projects\clang_asynch_exceptions_coroutines_bug\clang-cl-debug
Build config: +unoptimized, +assertions
clang-cl: note: diagnostic msg:
********************

PLEASE ATTACH THE FOLLOWING FILES TO THE BUG REPORT:
Preprocessed source(s) and associated run script(s) are located at:
clang-cl: note: diagnostic msg: C:\Users\tzura\AppData\Local\Temp\coroutine-5a56db.cpp
clang-cl: note: diagnostic msg: C:\Users\tzura\AppData\Local\Temp\coroutine-5a56db.sh
clang-cl: note: diagnostic msg:

********************

coroutine.cpp:

#include <coroutine>
#include <iostream>
#include <stdexcept>
#include <thread>
 
auto switch_to_new_thread(std::jthread& out)
{
    struct awaitable
    {
        std::jthread* p_out;
        bool await_ready() { return false; }
        void await_suspend(std::coroutine_handle<> h)
        {
            std::jthread& out = *p_out;
            if (out.joinable())
                throw std::runtime_error("Output jthread parameter not empty");
            out = std::jthread([h] { h.resume(); });
            // Potential undefined behavior: accessing potentially destroyed *this
            // std::cout << "New thread ID: " << p_out->get_id() << '\n';
            std::cout << "New thread ID: " << out.get_id() << '\n'; // this is OK
        }
        void await_resume() {}
    };
    return awaitable{&out};
}
 
struct task
{
    struct promise_type
    {
        task get_return_object() { return {}; }
        std::suspend_never initial_suspend() { return {}; }
        std::suspend_never final_suspend() noexcept { return {}; }
        void return_void() {}
        void unhandled_exception() {}
    };
};
 
task resuming_on_new_thread(std::jthread& out)
{
    std::cout << "Coroutine started on thread: " << std::this_thread::get_id() << '\n';
    co_await switch_to_new_thread(out);
    // awaiter destroyed here
    std::cout << "Coroutine resumed on thread: " << std::this_thread::get_id() << '\n';
}
 
int main()
{
    std::jthread out;
    resuming_on_new_thread(out);
}

To sum up all of the runs I performed, I attach this table:

Image

So I was able to compile coroutine_with_argument_having_deleter_and_move_ctor.cpp with Clang16.

I also tried to create the IR (in clang21 release, on coroutine_with_argument_having_deleter_and_move_ctor.cpp, both with optimizations on and without), and to track the IR creation and then IR compilation, a new error message emerged - error: invalid LLVM IR input: Instruction does not dominate all uses!:

C:\Dev\Projects\clang_asynch_exceptions_coroutines_bug>clang-cl-release\clang-cl.exe /c /EHa /std:c++latest coroutine_with_argument_having_deleter_and_move_ctor.cpp -Xclang -emit-llvm -o coroutine_with_argument_having_deleter_and_move_ctor_clang_trunk.ll

C:\Dev\Projects\clang_asynch_exceptions_coroutines_bug>clang-cl-release\clang-cl.exe /c /EHa /std:c++latest coroutine_with_argument_having_deleter_and_move_ctor.cpp /Os -Xclang -emit-llvm -o coroutine_with_argument_having_deleter_and_move_ctor_clang_trunk_optimized.ll

C:\Dev\Projects\clang_asynch_exceptions_coroutines_bug>clang-cl-release\clang-cl.exe coroutine_with_argument_having_deleter_and_move_ctor_clang_trunk.ll
error: invalid LLVM IR input: Instruction does not dominate all uses!
  %18 = phi ptr [ %11, %10 ], [ %16, %15 ]
  %148 = getelementptr inbounds %"?resuming_on_new_thread@@YA?AUtask@@Vunique_ptr@@@Z.Frame", ptr %18, i32 0, i32 9
Unwind edges out of a funclet pad must have the same unwind dest
  %95 = cleanuppad within none []
  invoke void @llvm.seh.scope.end() [ "funclet"(token %95) ]
          to label %96 unwind label %99
  cleanupret from %95 unwind to caller
Unwind edges out of a funclet pad must have the same unwind dest
  %97 = cleanuppad within none []
  invoke void @llvm.seh.scope.end() [ "funclet"(token %97) ]
          to label %98 unwind label %101
  cleanupret from %97 unwind to caller
Unwind edges out of a funclet pad must have the same unwind dest
  %97 = cleanuppad within none []
  invoke void @llvm.seh.scope.end() [ "funclet"(token %97) ]
          to label %98 unwind label %101
  cleanupret from %97 unwind to caller

1 error generated.

C:\Dev\Projects\clang_asynch_exceptions_coroutines_bug>clang-cl-release\clang-cl.exe coroutine_with_argument_having_deleter_and_move_ctor_clang_trunk_optimized.ll
error: invalid LLVM IR input: Instruction does not dominate all uses!
  %3 = invoke noalias noundef nonnull dereferenceable(40) ptr @"??2@YAPEAX_K@Z"(i64 noundef 40) #9
          to label %4 unwind label %34
  %36 = getelementptr inbounds nuw i8, ptr %3, i64 32
Unwind edges out of a funclet pad must have the same unwind dest
  %7 = cleanuppad within none []
  invoke void @llvm.seh.scope.end() [ "funclet"(token %7) ]
          to label %8 unwind label %9
  cleanupret from %7 unwind to caller

1 error generated.

Metadata

Metadata

Assignees

No one assigned

    Labels

    clang:codegenIR generation bugs: mangling, exceptions, etc.coroutinesC++20 coroutinescrashPrefer [crash-on-valid] or [crash-on-invalid]

    Type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions