Skip to content
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

<experimental/generator>: error C2980 when compiling with /kernel (regression) #1323

Closed
kobykahane opened this issue Sep 28, 2020 · 0 comments · Fixed by #1373
Closed

<experimental/generator>: error C2980 when compiling with /kernel (regression) #1323

kobykahane opened this issue Sep 28, 2020 · 0 comments · Fixed by #1373
Labels
bug Something isn't working fixed Something works now, yay!

Comments

@kobykahane
Copy link

Describe the bug
Following the changes from PR #1219, using the experimental/generator header in code built with /kernel (and hence no exception handling) now fails to compile with error C2980.

Command-line test case

C:\Users\kobyk\Documents\Stuff\ge>type ge.cpp
#include <malloc.h>
#include <coroutine>
#include <experimental/generator>

struct WDFQUEUE{};

namespace foo {

template <typename T>
class PoolAllocator final {
public:
    using value_type = T;
    using pointer = T*;
    using const_pointer = const T*;
    using reference = T&;
    using const_reference = const T&;
    using size_type = std::size_t;
    using difference_type = std::ptrdiff_t;

    template <class U>
    struct rebind {
        using other = PoolAllocator<T>;
    };

    pointer allocate(size_t size) noexcept {
        return static_cast<pointer>(malloc(size));
    }

    void deallocate(pointer ptr, [[maybe_unused]] size_t size) noexcept {

        free(ptr);
    }
};

template <typename T>
using Generator = std::experimental::generator<T, PoolAllocator<char>>;

class IteratedRequest final
{
public:
        bool valid() const { return true; }
        bool next(WDFQUEUE queue) { return true; }
};

Generator<IteratedRequest> IterateRequests(WDFQUEUE queue) {

    IteratedRequest currentRequest;
    while (currentRequest.next(queue)) {
        if (!currentRequest.valid()) {
            continue;
        }
        co_yield currentRequest;
    }
}

}
C:\Users\kobyk\Documents\Stuff\ge>cl /kernel /nologo /std:c++latest /c ge.cpp
ge.cpp
ge.cpp(54): error C2980: C++ exception handling is not supported with /kernel

Expected behavior
Previously, generators with a non-throwing allocator worked with code built with /kernel.
Furthermore, removing the unhandled_exception() function added by the PR results in the code compiling successfully.

STL version
Microsoft Visual Studio Community 2019 Preview
Version 16.8.0 Preview 3.1

Additional context
Switching back to legacy coroutines (i.e., including <experimental/coroutine> instead of <coroutine> and adding /await to the compiler command line) also resolves the C2980 error.

@CaseyCarter

@StephanTLavavej StephanTLavavej added the bug Something isn't working label Sep 28, 2020
CaseyCarter added a commit to CaseyCarter/STL that referenced this issue Oct 5, 2020
Restore the "no-exceptions" mode by defining `unhandled_exception` only when `_CPPUNWIND` is defined. If `unhandled_exception` is defined, the compiler will wrap the coroutine body in a `try...catch` as depicted in [dcl.fct.def.coroutine]/5, which it then diagnoses as ill-formed when unwinding is enabled.

Fixes microsoft#1323.

Some cleanup while we're here:
* Use STL style:
  * Prefer not to deduce simple return types
  * `const` west
  * introduce template type parameters with `class`
  * Annotate functions that don't throw exceptions `noexcept`
  * remove excess empy lines
  * Use `_Capital_snake` names for non-template-parameters
* Sharpen the no-exceptions design:
  * `generator::promise_type` only has members `_Exception` and `_Rethrow_if_exception` to "delay" exception delivery so as to avoid triggering VSO-1172852. They aren't present in "no-exceptions" mode.
* `generator::iterator` should have _explicit_ conversion from `coroutine_handle` rather than implicit for good design hygiene. The conversion from `nullptr_t` is unnecessary.
CaseyCarter added a commit to CaseyCarter/STL that referenced this issue Oct 13, 2020
Restore the "no-exceptions" mode by defining `unhandled_exception` only when `_CPPUNWIND` is defined. If `unhandled_exception` is defined, the compiler will wrap the coroutine body in a `try...catch` as depicted in [dcl.fct.def.coroutine]/5, which it then diagnoses as ill-formed when unwinding is enabled.

Fixes microsoft#1323.

Some cleanup while we're here:
* Use STL style:
  * Prefer not to deduce simple return types
  * `const` west
  * introduce template type parameters with `class`
  * Annotate functions that don't throw exceptions `noexcept`
  * remove excess empy lines
  * Use `_Capital_snake` names for non-template-parameters
* Sharpen the no-exceptions design:
  * `generator::promise_type` only has members `_Exception` and `_Rethrow_if_exception` to "delay" exception delivery so as to avoid triggering VSO-1172852. They aren't present in "no-exceptions" mode.
* `generator::iterator` should have _explicit_ conversion from `coroutine_handle` rather than implicit for good design hygiene. The conversion from `nullptr_t` is unnecessary.
CaseyCarter added a commit to CaseyCarter/STL that referenced this issue Oct 14, 2020
Restore kernel mode operation by defining `unhandled_exception` only when `_KERNEL_MODE` is not defined. (When `unhandled_exception` is defined, the compiler will wrap the coroutine body in a `try...catch` as depicted in [dcl.fct.def.coroutine]/5, which it then diagnoses as ill-formed when unwinding is disabled as in `/kernel`.)

Fixes microsoft#1323.

Some cleanup while we're here:
* Use STL style:
  * Prefer not to deduce simple return types
  * `const` west
  * introduce template type parameters with `class`
  * Annotate functions that don't throw exceptions `noexcept`
  * remove excess empy lines
  * Use `_Capital_snake` names for non-template-parameters
  * `generator::promise_type` only has members `_Exception` and `_Rethrow_if_exception` to "delay" exception delivery so as to avoid triggering VSO-1172852. They aren't needed in kernel mode.
* `generator::iterator` should have _explicit_ conversion from `coroutine_handle` rather than implicit for good design hygiene. The conversion from `nullptr_t` is unnecessary.

Note that the story for `/EHs-` without `/kernel` is less clear and currently not supported.
@StephanTLavavej StephanTLavavej added the fixed Something works now, yay! label Oct 17, 2020
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working fixed Something works now, yay!
Projects
None yet
Development

Successfully merging a pull request may close this issue.

2 participants